From 13ca8e0e4c9e25efcb09b2715cff4df8b3303dc1 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 28 Aug 2014 09:41:30 +0200 Subject: [PATCH] Add a user_data properties to the objects of the Python wrapper. --- .../handwritten_definitions.mustache | 9 +++-- tools/python/apixml2python/linphone.py | 38 +++++++++++++++++-- .../apixml2python/linphone_module.mustache | 14 ++++++- tools/python/unittests/linphonetester.py | 9 ++--- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index ae5bd2b76..2c1c308b0 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -182,7 +182,7 @@ static PyObject * pylinphone_Core_class_method_new(PyObject *cls, PyObject *args return NULL; } - self = (pylinphone_CoreObject *)PyObject_New(pylinphone_CoreObject, &pylinphone_CoreType); + self = (pylinphone_CoreObject *)PyObject_CallObject((PyObject *) &pylinphone_CoreType, NULL); if (self == NULL) { return NULL; } @@ -224,10 +224,11 @@ static PyObject * pylinphone_Core_class_method_new_with_config(PyObject *cls, Py return NULL; } - self = (pylinphone_CoreObject *)PyObject_New(pylinphone_CoreObject, &pylinphone_CoreType); + self = (pylinphone_CoreObject *)PyObject_CallObject((PyObject *) &pylinphone_CoreType, NULL); if (self == NULL) { return NULL; } + PyObject_Init((PyObject *)self, &pylinphone_CoreType); Py_INCREF(_vtable_dict); self->vtable_dict = _vtable_dict; {{#events}} @@ -321,7 +322,7 @@ static PyObject * pylinphone_VideoSize_new(PyTypeObject *type, PyObject *args, P return (PyObject *)self; } -static int pylinphone_VideoSize_init(PyObject *self, PyObject *args, PyObject *kwds) { +static int pylinphone_VideoSize_init(PyObject *self, PyObject *args, PyObject *kw) { pylinphone_VideoSizeObject *vso = (pylinphone_VideoSizeObject *)self; int width; int height; @@ -336,7 +337,7 @@ static int pylinphone_VideoSize_init(PyObject *self, PyObject *args, PyObject *k static PyMemberDef pylinphone_VideoSize_members[] = { { "width", T_INT, offsetof(pylinphone_VideoSizeObject, vs) + offsetof(MSVideoSize, width), 0, "[int] The width of the video" }, { "height", T_INT, offsetof(pylinphone_VideoSizeObject, vs) + offsetof(MSVideoSize, height), 0, "[int] The height of the video" }, - { NULL } /* Sentinel */ + { NULL, 0, 0, 0, NULL } /* Sentinel */ }; static PyTypeObject pylinphone_VideoSizeType = { diff --git a/tools/python/apixml2python/linphone.py b/tools/python/apixml2python/linphone.py index b3ae811fc..c5faec23b 100644 --- a/tools/python/apixml2python/linphone.py +++ b/tools/python/apixml2python/linphone.py @@ -485,7 +485,7 @@ class NewMethodDefinition(MethodDefinition): return "\tpylinphone_trace(1, \"[PYLINPHONE] >>> %s()\", __FUNCTION__);\n" def format_c_function_call(self): - return "\tself->native_ptr = NULL;\n" + return '' def format_return_trace(self): return "\tpylinphone_trace(-1, \"[PYLINPHONE] <<< %s -> %p\", __FUNCTION__, self);\n" @@ -493,6 +493,31 @@ class NewMethodDefinition(MethodDefinition): def format_return_result(self): return "\treturn (PyObject *)self;" +class InitMethodDefinition(MethodDefinition): + def __init__(self, linphone_module, class_, method_node = None): + MethodDefinition.__init__(self, linphone_module, class_, method_node) + + def format_local_variables_definition(self): + return \ +""" pylinphone_{class_name}Object *self_obj = (pylinphone_{class_name}Object *)self; + self_obj->user_data = Py_None; +""".format(class_name=self.class_['class_name']) + + def format_arguments_parsing(self): + return '' + + def format_enter_trace(self): + return "\tpylinphone_trace(1, \"[PYLINPHONE] >>> %s()\", __FUNCTION__);\n" + + def format_c_function_call(self): + return "\tself_obj->native_ptr = NULL;\n" + + def format_return_trace(self): + return "\tpylinphone_trace(-1, \"[PYLINPHONE] <<< %s -> %p\", __FUNCTION__, self);\n" + + def format_return_result(self): + return "\treturn 0;" + class NewFromNativePointerMethodDefinition(MethodDefinition): def __init__(self, linphone_module, class_): MethodDefinition.__init__(self, linphone_module, class_, None) @@ -515,11 +540,12 @@ class NewFromNativePointerMethodDefinition(MethodDefinition): {none_trace} Py_RETURN_NONE; }} - self = (pylinphone_{class_name}Object *)PyObject_New(pylinphone_{class_name}Object, type); + self = (pylinphone_{class_name}Object *)PyObject_CallObject((PyObject *)&pylinphone_{class_name}Type, NULL); if (self == NULL) {{ {none_trace} Py_RETURN_NONE; }} + PyObject_Init((PyObject *)self, type); self->native_ptr = ({class_cname} *)native_ptr; {set_user_data_func_call} """.format(class_name=self.class_['class_name'], class_cname=self.class_['class_cname'], @@ -573,8 +599,9 @@ class DeallocMethodDefinition(MethodDefinition): """ {reset_user_data_code} {native_ptr_dealloc_code} pylinphone_dispatch_messages(); + Py_DECREF(((pylinphone_{class_name}Object *)self)->user_data); self->ob_type->tp_free(self); -""".format(reset_user_data_code=reset_user_data_code, native_ptr_dealloc_code=native_ptr_dealloc_code) +""".format(class_name=self.class_['class_name'], reset_user_data_code=reset_user_data_code, native_ptr_dealloc_code=native_ptr_dealloc_code) def format_return_trace(self): return "\tpylinphone_trace(-1, \"[PYLINPHONE] <<< %s\", __FUNCTION__);" @@ -937,6 +964,11 @@ class LinphoneModule(object): except Exception, e: e.args += (c['class_name'], 'new_body') raise + try: + c['init_body'] = InitMethodDefinition(self, c, xml_new_method).format() + except Exception, e: + e.args += (c['class_name'], 'init_body') + raise try: c['new_from_native_pointer_body'] = NewFromNativePointerMethodDefinition(self, c).format() except Exception, e: diff --git a/tools/python/apixml2python/linphone_module.mustache b/tools/python/apixml2python/linphone_module.mustache index dcd0a7c3a..5a8f83b00 100644 --- a/tools/python/apixml2python/linphone_module.mustache +++ b/tools/python/apixml2python/linphone_module.mustache @@ -53,6 +53,7 @@ static PyTypeObject pylinphone_{{class_name}}Type; typedef struct { PyObject_HEAD + PyObject *user_data; {{class_cname}} *native_ptr; {{{class_object_members}}} } pylinphone_{{class_name}}Object; @@ -114,6 +115,10 @@ static PyObject * pylinphone_{{class_name}}_new(PyTypeObject *type, PyObject *ar {{{new_body}}} } +static int pylinphone_{{class_name}}_init(PyObject *self, PyObject *args, PyObject *kw) { +{{{init_body}}} +} + static void pylinphone_{{class_name}}_dealloc(PyObject *self) { {{{dealloc_body}}} } @@ -153,6 +158,11 @@ static PyMethodDef pylinphone_{{class_name}}_methods[] = { { NULL, NULL, 0, NULL } }; +static PyMemberDef pylinphone_{{class_name}}_members[] = { + { "user_data", T_OBJECT, offsetof(pylinphone_{{class_name}}Object, user_data), 0, "A place to store some user data." }, + { NULL, 0, 0, 0, NULL } /* Sentinel */ +}; + {{#class_properties}} {{{getter_definition_begin}}} @@ -206,14 +216,14 @@ static PyTypeObject pylinphone_{{class_name}}Type = { 0, /* tp_iter */ 0, /* tp_iternext */ pylinphone_{{class_name}}_methods, /* tp_methods */ - 0, /* tp_members */ + pylinphone_{{class_name}}_members, /* tp_members */ pylinphone_{{class_name}}_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - 0, /* tp_init */ + pylinphone_{{class_name}}_init, /* tp_init */ 0, /* tp_alloc */ pylinphone_{{class_name}}_new, /* tp_new */ 0, /* tp_free */ diff --git a/tools/python/unittests/linphonetester.py b/tools/python/unittests/linphonetester.py index 7dd003b98..9a32432bc 100644 --- a/tools/python/unittests/linphonetester.py +++ b/tools/python/unittests/linphonetester.py @@ -149,13 +149,11 @@ class CoreManagerStats: class CoreManager: - core_map = {} - @classmethod def registration_state_changed(cls, lc, cfg, state, message): logging.info("New registration state {state} for user id [{identity}] at proxy [{addr}]".format( state=linphone.RegistrationState.string(state), identity=cfg.identity, addr=cfg.server_addr)) - manager = CoreManager.core_map[lc] + manager = lc.user_data if state == linphone.RegistrationState.RegistrationNone: manager.stats.number_of_LinphoneRegistrationNone += 1 elif state == linphone.RegistrationState.RegistrationProgress: @@ -173,7 +171,7 @@ class CoreManager: def auth_info_requested(cls, lc, realm, username, domain): logging.info("Auth info requested for user id [{username}] at realm [{realm}]".format( username=username, realm=realm)) - manager = CoreManager.core_map[lc] + manager = lc.user_data manager.stats.number_of_auth_info_requested +=1 def __init__(self, rc_file = None, check_for_proxies = True, vtable = {}): @@ -220,7 +218,7 @@ class CoreManager: if rc_file is not None: rc_path = os.path.join('rcfiles', rc_file) self.lc = self.configure_lc_from(vtable, tester_resources_path, rc_path) - CoreManager.core_map[self.lc] = self + self.lc.user_data = self if check_for_proxies and rc_file is not None: proxy_count = len(self.lc.proxy_config_list) else: @@ -236,7 +234,6 @@ class CoreManager: # self.identity.clean() def stop(self): - del CoreManager.core_map[self.lc] self.lc = None def __del__(self):