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