def generate_callback_classes(out, callbacks): for callback_impl_num, template_parameters in enumerate(callbacks): sink = MemoryCodeSink() cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters) class_name = "PythonCallbackImpl%i" % callback_impl_num sink.writeln( % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name)) sink.indent() callback_return = template_parameters[0] return_ctype = ctypeparser.parse_type(callback_return) if ('const' in return_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: return_type = ReturnValue.new(str(return_ctype), **kwargs) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex: warnings.warn("***** Unable to register callback; Return value '%s' error (used in %s): %r" % (callback_return, cls_name, ex), Warning) continue arguments = [] ok = True callback_parameters = [arg for arg in template_parameters[1:] if arg != 'ns3::empty'] for arg_num, arg_type in enumerate(callback_parameters): arg_name = 'arg%i' % (arg_num+1) param_ctype = ctypeparser.parse_type(arg_type) if ('const' in param_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: arguments.append(Parameter.new(str(param_ctype), arg_name, **kwargs)) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex: warnings.warn("***** Unable to register callback; parameter '%s %s' error (used in %s): %r" % (arg_type, arg_name, cls_name, ex), Warning) ok = False
def generate_callback_classes(out, callbacks): for callback_impl_num, template_parameters in enumerate(callbacks): sink = MemoryCodeSink() cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters) #print >> sys.stderr, "***** trying to register callback: %r" % cls_name class_name = "PythonCallbackImpl%i" % callback_impl_num sink.writeln(''' class %s : public ns3::CallbackImpl<%s> { public: PyObject *m_callback; %s(PyObject *callback) { Py_INCREF(callback); m_callback = callback; } virtual ~%s() { Py_DECREF(m_callback); m_callback = NULL; } virtual bool IsEqual(ns3::Ptr<const ns3::CallbackImplBase> other_base) const { const %s *other = dynamic_cast<const %s*> (ns3::PeekPointer (other_base)); if (other != NULL) return (other->m_callback == m_callback); else return false; } ''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name)) sink.indent() callback_return = template_parameters[0] return_ctype = ctypeparser.parse_type(callback_return) if ('const' in return_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: return_type = ReturnValue.new(str(return_ctype), **kwargs) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex: warnings.warn( "***** Unable to register callback; Return value '%s' error (used in %s): %r" % (callback_return, cls_name, ex), Warning) continue arguments = [] ok = True callback_parameters = [ arg for arg in template_parameters[1:] if arg != 'ns3::empty' ] for arg_num, arg_type in enumerate(callback_parameters): arg_name = 'arg%i' % (arg_num + 1) param_ctype = ctypeparser.parse_type(arg_type) if ('const' in param_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: arguments.append( Parameter.new(str(param_ctype), arg_name, **kwargs)) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex: warnings.warn( "***** Unable to register callback; parameter '%s %s' error (used in %s): %r" % (arg_type, arg_name, cls_name, ex), Warning) ok = False
def generate_callback_classes(module, callbacks): out = module.after_forward_declarations for callback_impl_num, template_parameters in enumerate(callbacks): sink = MemoryCodeSink() cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters) #print >> sys.stderr, "***** trying to register callback: %r" % cls_name class_name = "PythonCallbackImpl%i" % callback_impl_num sink.writeln(''' class %s : public ns3::CallbackImpl<%s> { public: PyObject *m_callback; %s(PyObject *callback) { Py_INCREF(callback); m_callback = callback; } virtual ~%s() { PyGILState_STATE __py_gil_state; __py_gil_state = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0); Py_DECREF(m_callback); m_callback = NULL; PyGILState_Release(__py_gil_state); } virtual bool IsEqual(ns3::Ptr<const ns3::CallbackImplBase> other_base) const { const %s *other = dynamic_cast<const %s*> (ns3::PeekPointer (other_base)); if (other != NULL) return (other->m_callback == m_callback); else return false; } ''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name)) sink.indent() callback_return = template_parameters[0] return_ctype = ctypeparser.parse_type(callback_return) if ('const' in return_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: return_type = ReturnValue.new(str(return_ctype), **kwargs) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError) as ex: warnings.warn("***** Unable to register callback; Return value '%s' error (used in %s): %r" % (callback_return, cls_name, ex), Warning) continue arguments = [] ok = True callback_parameters = [arg for arg in template_parameters[1:] if arg != 'ns3::empty'] for arg_num, arg_type in enumerate(callback_parameters): arg_name = 'arg%i' % (arg_num+1) param_ctype = ctypeparser.parse_type(arg_type) if ('const' in param_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: param = Parameter.new(str(param_ctype), arg_name, **kwargs) cpp_class = getattr(param, "cpp_class", None) if isinstance(cpp_class, cppclass.CppClass): # check if the "helper class" can be constructed if cpp_class.helper_class is not None: cpp_class.helper_class.generate_forward_declarations( MemoryCodeSink()) if cpp_class.helper_class.cannot_be_constructed: cpp_class.helper_class = None cpp_class.helper_class_disabled = True arguments.append(param) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError) as ex: warnings.warn("***** Unable to register callback; parameter '%s %s' error (used in %s): %r" % (arg_type, arg_name, cls_name, ex), Warning) ok = False if not ok: try: typehandlers.return_type_matcher.lookup(cls_name)[0].DISABLED = True except typehandlers.TypeLookupError: pass try: typehandlers.param_type_matcher.lookup(cls_name)[0].DISABLED = True except typehandlers.TypeLookupError: pass continue wrapper = CallbackImplProxyMethod(return_type, arguments) wrapper.generate(sink, 'operator()', decl_modifiers=[]) sink.unindent() sink.writeln('};\n') print("Flushing to ", out, file=sys.stderr) sink.flush_to(out)
def generate_callback_classes(module, callbacks): out = module.after_forward_declarations for callback_impl_num, template_parameters in enumerate(callbacks): sink = MemoryCodeSink() cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters) #print >> sys.stderr, "***** trying to register callback: %r" % cls_name class_name = "PythonCallbackImpl%i" % callback_impl_num sink.writeln(''' class %s : public ns3::CallbackImpl<%s> { public: PyObject *m_callback; %s(PyObject *callback) { Py_INCREF(callback); m_callback = callback; } virtual ~%s() { PyGILState_STATE __py_gil_state; __py_gil_state = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0); Py_DECREF(m_callback); m_callback = NULL; PyGILState_Release(__py_gil_state); } virtual bool IsEqual(ns3::Ptr<const ns3::CallbackImplBase> other_base) const { const %s *other = dynamic_cast<const %s*> (ns3::PeekPointer (other_base)); if (other != NULL) return (other->m_callback == m_callback); else return false; } ''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name)) sink.indent() callback_return = template_parameters[0] return_ctype = ctypeparser.parse_type(callback_return) if ('const' in return_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: return_type = ReturnValue.new(str(return_ctype), **kwargs) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError) as ex: warnings.warn( "***** Unable to register callback; Return value '%s' error (used in %s): %r" % (callback_return, cls_name, ex), Warning) continue arguments = [] ok = True callback_parameters = [ arg for arg in template_parameters[1:] if arg != 'ns3::empty' ] for arg_num, arg_type in enumerate(callback_parameters): arg_name = 'arg%i' % (arg_num + 1) param_ctype = ctypeparser.parse_type(arg_type) if ('const' in param_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: param = Parameter.new(str(param_ctype), arg_name, **kwargs) cpp_class = getattr(param, "cpp_class", None) if isinstance(cpp_class, cppclass.CppClass): # check if the "helper class" can be constructed if cpp_class.helper_class is not None: cpp_class.helper_class.generate_forward_declarations( MemoryCodeSink()) if cpp_class.helper_class.cannot_be_constructed: cpp_class.helper_class = None cpp_class.helper_class_disabled = True arguments.append(param) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError) as ex: warnings.warn( "***** Unable to register callback; parameter '%s %s' error (used in %s): %r" % (arg_type, arg_name, cls_name, ex), Warning) ok = False if not ok: try: typehandlers.return_type_matcher.lookup( cls_name)[0].DISABLED = True except typehandlers.TypeLookupError: pass try: typehandlers.param_type_matcher.lookup( cls_name)[0].DISABLED = True except typehandlers.TypeLookupError: pass continue wrapper = CallbackImplProxyMethod(return_type, arguments) wrapper.generate(sink, 'operator()', decl_modifiers=[]) sink.unindent() sink.writeln('};\n') print("Flushing to ", out, file=sys.stderr) sink.flush_to(out)
def generate_callback_classes(out, callbacks): for callback_impl_num, template_parameters in enumerate(callbacks): sink = MemoryCodeSink() cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters) #print >> sys.stderr, "***** trying to register callback: %r" % cls_name class_name = "PythonCallbackImpl%i" % callback_impl_num sink.writeln(''' class %s : public ns3::CallbackImpl<%s> { public: PyObject *m_callback; %s(PyObject *callback) { Py_INCREF(callback); m_callback = callback; } virtual ~%s() { Py_DECREF(m_callback); m_callback = NULL; } virtual bool IsEqual(ns3::Ptr<const ns3::CallbackImplBase> other_base) const { const %s *other = dynamic_cast<const %s*> (ns3::PeekPointer (other_base)); if (other != NULL) return (other->m_callback == m_callback); else return false; } ''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name)) sink.indent() callback_return = template_parameters[0] return_ctype = ctypeparser.parse_type(callback_return) if ('const' in return_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: return_type = ReturnValue.new(str(return_ctype), **kwargs) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex: warnings.warn("***** Unable to register callback; Return value '%s' error (used in %s): %r" % (callback_return, cls_name, ex), Warning) continue arguments = [] ok = True callback_parameters = [arg for arg in template_parameters[1:] if arg != 'ns3::empty'] for arg_num, arg_type in enumerate(callback_parameters): arg_name = 'arg%i' % (arg_num+1) param_ctype = ctypeparser.parse_type(arg_type) if ('const' in param_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: arguments.append(Parameter.new(str(param_ctype), arg_name, **kwargs)) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex: warnings.warn("***** Unable to register callback; parameter '%s %s' error (used in %s): %r" % (arg_type, arg_name, cls_name, ex), Warning) ok = False
def generate_callback_classes(out, callbacks): for callback_impl_num, template_parameters in enumerate(callbacks): sink = MemoryCodeSink() cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters) #print >> sys.stderr, "***** trying to register callback: %r" % cls_name class_name = "PythonCallbackImpl%i" % callback_impl_num sink.writeln(''' class %s : public ns3::CallbackImpl<%s> { public: PyObject *m_callback; %s(PyObject *callback) { Py_INCREF(callback); m_callback = callback; } virtual ~%s() { PyGILState_STATE __py_gil_state; __py_gil_state = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0); Py_DECREF(m_callback); m_callback = NULL; PyGILState_Release(__py_gil_state); } virtual bool IsEqual(ns3::Ptr<const ns3::CallbackImplBase> other_base) const { const %s *other = dynamic_cast<const %s*> (ns3::PeekPointer (other_base)); if (other != NULL) return (other->m_callback == m_callback); else return false; } ''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name)) sink.indent() callback_return = template_parameters[0] return_ctype = ctypeparser.parse_type(callback_return) if ('const' in return_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: return_type = ReturnValue.new(str(return_ctype), **kwargs) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError) as ex: warnings.warn("***** Unable to register callback; Return value '%s' error (used in %s): %r" % (callback_return, cls_name, ex), Warning) continue arguments = [] ok = True callback_parameters = [arg for arg in template_parameters[1:] if arg != 'ns3::empty'] for arg_num, arg_type in enumerate(callback_parameters): arg_name = 'arg%i' % (arg_num+1) param_ctype = ctypeparser.parse_type(arg_type) if ('const' in param_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: arguments.append(Parameter.new(str(param_ctype), arg_name, **kwargs)) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError) as ex: warnings.warn("***** Unable to register callback; parameter '%s %s' error (used in %s): %r" % (arg_type, arg_name, cls_name, ex), Warning) ok = False if not ok: continue wrapper = CallbackImplProxyMethod(return_type, arguments) wrapper.generate(sink, 'operator()', decl_modifiers=[]) sink.unindent() sink.writeln('};\n') sink.flush_to(out) class PythonCallbackParameter(Parameter): "Class handlers" CTYPES = [cls_name] print("***** registering callback handler: %r" % ctypeparser.normalize_type_string(cls_name), file=sys.stderr) DIRECTIONS = [Parameter.DIRECTION_IN] PYTHON_CALLBACK_IMPL_NAME = class_name TEMPLATE_ARGS = template_parameters def convert_python_to_c(self, wrapper): "parses python args to get C++ value" assert isinstance(wrapper, typehandlers.ForwardWrapperBase) if self.default_value is None: py_callback = wrapper.declarations.declare_variable('PyObject*', self.name) wrapper.parse_params.add_parameter('O', ['&'+py_callback], self.name) wrapper.before_call.write_error_check( '!PyCallable_Check(%s)' % py_callback, 'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");' % self.name) callback_impl = wrapper.declarations.declare_variable( 'ns3::Ptr<%s>' % self.PYTHON_CALLBACK_IMPL_NAME, '%s_cb_impl' % self.name) wrapper.before_call.write_code("%s = ns3::Create<%s> (%s);" % (callback_impl, self.PYTHON_CALLBACK_IMPL_NAME, py_callback)) wrapper.call_params.append( 'ns3::Callback<%s> (%s)' % (', '.join(self.TEMPLATE_ARGS), callback_impl)) else: py_callback = wrapper.declarations.declare_variable('PyObject*', self.name, 'NULL') wrapper.parse_params.add_parameter('O', ['&'+py_callback], self.name, optional=True) value = wrapper.declarations.declare_variable( 'ns3::Callback<%s>' % ', '.join(self.TEMPLATE_ARGS), self.name+'_value', self.default_value) wrapper.before_call.write_code("if (%s) {" % (py_callback,)) wrapper.before_call.indent() wrapper.before_call.write_error_check( '!PyCallable_Check(%s)' % py_callback, 'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");' % self.name) wrapper.before_call.write_code("%s = ns3::Callback<%s> (ns3::Create<%s> (%s));" % (value, ', '.join(self.TEMPLATE_ARGS), self.PYTHON_CALLBACK_IMPL_NAME, py_callback)) wrapper.before_call.unindent() wrapper.before_call.write_code("}") # closes: if (py_callback) { wrapper.call_params.append(value) def convert_c_to_python(self, wrapper): raise typehandlers.NotSupportedError("Reverse wrappers for ns3::Callback<...> types " "(python using callbacks defined in C++) not implemented.")
def generate_callback_classes(out, callbacks): for callback_impl_num, template_parameters in enumerate(callbacks): sink = MemoryCodeSink() cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters) #print >> sys.stderr, "***** trying to register callback: %r" % cls_name class_name = "PythonCallbackImpl%i" % callback_impl_num sink.writeln(''' class %s : public ns3::CallbackImpl<%s> { public: PyObject *m_callback; %s(PyObject *callback) { Py_INCREF(callback); m_callback = callback; } virtual ~%s() { PyGILState_STATE __py_gil_state; __py_gil_state = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0); Py_DECREF(m_callback); m_callback = NULL; PyGILState_Release(__py_gil_state); } virtual bool IsEqual(ns3::Ptr<const ns3::CallbackImplBase> other_base) const { const %s *other = dynamic_cast<const %s*> (ns3::PeekPointer (other_base)); if (other != NULL) return (other->m_callback == m_callback); else return false; } ''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name)) sink.indent() callback_return = template_parameters[0] return_ctype = ctypeparser.parse_type(callback_return) if ('const' in return_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: return_type = ReturnValue.new(str(return_ctype), **kwargs) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError) as ex: warnings.warn( "***** Unable to register callback; Return value '%s' error (used in %s): %r" % (callback_return, cls_name, ex), Warning) continue arguments = [] ok = True callback_parameters = [ arg for arg in template_parameters[1:] if arg != 'ns3::empty' ] for arg_num, arg_type in enumerate(callback_parameters): arg_name = 'arg%i' % (arg_num + 1) param_ctype = ctypeparser.parse_type(arg_type) if ('const' in param_ctype.remove_modifiers()): kwargs = {'is_const': True} else: kwargs = {} try: arguments.append( Parameter.new(str(param_ctype), arg_name, **kwargs)) except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError) as ex: warnings.warn( "***** Unable to register callback; parameter '%s %s' error (used in %s): %r" % (arg_type, arg_name, cls_name, ex), Warning) ok = False if not ok: continue wrapper = CallbackImplProxyMethod(return_type, arguments) wrapper.generate(sink, 'operator()', decl_modifiers=[]) sink.unindent() sink.writeln('};\n') sink.flush_to(out) class PythonCallbackParameter(Parameter): "Class handlers" CTYPES = [cls_name] print("***** registering callback handler: %r" % ctypeparser.normalize_type_string(cls_name), file=sys.stderr) DIRECTIONS = [Parameter.DIRECTION_IN] PYTHON_CALLBACK_IMPL_NAME = class_name TEMPLATE_ARGS = template_parameters def convert_python_to_c(self, wrapper): "parses python args to get C++ value" assert isinstance(wrapper, typehandlers.ForwardWrapperBase) if self.default_value is None: py_callback = wrapper.declarations.declare_variable( 'PyObject*', self.name) wrapper.parse_params.add_parameter('O', ['&' + py_callback], self.name) wrapper.before_call.write_error_check( '!PyCallable_Check(%s)' % py_callback, 'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");' % self.name) callback_impl = wrapper.declarations.declare_variable( 'ns3::Ptr<%s>' % self.PYTHON_CALLBACK_IMPL_NAME, '%s_cb_impl' % self.name) wrapper.before_call.write_code( "%s = ns3::Create<%s> (%s);" % (callback_impl, self.PYTHON_CALLBACK_IMPL_NAME, py_callback)) wrapper.call_params.append( 'ns3::Callback<%s> (%s)' % (', '.join(self.TEMPLATE_ARGS), callback_impl)) else: py_callback = wrapper.declarations.declare_variable( 'PyObject*', self.name, 'NULL') wrapper.parse_params.add_parameter('O', ['&' + py_callback], self.name, optional=True) value = wrapper.declarations.declare_variable( 'ns3::Callback<%s>' % ', '.join(self.TEMPLATE_ARGS), self.name + '_value', self.default_value) wrapper.before_call.write_code("if (%s) {" % (py_callback, )) wrapper.before_call.indent() wrapper.before_call.write_error_check( '!PyCallable_Check(%s)' % py_callback, 'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");' % self.name) wrapper.before_call.write_code( "%s = ns3::Callback<%s> (ns3::Create<%s> (%s));" % (value, ', '.join(self.TEMPLATE_ARGS), self.PYTHON_CALLBACK_IMPL_NAME, py_callback)) wrapper.before_call.unindent() wrapper.before_call.write_code( "}") # closes: if (py_callback) { wrapper.call_params.append(value) def convert_c_to_python(self, wrapper): raise typehandlers.NotSupportedError( "Reverse wrappers for ns3::Callback<...> types " "(python using callbacks defined in C++) not implemented.")