Add support for customising an 'instance creation function', for cases when creating instances with new ClassName does not work (*cough*ns-3*cough*).

This commit is contained in:
Gustavo J. A. M. Carneiro committed 2008-02-05 22:45:12 +00:00
1 parent d931ff818b
commit 06882321d8
6 files changed
+122 -42

No files matched your search

+84 -28
View File
@@ -22,6 +22,27 @@ import settings
import utils
def default_instance_creation_function(cpp_class, code_block, lvalue,
parameters, construct_type_name):
"""
Default "instance creation function"; it is called whenever a new
C++ class instance needs to be created; this default
implementation uses a standard C++ new allocator.
cpp_class -- the CppClass object whose instance is to be created
code_block -- CodeBlock object on which the instance creation code should be generated
lvalue -- lvalue expression that should hold the result in the end
contruct_type_name -- actual name of type to be constructed (it is
not always the class name, sometimes it's
the python helper class)
parameters -- stringified list of parameters
"""
assert lvalue
assert not lvalue.startswith('None')
code_block.write_code(
"%s = new %s(%s);" % (lvalue, construct_type_name, parameters))
class CppHelperClass(object):
"""
Generates code for a C++ proxy subclass that takes care of
@@ -302,6 +323,7 @@ class CppClass(object):
self.constructors = [] # (name, wrapper) pairs
self.slots = dict()
self.helper_class = None
self.instance_creation_function = None
## set to True when we become aware generating the helper
## class is not going to be possible
self.helper_class_disabled = False
@@ -410,6 +432,30 @@ class CppClass(object):
except ValueError:
pass
def set_instance_creation_function(self, instance_creation_function):
"""Set a custom function to be called to create instances of this
class and its subclasses.
instance_creation_function -- instance creation function; see
default_instance_creation_function()
for signature and example.
"""
self.instance_creation_function = instance_creation_function
def get_instance_creation_function(self):
if self.instance_creation_function is None:
if self.parent is None:
return default_instance_creation_function
else:
return self.parent.get_instance_creation_function()
else:
return self.instance_creation_function
def write_create_instance(self, code_block, lvalue, parameters, construct_type_name=None):
instance_creation_func = self.get_instance_creation_function()
if construct_type_name is None:
construct_type_name = self.get_construct_name()
instance_creation_func(self, code_block, lvalue, parameters, construct_type_name)
def get_pystruct(self):
if self._pystruct is None:
@@ -1151,8 +1197,9 @@ class CppClassParameter(CppClassParameterBase):
wrapper.before_call.write_code(
"%s->inst_dict = NULL;" % (self.py_name,))
wrapper.before_call.write_code(
"%s->obj = new %s(%s);" % (self.py_name, self.cpp_class.get_construct_name(), self.value))
self.cpp_class.write_create_instance(wrapper.before_call,
"%s->obj" % self.py_name,
self.value)
wrapper.build_params.add_parameter("N", [self.py_name])
@@ -1208,8 +1255,10 @@ class CppClassRefParameter(CppClassParameterBase):
if self.cpp_class.allow_subclassing:
wrapper.after_call.write_code(
"%s->inst_dict = NULL;" % (self.py_name,))
wrapper.before_call.write_code(
"%s->obj = new %s;" % (self.py_name, self.cpp_class.get_construct_name()))
self.cpp_class.write_create_instance(wrapper.before_call,
"%s->obj" % self.py_name,
'')
wrapper.call_params.append('*%s->obj' % (self.py_name,))
wrapper.build_params.add_parameter("N", [self.py_name])
@@ -1248,8 +1297,9 @@ class CppClassRefParameter(CppClassParameterBase):
"%s->inst_dict = NULL;" % (self.py_name,))
if self.direction == Parameter.DIRECTION_IN:
wrapper.before_call.write_code(
"%s->obj = new %s(%s);" % (self.py_name, self.cpp_class.get_construct_name(), self.value))
self.cpp_class.write_create_instance(wrapper.before_call,
"%s->obj" % self.py_name,
self.value)
wrapper.build_params.add_parameter("N", [self.py_name])
else:
## out/inout case:
@@ -1274,11 +1324,13 @@ class CppClassRefParameter(CppClassParameterBase):
wrapper.after_call.write_code(
"if (%s->ob_refcnt == 1)\n"
" %s->obj = NULL;\n"
"else\n"
" %s->obj = new %s(%s);" %
(self.py_name, self.py_name, self.py_name,
self.cpp_class.get_construct_name(), self.value))
"else{\n" % (self.py_name, self.py_name))
wrapper.after_call.indent()
self.cpp_class.write_create_instance(wrapper.after_call,
"%s->obj" % self.py_name,
self.value)
wrapper.after_call.unindent()
wrapper.after_call.write_code('}')
class CppClassReturnValue(CppClassReturnValueBase):
@@ -1313,8 +1365,11 @@ class CppClassReturnValue(CppClassReturnValueBase):
if self.cpp_class.allow_subclassing:
wrapper.after_call.write_code(
"%s->inst_dict = NULL;" % (py_name,))
wrapper.after_call.write_code(
"%s->obj = new %s(%s);" % (py_name, self.cpp_class.get_construct_name(), self.value))
self.cpp_class.write_create_instance(wrapper.after_call,
"%s->obj" % py_name,
self.value)
wrapper.build_params.add_parameter("N", [py_name], prepend=True)
def convert_python_to_c(self, wrapper):
@@ -1456,10 +1511,9 @@ class CppClassPtrParameter(CppClassParameterBase):
## the object after the call.
if self.direction == Parameter.DIRECTION_IN:
wrapper.before_call.write_code(
"%s->obj = new %s(*%s);" %
(self.py_name, self.cpp_class.get_construct_name(), self.value))
self.cpp_class.write_create_instance(wrapper.before_call,
"%s->obj" % self.py_name,
'*'+self.value)
wrapper.build_params.add_parameter("N", [self.py_name])
else:
## out/inout case:
@@ -1484,11 +1538,13 @@ class CppClassPtrParameter(CppClassParameterBase):
wrapper.after_call.write_code(
"if (%s->ob_refcnt == 1)\n"
" %s->obj = NULL;\n"
"else\n"
" %s->obj = new %s(*%s);" %
(self.py_name, self.py_name, self.py_name,
self.cpp_class.get_construct_name(), value))
"else {\n" % (self.py_name, self.py_name))
wrapper.after_call.indent()
self.cpp_class.write_create_instance(wrapper.after_call,
"%s->obj" % self.py_name,
'*'+value)
wrapper.after_call.unindent()
wrapper.after_call.write_code('}')
else:
## The PyObject gets a new reference to the same obj
wrapper.before_call.write_code(
@@ -1646,9 +1702,9 @@ class CppClassPtrReturnValue(CppClassReturnValueBase):
else:
if self.cpp_class.incref_method is None:
## The PyObject creates its own copy
wrapper.after_call.write_code(
"%s->obj = new %s(*%s);"
% (py_name, self.cpp_class.get_construct_name(), value))
self.cpp_class.write_create_instance(wrapper.after_call,
"%s->obj" % py_name,
'*'+value)
else:
## The PyObject gets a new reference to the same obj
wrapper.after_call.write_code(
@@ -1710,9 +1766,9 @@ class CppClassPtrReturnValue(CppClassReturnValueBase):
if self.caller_owns_return:
if self.cpp_class.incref_method is None:
## the caller receives a copy
wrapper.after_call.write_code(
"%s = new %s(*%s);"
% (self.value, self.cpp_class.get_construct_name(), value))
self.cpp_class.write_create_instance(wrapper.after_call,
"%s" % self.value,
'*'+value)
else:
## the caller gets a new reference to the same obj
wrapper.after_call.write_code(