From b4ca4c9be7433e9368bf64be9ad641a6c14bd35d Mon Sep 17 00:00:00 2001 From: tasn Date: Tue, 17 Apr 2012 13:38:41 +0000 Subject: [PATCH] Eobj: Added weak ref. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@70269 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- lib/Eobj.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++ lib/eobj.c | 34 ++++++++++++++++++++++++++++++++ tests/eobj_test_general.c | 35 ++++++++++++++++++++++++++++++++- 3 files changed, 118 insertions(+), 1 deletion(-) diff --git a/lib/Eobj.h b/lib/Eobj.h index f418693..635829d 100644 --- a/lib/Eobj.h +++ b/lib/Eobj.h @@ -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. * @{ */ diff --git a/lib/eobj.c b/lib/eobj.c index e449976..e449575 100644 --- a/lib/eobj.c +++ b/lib/eobj.c @@ -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) { diff --git a/tests/eobj_test_general.c b/tests/eobj_test_general.c index d92dde9..390cefd 100644 --- a/tests/eobj_test_general.c +++ b/tests/eobj_test_general.c @@ -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); } -- 2.7.4