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)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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.")
Exemplo n.º 6
0
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.")