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()

-- 


Reply via email to