kuuko pushed a commit to branch master. http://git.enlightenment.org/bindings/python/python-efl.git/commit/?id=247eb9e452c2490ff1312e6ba2af63937f11a4c6
commit 247eb9e452c2490ff1312e6ba2af63937f11a4c6 Author: Kai Huuhko <kai.huu...@gmail.com> Date: Wed Mar 11 22:13:00 2015 +0200 Evas.SmartObject: Revert SmartCb add/del mechanism partially We need to keep a better track of the spec references so they don't get mixed up when user adds and deletes the callbacks. --- efl/evas/efl.evas_object_smart.pxi | 37 ++++++++++++++++++++++++++----------- include/efl.evas.pxd | 3 ++- tests/elementary/test_01_basics.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/efl/evas/efl.evas_object_smart.pxi b/efl/evas/efl.evas_object_smart.pxi index cc9ee11..f22b4f1 100644 --- a/efl/evas/efl.evas_object_smart.pxi +++ b/efl/evas/efl.evas_object_smart.pxi @@ -598,7 +598,7 @@ cdef class SmartObject(Object): parameter ``smart`` """ def __cinit__(self): - self._owned_references = list() + self._smart_callback_specs = dict() def __init__(self, Canvas canvas not None, Smart smart not None, **kwargs): #_smart_classes.append(<uintptr_t>cls_def) @@ -756,8 +756,8 @@ cdef class SmartObject(Object): if isinstance(event, unicode): event = PyUnicode_AsUTF8String(event) spec = (<uintptr_t><void *>event_conv, func, args, kargs) - self._owned_references.append(spec) - #Py_INCREF(spec) + lst = self._smart_callback_specs.setdefault(event, []) + lst.append(spec) evas_object_smart_callback_add(self.obj, <const char *>event if event is not None else NULL, @@ -784,21 +784,36 @@ cdef class SmartObject(Object): """ cdef: - void *tmp tuple spec + int found = 0 + int i + void *tmp if isinstance(event, unicode): event = PyUnicode_AsUTF8String(event) - tmp = evas_object_smart_callback_del(self.obj, + lst = self._smart_callback_specs.get(event, None) + + if lst is None: + raise ValueError("No callbacks registered for the given event type") + + for i, spec in enumerate(lst): + if spec[1] is func: + found = 1 + break + + if found == 0: + raise ValueError("func not registered") + + tmp = evas_object_smart_callback_del_full(self.obj, <const char *>event if event is not None else NULL, - _smart_callback) + _smart_callback, + <void *>spec + ) if tmp == NULL: - return 1 - else: - spec = <tuple>tmp - self._owned_references.remove(spec) - #Py_DECREF(spec) + raise RuntimeError("Something went wrong while unregistering!") + + lst.pop(i) return 1 diff --git a/include/efl.evas.pxd b/include/efl.evas.pxd index 2f1c94f..f9326b8 100644 --- a/include/efl.evas.pxd +++ b/include/efl.evas.pxd @@ -800,6 +800,7 @@ cdef extern from "Evas.h": void evas_object_smart_data_set(Evas_Object *obj, void *data) void evas_object_smart_callback_add(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) void *evas_object_smart_callback_del(Evas_Object *obj, const char *event, Evas_Smart_Cb func) + void *evas_object_smart_callback_del_full(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) void evas_object_smart_callback_call(Evas_Object *obj, const char *event, void *event_info) void evas_object_smart_changed(Evas_Object *obj) void evas_object_smart_need_recalculate_set(Evas_Object *obj, int value) @@ -1211,7 +1212,7 @@ cdef class Textblock(Object): cdef class SmartObject(Object): cdef: - list _owned_references + dict _smart_callback_specs int _set_obj(self, cEo *obj) except 0 int _callback_add_full(self, event, object(*)(void*), func, tuple args, dict kargs) except 0 int _callback_del_full(self, event, object(*)(void*), func) except 0 diff --git a/tests/elementary/test_01_basics.py b/tests/elementary/test_01_basics.py index e75e08b..a24c4fe 100644 --- a/tests/elementary/test_01_basics.py +++ b/tests/elementary/test_01_basics.py @@ -9,6 +9,13 @@ from efl.elementary.button import Button elementary.init() +def cb1(*args): + pass + +def cb2(*args): + pass + + class TestElmBasics(unittest.TestCase): def setUp(self): @@ -22,6 +29,29 @@ class TestElmBasics(unittest.TestCase): self.assertEqual(Eo.parent_get(o), self.o) o.delete() + def testCallbacks1(self): + self.o.callback_iconified_add(cb1) + self.o.callback_iconified_del(cb1) + + def testCallbacks2(self): + self.o.callback_iconified_add(cb1) + self.o.callback_iconified_add(cb2) + self.o.callback_iconified_del(cb1) + self.o.callback_iconified_del(cb2) + + def testCallbacks3(self): + self.o.callback_iconified_add(cb1) + self.o.callback_fullscreen_add(cb1) + self.o.callback_iconified_del(cb1) + self.o.callback_fullscreen_del(cb1) + + def testCallbacks4(self): + self.o.callback_iconified_add(cb1) + self.o.callback_fullscreen_add(cb2) + self.assertRaises(ValueError, self.o.callback_iconified_del, cb2) + self.assertRaises(ValueError, self.o.callback_fullscreen_del, cb1) + + if __name__ == '__main__': unittest.main(verbosity=2) elementary.shutdown() --