Eo: Make wref a c array instead of using event callbacks.
authortasn <tasn>
Tue, 1 May 2012 12:38:14 +0000 (12:38 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 1 May 2012 12:38:14 +0000 (12:38 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@70578 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

lib/eo_base_class.c
tests/eo_test_general.c

index 9161cdb..26435c4 100644 (file)
@@ -10,6 +10,7 @@ EAPI Eo_Op EO_BASE_BASE_ID = EO_NOOP;
 typedef struct
 {
    Eina_Inlist *generic_data;
+   Eo ***wrefs;
 } Private_Data;
 
 typedef struct
@@ -115,29 +116,43 @@ _data_del(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
 }
 
 /* Weak reference. */
-static Eina_Bool
-_eo_weak_ref_cb(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
+
+static inline size_t
+_wref_count(Private_Data *pd)
 {
-   Eo **wref = data;
-   *wref = NULL;
+   size_t count = 0;
+   if (!pd->wrefs)
+      return 0;
 
-   return EO_CALLBACK_CONTINUE;
+   Eo ***itr;
+   for (itr = pd->wrefs ; *itr ; itr++)
+      count++;
+
+   return count;
 }
 
 static void
-_wref_add(const Eo *obj, const void *class_data EINA_UNUSED, va_list *list)
+_wref_add(const Eo *obj, const void *class_data, va_list *list)
 {
+   Private_Data *pd = (Private_Data *) class_data;
+   size_t count;
    Eo **wref = va_arg(*list, Eo **);
 
+   count = _wref_count(pd);
+   count += 1; /* New wref. */
+
+   pd->wrefs= realloc(pd->wrefs, sizeof(*pd->wrefs) * (count + 1));
+
+   pd->wrefs[count - 1] = wref;
+   pd->wrefs[count] = NULL;
    *wref = (Eo *) obj;
-   /* FIXME: The cast and the one in the next func are both bad and should be
-    * fixed once the event callback functions are fixed. */
-   eo_event_callback_add((Eo *) obj, EO_EV_DEL, _eo_weak_ref_cb, wref);
 }
 
 static void
-_wref_del(const Eo *obj, const void *class_data EINA_UNUSED, va_list *list)
+_wref_del(const Eo *obj, const void *class_data, va_list *list)
 {
+   Private_Data *pd = (Private_Data *) class_data;
+   size_t count;
    Eo **wref = va_arg(*list, Eo **);
    if (*wref != obj)
      {
@@ -145,10 +160,56 @@ _wref_del(const Eo *obj, const void *class_data EINA_UNUSED, va_list *list)
               *wref, obj);
         return;
      }
-   eo_event_callback_del((Eo *) obj, EO_EV_DEL, _eo_weak_ref_cb, wref);
+
+   if (!pd->wrefs)
+     {
+        ERR("There are no weak refs for object %p", obj);
+        return;
+     }
+
+   /* Move the last item in the array instead of the current wref. */
+   count = _wref_count(pd);
+
+   if (count > 1)
+     {
+        Eo ***itr;
+        for (itr = pd->wrefs ; *itr ; itr++)
+          {
+             if (*itr == wref)
+               {
+                  *itr = pd->wrefs[count - 1];
+                  break;
+               }
+          }
+
+        // No count--; because of the NULL that is not included in the count. */
+        pd->wrefs = realloc(pd->wrefs, sizeof(*pd->wrefs) * count);
+        pd->wrefs[count] = NULL;
+     }
+   else
+     {
+        free(pd->wrefs);
+        pd->wrefs = NULL;
+     }
+
    *wref = NULL;
 }
 
+static inline void
+_wref_destruct(Private_Data *pd)
+{
+   Eo ***itr;
+   if (!pd->wrefs)
+      return;
+
+   for (itr = pd->wrefs ; *itr ; itr++)
+     {
+        **itr = NULL;
+     }
+
+   free(pd->wrefs);
+}
+
 /* EOF Weak reference. */
 
 
@@ -177,6 +238,7 @@ _destructor(Eo *obj, void *class_data)
    DBG("%p - %s.", obj, eo_class_name_get(MY_CLASS));
 
    _eo_generic_data_del_all(class_data);
+   _wref_destruct(class_data);
 }
 
 static void
index 424b764..c222170 100644 (file)
@@ -101,6 +101,10 @@ START_TEST(eo_weak_reference)
    eo_wref_del_safe(&wref);
    fail_if(wref);
 
+   wref = obj;
+   eo_do(obj, eo_wref_del(&wref));
+   fail_if(wref != obj);
+
    eo_unref(obj);
    eo_unref(obj2);