Eobj: Added weak ref.
authortasn <tasn>
Tue, 17 Apr 2012 13:38:41 +0000 (13:38 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 17 Apr 2012 13:38:41 +0000 (13:38 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@70269 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

lib/Eobj.h
lib/eobj.c
tests/eobj_test_general.c

index f418693..635829d 100644 (file)
@@ -432,6 +432,56 @@ EAPI extern const Eobj_Event_Description _EOBJ_EV_DEL;
 #define EOBJ_EV_DEL (&(_EOBJ_EV_DEL))
 
 /**
+ * @addtogroup Eobj_Weak_Ref Weak reference for Eobj objects.
+ * @{
+ */
+
+/**
+ * @struct _Eobj_Weak_Ref
+ * This is exposed for performance, please use eobj_weak_ref_get() when you
+ * actually want to get the refed object.
+ */
+struct _Eobj_Weak_Ref
+{
+   Eobj *obj; /**< The object being referenced. */
+};
+
+/**
+ * @typedef Eobj_Weak_Ref
+ * Weak reference type for Eobj.
+ */
+typedef struct _Eobj_Weak_Ref Eobj_Weak_Ref;
+
+/**
+ * @brief Create a new weak reference to obj.
+ * @param obj The object being referenced.
+ * @return A new weak reference.
+ */
+EAPI Eobj_Weak_Ref *eobj_weak_ref_new(const Eobj *obj);
+
+/**
+ * @brief Free the weak reference passed.
+ * @param wref the weak reference to free.
+ */
+EAPI void eobj_weak_ref_free(Eobj_Weak_Ref *wref);
+
+/**
+ * @brief Get the referenced object from the weak reference.
+ * @param wref the weak reference to get the object from.
+ * @return The object referenced by wref.
+ */
+static inline Eobj *
+eobj_weak_ref_get(const Eobj_Weak_Ref *wref)
+{
+   return wref->obj;
+}
+
+/**
+ * @}
+ */
+
+
+/**
  * @addtogroup Eobj_Composite_Objects Composite Objects.
  * @{
  */
index e449976..e449575 100644 (file)
@@ -829,6 +829,40 @@ eobj_ref_get(const Eobj *obj)
    return obj->refcount;
 }
 
+/* Weak reference. */
+Eina_Bool
+_eobj_weak_ref_cb(void *data, Eobj *obj __UNUSED__, const Eobj_Event_Description *desc __UNUSED__, void *event_info __UNUSED__)
+{
+   Eobj_Weak_Ref *wref = data;
+   wref->obj = NULL;
+
+   return EINA_TRUE;
+}
+
+EAPI Eobj_Weak_Ref *
+eobj_weak_ref_new(const Eobj *_obj)
+{
+   Eobj *obj = (Eobj *) _obj;
+   Eobj_Weak_Ref *wref = calloc(1, sizeof(*wref));
+   wref->obj = obj;
+   eobj_event_callback_add(obj, EOBJ_EV_DEL, _eobj_weak_ref_cb, wref);
+
+   return wref;
+}
+
+EAPI void
+eobj_weak_ref_free(Eobj_Weak_Ref *wref)
+{
+   if (wref->obj)
+     {
+        eobj_event_callback_del_full(wref->obj, EOBJ_EV_DEL, _eobj_weak_ref_cb,
+              wref);
+     }
+   free(wref);
+}
+
+/* EOF Weak reference. */
+
 EAPI void
 eobj_del(Eobj *obj)
 {
index d92dde9..390cefd 100644 (file)
@@ -13,8 +13,40 @@ START_TEST(eobj_simple)
 {
    eobj_init();
    Eobj *obj = eobj_add(EOBJ_CLASS_BASE, NULL);
-
    fail_if(obj);
+
+   eobj_shutdown();
+}
+END_TEST
+
+START_TEST(eobj_weak_reference)
+{
+   eobj_init();
+
+   Eobj *obj = eobj_add(SIMPLE_CLASS, NULL);
+   Eobj_Weak_Ref *wref = eobj_weak_ref_new(obj);
+   fail_if(!eobj_weak_ref_get(wref));
+
+   eobj_unref(obj);
+   fail_if(eobj_weak_ref_get(wref));
+
+   eobj_weak_ref_free(wref);
+
+   obj = eobj_add(SIMPLE_CLASS, NULL);
+   wref = eobj_weak_ref_new(obj);
+
+   eobj_ref(obj);
+   fail_if(!eobj_weak_ref_get(wref));
+
+   eobj_del(obj);
+   fail_if(eobj_weak_ref_get(wref));
+
+   eobj_unref(obj);
+   fail_if(eobj_weak_ref_get(wref));
+
+   eobj_weak_ref_free(wref);
+
+
    eobj_shutdown();
 }
 END_TEST
@@ -91,4 +123,5 @@ void eobj_test_general(TCase *tc)
    tcase_add_test(tc, eobj_generic_data);
    tcase_add_test(tc, eobj_op_errors);
    tcase_add_test(tc, eobj_simple);
+   tcase_add_test(tc, eobj_weak_reference);
 }