bindings/python/ns3modulegen_core_customizations.py
author Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
Sun, 13 Jul 2008 17:55:48 +0100
changeset 3421 b9424c43753d
parent 3412 518719e905a0
child 3473 6bce86ea4778
permissions -rw-r--r--
Python: make helper class methods using attribute optional parameters work.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3408
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     1
import re
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     2
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     3
from pybindgen.typehandlers import base as typehandlers
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     4
from pybindgen import (ReturnValue, Parameter)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     5
from pybindgen.cppmethod import CustomCppMethodWrapper, CustomCppConstructorWrapper
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     6
from pybindgen.typehandlers.codesink import MemoryCodeSink
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     7
from pybindgen.typehandlers import ctypeparser
3421
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
     8
from pybindgen import cppclass
3408
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     9
import warnings
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    10
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    11
from pybindgen.typehandlers.base import CodeGenerationError
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    12
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    13
import sys
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    14
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    15
class SmartPointerTransformation(typehandlers.TypeTransformation):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    16
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    17
    This class provides a "type transformation" that tends to support
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    18
    NS-3 smart pointers.  Parameters such as "Ptr<Foo> foo" are
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    19
    transformed into something like Parameter.new("Foo*", "foo",
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    20
    transfer_ownership=False).  Return values such as Ptr<Foo> are
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    21
    transformed into ReturnValue.new("Foo*",
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    22
    caller_owns_return=False).  Since the underlying objects have
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    23
    reference counting, PyBindGen does the right thing.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    24
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    25
    def __init__(self):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    26
        super(SmartPointerTransformation, self).__init__()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    27
        self.rx = re.compile(r'(ns3::|::ns3::|)Ptr<([^>]+)>')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    28
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    29
    def _get_untransformed_type_traits(self, name):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    30
        m = self.rx.match(name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    31
        is_const = False
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    32
        if m is None:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    33
            return None, False
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    34
        else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    35
            name1 = m.group(2).strip()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    36
            if name1.startswith('const '):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    37
                name1 = name1[len('const '):]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    38
                is_const = True
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    39
            if name1.endswith(' const'):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    40
                name1 = name1[:-len(' const')]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    41
                is_const = True
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    42
            new_name = name1+' *'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    43
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    44
            if new_name.startswith('::'):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    45
                new_name = new_name[2:]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    46
            return new_name, is_const
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    47
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    48
    def get_untransformed_name(self, name):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    49
        new_name, dummy_is_const = self._get_untransformed_type_traits(name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    50
        return new_name
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    51
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    52
    def create_type_handler(self, type_handler, *args, **kwargs):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    53
        if issubclass(type_handler, Parameter):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    54
            kwargs['transfer_ownership'] = False
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    55
        elif issubclass(type_handler, ReturnValue):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    56
            kwargs['caller_owns_return'] = False
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    57
        else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    58
            raise AssertionError
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    59
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    60
        ## fix the ctype, add ns3:: namespace
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    61
        orig_ctype, is_const = self._get_untransformed_type_traits(args[0])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    62
        if is_const:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    63
            kwargs['is_const'] = True
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    64
            correct_ctype = 'ns3::Ptr< %s const >' % orig_ctype[:-2]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    65
        else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    66
            correct_ctype = 'ns3::Ptr< %s >' % orig_ctype[:-2]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    67
        args = tuple([correct_ctype] + list(args[1:]))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    68
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    69
        handler = type_handler(*args, **kwargs)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    70
        handler.set_tranformation(self, orig_ctype)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    71
        return handler
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    72
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    73
    def untransform(self, type_handler, declarations, code_block, expression):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    74
        return 'ns3::PeekPointer (%s)' % (expression,)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    75
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    76
    def transform(self, type_handler, declarations, code_block, expression):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    77
        assert type_handler.untransformed_ctype[-1] == '*'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    78
        return 'ns3::Ptr< %s > (%s)' % (type_handler.untransformed_ctype[:-1], expression)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    79
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    80
## register the type transformation
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    81
transf = SmartPointerTransformation()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    82
typehandlers.return_type_matcher.register_transformation(transf)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    83
typehandlers.param_type_matcher.register_transformation(transf)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    84
del transf
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    85
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    86
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    87
class ArgvParam(Parameter):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    88
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    89
    Converts a python list-of-strings argument to a pair of 'int argc,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    90
    char *argv[]' arguments to pass into C.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    91
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    92
    One Python argument becomes two C function arguments -> it's a miracle!
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    93
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    94
    Note: this parameter type handler is not registered by any name;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    95
    must be used explicitly.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    96
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    97
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    98
    DIRECTIONS = [Parameter.DIRECTION_IN]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    99
    CTYPES = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   100
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   101
    def convert_c_to_python(self, wrapper):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   102
        raise NotImplementedError
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   103
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   104
    def convert_python_to_c(self, wrapper):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   105
        py_name = wrapper.declarations.declare_variable('PyObject*', 'py_' + self.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   106
        argc_var = wrapper.declarations.declare_variable('int', 'argc')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   107
        name = wrapper.declarations.declare_variable('char**', self.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   108
        idx = wrapper.declarations.declare_variable('Py_ssize_t', 'idx')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   109
        wrapper.parse_params.add_parameter('O!', ['&PyList_Type', '&'+py_name], self.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   110
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   111
        #wrapper.before_call.write_error_check('!PyList_Check(%s)' % py_name) # XXX
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   112
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   113
        wrapper.before_call.write_code("%s = (char **) malloc(sizeof(char*)*PyList_Size(%s));"
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   114
                                       % (name, py_name))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   115
        wrapper.before_call.add_cleanup_code('free(%s);' % name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   116
        wrapper.before_call.write_code('''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   117
for (%(idx)s = 0; %(idx)s < PyList_Size(%(py_name)s); %(idx)s++)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   118
{
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   119
''' % vars())
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   120
        wrapper.before_call.sink.indent()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   121
        wrapper.before_call.write_code('''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   122
PyObject *item = PyList_GET_ITEM(%(py_name)s, %(idx)s);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   123
''' % vars())
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   124
        #wrapper.before_call.write_error_check('item == NULL')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   125
        wrapper.before_call.write_error_check(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   126
            '!PyString_Check(item)',
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   127
            failure_cleanup=('PyErr_SetString(PyExc_TypeError, '
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   128
                             '"argument %s must be a list of strings");') % self.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   129
        wrapper.before_call.write_code(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   130
            '%s[%s] = PyString_AsString(item);' % (name, idx))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   131
        wrapper.before_call.sink.unindent()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   132
        wrapper.before_call.write_code('}')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   133
        wrapper.before_call.write_code('%s = PyList_Size(%s);' % (argc_var, py_name))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   134
        
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   135
        wrapper.call_params.append(argc_var)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   136
        wrapper.call_params.append(name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   137
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   138
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   139
class CallbackImplProxyMethod(typehandlers.ReverseWrapperBase):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   140
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   141
    Class that generates a proxy virtual method that calls a similarly named python method.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   142
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   143
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   144
    def __init__(self, return_value, parameters):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   145
        super(CallbackImplProxyMethod, self).__init__(return_value, parameters)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   146
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   147
    def generate_python_call(self):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   148
        """code to call the python method"""
3412
518719e905a0 Fix a problem with callback proxies with zero or one parameters.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3408
diff changeset
   149
        build_params = self.build_params.get_parameters(force_tuple_creation=True)
3408
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   150
        if build_params[0][0] == '"':
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   151
            build_params[0] = '(char *) ' + build_params[0]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   152
        args = self.before_call.declare_variable('PyObject*', 'args')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   153
        self.before_call.write_code('%s = Py_BuildValue(%s);'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   154
                                    % (args, ', '.join(build_params)))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   155
        self.before_call.add_cleanup_code('Py_DECREF(%s);' % args)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   156
        self.before_call.write_code('py_retval = PyObject_CallObject(m_callback, %s);' % args)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   157
        self.before_call.write_error_check('py_retval == NULL')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   158
        self.before_call.add_cleanup_code('Py_DECREF(py_retval);')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   159
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   160
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   161
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   162
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   163
def generate_callback_classes(out, callbacks):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   164
    for callback_impl_num, template_parameters in enumerate(callbacks):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   165
        sink = MemoryCodeSink()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   166
        cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   167
        #print >> sys.stderr, "***** trying to register callback: %r" % cls_name
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   168
        class_name = "PythonCallbackImpl%i" % callback_impl_num
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   169
        sink.writeln('''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   170
class %s : public ns3::CallbackImpl<%s>
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   171
{
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   172
public:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   173
    PyObject *m_callback;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   174
    %s(PyObject *callback)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   175
    {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   176
        Py_INCREF(callback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   177
        m_callback = callback;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   178
    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   179
    virtual ~%s()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   180
    {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   181
        Py_DECREF(m_callback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   182
        m_callback = NULL;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   183
    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   184
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   185
    virtual bool IsEqual(ns3::Ptr<const ns3::CallbackImplBase> other_base) const
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   186
    {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   187
        const %s *other = dynamic_cast<const %s*> (ns3::PeekPointer (other_base));
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   188
        if (other != NULL)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   189
            return (other->m_callback == m_callback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   190
        else
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   191
            return false;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   192
    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   193
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   194
''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   195
        sink.indent()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   196
        callback_return = template_parameters[0]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   197
        return_ctype = ctypeparser.parse_type(callback_return)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   198
        if ('const' in return_ctype.remove_modifiers()):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   199
            kwargs = {'is_const': True}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   200
        else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   201
            kwargs = {}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   202
        try:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   203
            return_type = ReturnValue.new(str(return_ctype), **kwargs)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   204
        except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   205
            warnings.warn("***** Unable to register callback; Return value '%s' error (used in %s): %r"
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   206
                          % (callback_return, cls_name, ex),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   207
                          Warning)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   208
            continue
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   209
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   210
        arguments = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   211
        ok = True
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   212
        callback_parameters = [arg for arg in template_parameters[1:] if arg != 'ns3::empty']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   213
        for arg_num, arg_type in enumerate(callback_parameters):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   214
            arg_name = 'arg%i' % (arg_num+1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   215
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   216
            param_ctype = ctypeparser.parse_type(arg_type)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   217
            if ('const' in param_ctype.remove_modifiers()):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   218
                kwargs = {'is_const': True}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   219
            else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   220
                kwargs = {}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   221
            try:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   222
                arguments.append(Parameter.new(str(param_ctype), arg_name, **kwargs))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   223
            except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   224
                warnings.warn("***** Unable to register callback; parameter '%s %s' error (used in %s): %r"
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   225
                              % (arg_type, arg_name, cls_name, ex),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   226
                              Warning)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   227
                ok = False
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   228
        if not ok:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   229
            continue
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   230
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   231
        wrapper = CallbackImplProxyMethod(return_type, arguments)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   232
        wrapper.generate(sink, 'operator()', decl_modifiers=[])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   233
            
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   234
        sink.unindent()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   235
        sink.writeln('};\n')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   236
        sink.flush_to(out)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   237
        
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   238
        class PythonCallbackParameter(Parameter):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   239
            "Class handlers"
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   240
            CTYPES = [cls_name]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   241
            #print >> sys.stderr, "***** registering callback handler: %r" % ctypeparser.normalize_type_string(cls_name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   242
            DIRECTIONS = [Parameter.DIRECTION_IN]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   243
            PYTHON_CALLBACK_IMPL_NAME = class_name
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   244
            TEMPLATE_ARGS = template_parameters
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   245
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   246
            def convert_python_to_c(self, wrapper):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   247
                "parses python args to get C++ value"
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   248
                assert isinstance(wrapper, typehandlers.ForwardWrapperBase)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   249
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   250
                py_callback = wrapper.declarations.declare_variable('PyObject*', self.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   251
                wrapper.parse_params.add_parameter('O', ['&'+py_callback], self.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   252
                wrapper.before_call.write_error_check(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   253
                    '!PyCallable_Check(%s)' % py_callback,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   254
                    'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");' % self.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   255
                callback_impl = wrapper.declarations.declare_variable(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   256
                    'ns3::Ptr<%s>' % self.PYTHON_CALLBACK_IMPL_NAME,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   257
                    '%s_cb_impl' % self.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   258
                wrapper.before_call.write_code("%s = ns3::Create<%s> (%s);"
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   259
                                               % (callback_impl, self.PYTHON_CALLBACK_IMPL_NAME, py_callback))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   260
                wrapper.call_params.append(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   261
                    'ns3::Callback<%s> (%s)' % (', '.join(self.TEMPLATE_ARGS), callback_impl))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   262
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   263
            def convert_c_to_python(self, wrapper):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   264
                raise typehandlers.NotSupportedError("Reverse wrappers for ns3::Callback<...> types "
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   265
                                                     "(python using callbacks defined in C++) not implemented.")
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   266
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   267
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   268
# def write_preamble(out):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   269
#     pybindgen.write_preamble(out)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   270
#     out.writeln("#include \"ns3/everything.h\"")
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   271
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   272
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   273
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   274
def Simulator_customizations(module):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   275
    Simulator = module['ns3::Simulator']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   276
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   277
    ## Simulator::Schedule(delay, callback, ...user..args...)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   278
    Simulator.add_custom_method_wrapper("Schedule", "_wrap_Simulator_Schedule",
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   279
                                        flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   280
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   281
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   282
    ## Simulator::ScheduleNow(callback, ...user..args...)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   283
    Simulator.add_custom_method_wrapper("ScheduleNow", "_wrap_Simulator_ScheduleNow",
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   284
                                        flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   285
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   286
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   287
    ## Simulator::ScheduleDestroy(callback, ...user..args...)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   288
    Simulator.add_custom_method_wrapper("ScheduleDestroy", "_wrap_Simulator_ScheduleDestroy",
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   289
                                        flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   290
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   291
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   292
def CommandLine_customizations(module):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   293
    CommandLine = module['ns3::CommandLine']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   294
    CommandLine.add_method('Parse', None, [ArgvParam(None, 'argv')],
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   295
                           is_static=False)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   296
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   297
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   298
def Object_customizations(module):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   299
    ## ---------------------------------------------------------------------
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   300
    ## Here we generate custom constructor code for all classes that
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   301
    ## derive from ns3::Object.  The custom constructors are needed in
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   302
    ## order to support kwargs only and to translate kwargs into ns3
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   303
    ## attributes, etc.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   304
    ## ---------------------------------------------------------------------
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   305
    Object = module['ns3::Object']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   306
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   307
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   308
    ## add a GetTypeId method to all generatd helper classes
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   309
    def helper_class_hook(helper_class):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   310
        decl = """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   311
static ns3::TypeId GetTypeId (void)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   312
{
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   313
  static ns3::TypeId tid = ns3::TypeId ("%s")
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   314
    .SetParent< %s > ()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   315
    ;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   316
  return tid;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   317
}"""  % (helper_class.name, helper_class.class_.full_name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   318
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   319
        helper_class.add_custom_method(decl)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   320
        helper_class.add_post_generation_code(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   321
            "NS_OBJECT_ENSURE_REGISTERED (%s);" % helper_class.name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   322
    Object.add_helper_class_hook(helper_class_hook)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   323
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   324
    ## Replace all class constructors with a generic constructor based on CreateObject<T> (AttributeList)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   325
    module.header.writeln('''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   326
namespace ns3 {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   327
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   328
void PythonCompleteConstruct (Ptr<Object> object, TypeId typeId, const AttributeList &attributes);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   329
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   330
template <typename T>
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   331
Ptr<T> CreateObjectPython (PyObject *pyobj, const AttributeList &attributes)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   332
{
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   333
  Ptr<T> p = Ptr<T> (new T (), false);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   334
  p->set_pyobj (pyobj);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   335
  PythonCompleteConstruct (p, T::GetTypeId (), attributes);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   336
  return p;  
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   337
}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   338
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   339
} // namespace ns3
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   340
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   341
''')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   342
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   343
    for cls in module.classes:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   344
        if not cls.is_subclass(Object):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   345
            continue
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   346
        cls.constructors = [] # clear the list of constructors
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   347
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   348
        ## add our own custom constructor, if possible
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   349
        try:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   350
            construct_name = cls.get_construct_name()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   351
        except CodeGenerationError:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   352
            construct_name = None
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   353
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   354
        if construct_name and not cls.helper_class:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   355
            construct_code = '''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   356
    ns3::Ptr< %(CONSTRUCT_NAME)s > obj = ns3::CreateObject< %(CONSTRUCT_NAME)s > (attrList);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   357
    obj->Ref ();
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   358
    self->obj = ns3::PeekPointer (obj);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   359
''' % dict (CONSTRUCT_NAME=construct_name)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   360
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   361
        elif not construct_name and not cls.helper_class:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   362
            continue
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   363
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   364
        elif not construct_name and cls.helper_class:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   365
            construct_code = '''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   366
    if (self->ob_type != &%(PYTYPESTRUCT)s)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   367
    {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   368
        ns3::Ptr< %(HELPER_CLASS_NAME)s > obj = ns3::CreateObjectPython< %(HELPER_CLASS_NAME)s > ((PyObject *)self, attrList);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   369
        obj->Ref ();
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   370
        self->obj = ns3::PeekPointer (obj);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   371
    } else {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   372
        PyErr_SetString(PyExc_TypeError, "Class cannot be constructed (unless subclassed)");
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   373
        {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   374
            PyObject *exc_type, *traceback;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   375
            PyErr_Fetch(&exc_type, return_exception, &traceback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   376
            Py_XDECREF(exc_type);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   377
            Py_XDECREF(traceback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   378
        }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   379
        return -1;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   380
    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   381
''' % dict (CONSTRUCT_NAME=construct_name, HELPER_CLASS_NAME=cls.helper_class.name,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   382
            PYTYPESTRUCT=cls.pytypestruct)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   383
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   384
        elif construct_name and cls.helper_class:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   385
            construct_code = '''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   386
    if (self->ob_type != &%(PYTYPESTRUCT)s)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   387
    {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   388
        ns3::Ptr< %(HELPER_CLASS_NAME)s > obj = ns3::CreateObjectPython< %(HELPER_CLASS_NAME)s > ((PyObject *)self, attrList);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   389
        obj->Ref ();
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   390
        self->obj = ns3::PeekPointer (obj);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   391
    } else {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   392
        ns3::Ptr< %(CONSTRUCT_NAME)s > obj = ns3::CreateObject< %(CONSTRUCT_NAME)s > (attrList);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   393
        obj->Ref ();
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   394
        self->obj = ns3::PeekPointer (obj);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   395
    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   396
''' % dict (CONSTRUCT_NAME=construct_name, HELPER_CLASS_NAME=cls.helper_class.name,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   397
            PYTYPESTRUCT=cls.pytypestruct)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   398
        else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   399
            raise AssertionError
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   400
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   401
        wrapper_name = "_wrap_create_object_%s" % (cls.full_name.replace(':', '_'),) 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   402
        constructor = '''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   403
static int %(WRAPPER_NAME)s (%(PYSTRUCT)s *self, PyObject *args, PyObject *kwargs, PyObject **return_exception)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   404
{
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   405
    if (PyTuple_Size(args)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   406
        PyErr_SetString(PyExc_TypeError, "positional arguments not supported "
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   407
                        "for ns3.Object constructors, only keyword arguments"
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   408
                        " should be used (AttributeName=Value)");
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   409
        {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   410
            PyObject *exc_type, *traceback;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   411
            PyErr_Fetch(&exc_type, return_exception, &traceback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   412
            Py_XDECREF(exc_type);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   413
            Py_XDECREF(traceback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   414
        }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   415
        return -1;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   416
    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   417
    ns3::AttributeList attrList;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   418
    if (kwargs && KwargsToAttributeList(kwargs, %(CLASS_NAME)s::GetTypeId(), attrList)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   419
        {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   420
            PyObject *exc_type, *traceback;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   421
            PyErr_Fetch(&exc_type, return_exception, &traceback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   422
            Py_XDECREF(exc_type);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   423
            Py_XDECREF(traceback);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   424
        }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   425
        return -1;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   426
    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   427
    %(CONSTRUCT_CODE)s
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   428
    return 0;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   429
}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   430
''' % dict(WRAPPER_NAME=wrapper_name, PYSTRUCT=cls.pystruct, CLASS_NAME=cls.full_name,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   431
           CONSTRUCT_CODE=construct_code, PURE_VIRTUALS=cls.have_pure_virtual_methods)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   432
        cls.add_constructor(CustomCppConstructorWrapper(wrapper_name, constructor))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   433
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   434
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   435
    # Generate conversion function from PyObject* to AttributeValue
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   436
#     sink = module.body
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   437
#     sink.writeln('''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   438
# Ptr<AttributeValue> AttributeValueFromPyObject (PyObject *obj)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   439
# {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   440
#     // note: needs to check for bool first, because bool is a subclass of int
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   441
#     if (PyBool_Check(obj)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   442
#         return Create<BooleanValue>(PyObject_IsTrue(obj));
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   443
#     } else if (PyInt_Check(obj)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   444
#         return Create<IntegerValue>(PyInt_AsLong(obj));
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   445
#     } else if (PyLong_Check(obj)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   446
#         return Create<IntegerValue>(PyLong_AsLongLong(obj));
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   447
#     } else if (PyFloat_Check(obj)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   448
#         return Create<DoubleValue>(PyFloat_AsDouble(obj));
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   449
#     }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   450
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   451
# ''')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   452
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   453
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   454
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   455
    ## ---------------------------------------------------------------------
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   456
    ## -------------- write the KwargsToAttributeList function -------------
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   457
    ## ---------------------------------------------------------------------
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   458
    Attribute = module['ns3::AttributeValue']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   459
    module.after_forward_declarations.writeln(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   460
        'int KwargsToAttributeList(PyObject *kwargs, ns3::TypeId tid, ns3::AttributeList &oAttrList);')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   461
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   462
    module.body.writeln(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   463
'''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   464
int KwargsToAttributeList(PyObject *kwargs, ns3::TypeId tid, ns3::AttributeList &oAttrList)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   465
{
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   466
    PyObject *key, *value;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   467
    Py_ssize_t pos = 0;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   468
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   469
    while (PyDict_Next(kwargs, &pos, &key, &value)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   470
        if (!PyString_Check(key)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   471
            PyErr_SetString(PyExc_TypeError, "kwargs keys must be strings");
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   472
            return -1;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   473
        }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   474
        if (PyObject_IsInstance(value, (PyObject*) &%s)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   475
            oAttrList.SetWithTid(tid, PyString_AsString(key), *((%s *) value)->obj);''' \
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   476
    % (Attribute.pytypestruct, Attribute.pystruct))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   477
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   478
    for conversion_source in Attribute.get_all_implicit_conversions():
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   479
        module.body.writeln('''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   480
        } else if (PyObject_IsInstance(value, (PyObject*) &%s)) {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   481
            oAttrList.SetWithTid(tid, PyString_AsString(key), *((%s *) value)->obj);''' \
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   482
                        % (conversion_source.pytypestruct, conversion_source.pystruct))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   483
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   484
    possible_type_names = ", ".join([cls.name for cls in [Attribute] + Attribute.get_all_implicit_conversions()])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   485
    module.body.writeln('''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   486
        } else {
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   487
            PyErr_Format(PyExc_TypeError, \"parameter must an instance of one of the types (%s), not %%s\", value->ob_type->tp_name);
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   488
            return -1;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   489
        }''' % (possible_type_names))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   490
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   491
    module.body.writeln(
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   492
'''
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   493
    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   494
    return 0;
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   495
}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   496
''')
3421
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   497
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   498
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   499
def Attribute_customizations(module):
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   500
    # Fix up for the "const AttributeValue &v = EmptyAttribute()"
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   501
    # case, as used extensively by helper classes.
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   502
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   503
    # Here's why we need to do this: pybindgen.gccxmlscanner, when
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   504
    # scanning parameter default values, is only provided with the
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   505
    # value as a simple C expression string.  (py)gccxml does not
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   506
    # report the type of the default value.
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   507
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   508
    # As a workaround, here we iterate over all parameters of all
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   509
    # methods of all classes and tell pybindgen what is the type of
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   510
    # the default value for attributes.
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   511
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   512
    for cls in module.classes:
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   513
        for meth in cls.get_all_methods():
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   514
            for param in meth.parameters:
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   515
                if isinstance(param, cppclass.CppClassRefParameter):
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   516
                    if param.cpp_class.name == 'AttributeValue' \
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   517
                            and param.default_value is not None \
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   518
                            and param.default_value_type is None:
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   519
                        param.default_value_type = 'ns3::EmptyAttributeValue'
b9424c43753d Python: make helper class methods using attribute optional parameters work.
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents: 3412
diff changeset
   520