#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.
* @{
*/
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)
{
{
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
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);
}