From: tasn Date: Mon, 14 May 2012 07:35:19 +0000 (+0000) Subject: Eo: Move event callback handling to base class. X-Git-Tag: submit/2.0alpha-wayland/20121127.222020~129 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=123e15e90703b37b380818d7810a7a6c0c997214;p=profile%2Fivi%2Feobj.git Eo: Move event callback handling to base class. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@70990 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/examples/access/simple.c b/examples/access/simple.c index da74104..c43f529 100644 --- a/examples/access/simple.c +++ b/examples/access/simple.c @@ -27,7 +27,7 @@ _a_set(Eo *obj, void *class_data, va_list *list) pd->protected.protected_x1 = a + 1; pd->protected.public.public_x2 = a + 2; - eo_event_callback_call(obj, EV_A_CHANGED, &pd->a); + eo_do(obj, eo_event_callback_call(EV_A_CHANGED, &pd->a, NULL)); } static void diff --git a/examples/composite_objects/comp.c b/examples/composite_objects/comp.c index 45a767a..f8ed9f2 100644 --- a/examples/composite_objects/comp.c +++ b/examples/composite_objects/comp.c @@ -25,7 +25,7 @@ _constructor(Eo *obj, void *class_data EINA_UNUSED) Eo *simple = eo_add(SIMPLE_CLASS, obj); eo_composite_object_attach(obj, simple); - eo_event_callback_forwarder_add(simple, EV_A_CHANGED, obj); + eo_do(simple, eo_event_callback_forwarder_add(EV_A_CHANGED, obj)); fail_if(eo_composite_is(obj)); fail_if(!eo_composite_is(simple)); diff --git a/examples/composite_objects/main.c b/examples/composite_objects/main.c index 12620df..2be1b13 100644 --- a/examples/composite_objects/main.c +++ b/examples/composite_objects/main.c @@ -27,7 +27,7 @@ main(int argc, char *argv[]) eo_init(); Eo *obj = eo_add(COMP_CLASS, NULL); - eo_event_callback_add(obj, EV_A_CHANGED, _a_changed_cb, NULL); + eo_do(obj, eo_event_callback_add(EV_A_CHANGED, _a_changed_cb, NULL)); int a; eo_do(obj, simple_a_set(1)); @@ -40,7 +40,7 @@ main(int argc, char *argv[]) Eo *simple; eo_do(obj, eo_base_data_get("simple-obj", (void **) &simple)); eo_ref(simple); - eo_event_callback_forwarder_del(simple, EV_A_CHANGED, obj); + eo_do(simple, eo_event_callback_forwarder_del(EV_A_CHANGED, obj)); cb_called = EINA_FALSE; eo_do(obj, simple_a_set(2)); diff --git a/examples/composite_objects/simple.c b/examples/composite_objects/simple.c index e76d1db..ee9e6e3 100644 --- a/examples/composite_objects/simple.c +++ b/examples/composite_objects/simple.c @@ -19,7 +19,7 @@ _a_set(Eo *obj, void *class_data, va_list *list) printf("%s %d\n", eo_class_name_get(MY_CLASS), a); pd->a = a; - eo_event_callback_call(obj, EV_A_CHANGED, &pd->a); + eo_do(obj, eo_event_callback_call(EV_A_CHANGED, &pd->a, NULL)); } static void diff --git a/examples/evas/elw_boxedbutton.c b/examples/evas/elw_boxedbutton.c index 58e2ce8..21c465a 100644 --- a/examples/evas/elw_boxedbutton.c +++ b/examples/evas/elw_boxedbutton.c @@ -22,7 +22,7 @@ _constructor(Eo *obj, void *class_data EINA_UNUSED) Eo *bt = eo_add(ELW_BUTTON_CLASS, obj); eo_composite_object_attach(obj, bt); - eo_event_callback_forwarder_add(bt, EV_CLICKED, obj); + eo_do(bt, eo_event_callback_forwarder_add(EV_CLICKED, obj)); eo_do(bt, evas_obj_visibility_set(EINA_TRUE)); eo_do(obj, elw_box_pack_end(bt)); diff --git a/examples/evas/elw_button.c b/examples/evas/elw_button.c index 270a3cd..47ff6d3 100644 --- a/examples/evas/elw_button.c +++ b/examples/evas/elw_button.c @@ -44,7 +44,7 @@ _btn_clicked(void *data, Evas_Object *evas_obj, void *event_info) (void) evas_obj; (void) event_info; Eo *obj = data; - eo_event_callback_call(obj, EV_CLICKED, NULL); + eo_do(obj, eo_event_callback_call(EV_CLICKED, NULL, NULL)); } static void diff --git a/examples/evas/test.c b/examples/evas/test.c index 3268400..c4dc88d 100644 --- a/examples/evas/test.c +++ b/examples/evas/test.c @@ -38,7 +38,7 @@ main(int argc, char *argv[]) evas_obj_color_set(255, 0, 0, 255), elw_button_text_set("Click"), evas_obj_visibility_set(EINA_TRUE)); - eo_event_callback_add(bt, EV_CLICKED, _btn_clicked_cb, "btn"); + eo_do(bt, eo_event_callback_add(EV_CLICKED, _btn_clicked_cb, "btn")); int r, g, b, a; eo_do(bt, evas_obj_color_get(&r, &g, &b, &a)); @@ -50,7 +50,7 @@ main(int argc, char *argv[]) evas_obj_color_set(0, 0, 255, 255), elw_button_text_set("Click2"), evas_obj_visibility_set(EINA_TRUE)); - eo_event_callback_add(bx, EV_CLICKED, _btn_clicked_cb, "bxedbtn"); + eo_do(bx, eo_event_callback_add(EV_CLICKED, _btn_clicked_cb, "bxedbtn")); elm_run(); diff --git a/examples/signals/main.c b/examples/signals/main.c index adbdd76..7ceb523 100644 --- a/examples/signals/main.c +++ b/examples/signals/main.c @@ -30,37 +30,41 @@ main(int argc, char *argv[]) Simple_Public_Data *pd = eo_data_get(obj, SIMPLE_CLASS); /* The order of these two is undetermined. */ - eo_event_callback_priority_add(obj, EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2); - eo_event_callback_priority_add(obj, EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1); + eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2)); + eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1)); /* This will be called afterwards. */ - eo_event_callback_priority_add(obj, EV_A_CHANGED, EO_CALLBACK_PRIORITY_DEFAULT, _a_changed_cb, (void *) 3); + eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_DEFAULT, _a_changed_cb, (void *) 3)); /* This will never be called because the previous callback returns NULL. */ - eo_event_callback_priority_add(obj, EV_A_CHANGED, EO_CALLBACK_PRIORITY_AFTER, _a_changed_cb, (void *) 4); + eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_AFTER, _a_changed_cb, (void *) 4)); eo_do(obj, simple_a_set(1)); fail_if(cb_count != 3); - eo_event_callback_del(obj, EV_A_CHANGED, _a_changed_cb, (void *) 3); + eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 3)); fail_if(pd->cb_count != 3); - fail_if(eo_event_callback_del(obj, EV_A_CHANGED, _a_changed_cb, (void *) 12)); + eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 12)); fail_if(pd->cb_count != 3); - fail_if(4 != (int) eo_event_callback_del(obj, EV_A_CHANGED, _a_changed_cb, (void *) 4)); + eo_do(obj, eo_event_callback_del(EV_A_CHANGED, _a_changed_cb, (void *) 4)); fail_if(pd->cb_count != 2); - eo_event_callback_del_lazy(obj, EV_A_CHANGED, _a_changed_cb); + void *ret; + + eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret)); fail_if(pd->cb_count != 1); - fail_if(eo_event_callback_del_lazy(obj, EV_A_CHANGED, NULL)); + eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, NULL, &ret)); + fail_if(ret); fail_if(pd->cb_count != 1); - fail_if(eo_event_callback_del(obj, EV_A_CHANGED, NULL, 0)); + eo_do(obj, eo_event_callback_del(EV_A_CHANGED, NULL, 0)); fail_if(pd->cb_count != 1); - eo_event_callback_del_lazy(obj, EV_A_CHANGED, _a_changed_cb); + eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret)); fail_if(pd->cb_count != 0); - fail_if(eo_event_callback_del_lazy(obj, EV_A_CHANGED, _a_changed_cb)); + eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret)); + fail_if(ret); fail_if(pd->cb_count != 0); eo_unref(obj); diff --git a/examples/signals/simple.c b/examples/signals/simple.c index 61d446a..dd52e48 100644 --- a/examples/signals/simple.c +++ b/examples/signals/simple.c @@ -25,7 +25,7 @@ _a_set(Eo *obj, void *class_data, va_list *list) pd->a = a; printf("%s %d\n", __func__, pd->a); - eo_event_callback_call(obj, EV_A_CHANGED, &pd->a); + eo_do(obj, eo_event_callback_call(EV_A_CHANGED, &pd->a, NULL)); } Eina_Bool @@ -67,8 +67,8 @@ _constructor(Eo *obj, void *class_data EINA_UNUSED) { eo_constructor_super(obj); - eo_event_callback_add(obj, EO_EV_CALLBACK_ADD, _cb_added, NULL); - eo_event_callback_add(obj, EO_EV_CALLBACK_DEL, _cb_deled, NULL); + eo_do(obj, eo_event_callback_add(EO_EV_CALLBACK_ADD, _cb_added, NULL)); + eo_do(obj, eo_event_callback_add(EO_EV_CALLBACK_DEL, _cb_deled, NULL)); eo_do(obj, eo_base_data_set("cb_count", (intptr_t) 0, NULL)); } diff --git a/lib/Eo.h b/lib/Eo.h index 320016f..b3fe7b0 100644 --- a/lib/Eo.h +++ b/lib/Eo.h @@ -555,7 +555,7 @@ EAPI void *eo_data_get(const Eo *obj, const Eo_Class *klass); * @see eo_unref() * @see eo_ref_get() */ -EAPI Eo *eo_ref(Eo *obj); +EAPI Eo *eo_ref(const Eo *obj); /** * @brief Decrement the object's reference count by 1 and free it if needed. @@ -564,7 +564,7 @@ EAPI Eo *eo_ref(Eo *obj); * @see eo_ref() * @see eo_ref_get() */ -EAPI void eo_unref(Eo *obj); +EAPI void eo_unref(const Eo *obj); /** * @brief Return the ref count of the object passed. @@ -660,156 +660,6 @@ EAPI Eina_Bool eo_composite_is(Eo *comp_obj); */ /** - * @addtogroup Eo_Events Eo's Event Handling - * @{ - */ - -/** - * @def EO_CALLBACK_PRIORITY_BEFORE - * Slightly more prioritized than default. - */ -#define EO_CALLBACK_PRIORITY_BEFORE -100 -/** - * @def EO_CALLBACK_PRIORITY_DEFAULT - * Default callback priority level - */ -#define EO_CALLBACK_PRIORITY_DEFAULT 0 -/** - * @def EO_CALLBACK_PRIORITY_AFTER - * Slightly less prioritized than default. - */ -#define EO_CALLBACK_PRIORITY_AFTER 100 - -/** - * @typedef Eo_Callback_Priority - * - * Callback priority value. Range is -32k - 32k. The lower the number, the - * higher the priority. - * - * @see EO_CALLBACK_PRIORITY_AFTER - * @see EO_CALLBACK_PRIORITY_BEFORE - * @see EO_CALLBACK_PRIORITY_DEFAULT - */ -typedef short Eo_Callback_Priority; - -/** - * @def EO_CALLBACK_STOP - * Stop calling callbacks for the even of which the callback was called for. - * @see EO_CALLBACK_CONTINUE - */ -#define EO_CALLBACK_STOP EINA_FALSE - -/** - * @def EO_CALLBACK_CONTINUE - * Continue calling callbacks for the even of which the callback was called for. - * @see EO_CALLBACK_STOP - */ -#define EO_CALLBACK_CONTINUE EINA_TRUE - -/** - * @typedef Eo_Event_Cb - * - * An event callback prototype. - * - * @param data The user data registered with the callback. - * @param obj The object which initiated the event. - * @param desc The event's description. - * @param event_info additional data passed with the event. - * @return #EO_CALLBACK_STOP to stop calling additional callbacks for the event, #EO_CALLBACK_CONTINUE to continue. - */ -typedef Eina_Bool (*Eo_Event_Cb)(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); - -/** - * @brief Add an event callback forwarder for an event and an object. - * @param obj The object to listen to events on. - * @param desc The description of the event to listen to. - * @param new_obj The object to emit events from. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * @see eo_event_callback_forwarder_del() - */ -EAPI Eina_Bool eo_event_callback_forwarder_add(Eo *obj, const Eo_Event_Description *desc, Eo *new_obj); - -/** - * @brief Remove an event callback forwarder for an event and an object. - * @param obj The object to listen to events on. - * @param desc The description of the event to listen to. - * @param new_obj The object to emit events from. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * @see eo_event_callback_forwarder_add() - */ -EAPI Eina_Bool eo_event_callback_forwarder_del(Eo *obj, const Eo_Event_Description *desc, Eo *new_obj); - -/** - * @def eo_event_callback_add(obj, desc, cb, data) - * Add a callback for an event. - * @param obj The object to listen to events on. - * @param desc The description of the event to listen to. - * @param cb the callback to call. - * @param data additional data to pass to the callback. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * callbacks of the same priority are called in reverse order of creation. - * - * @see eo_event_callback_priority_add() - */ -#define eo_event_callback_add(obj, desc, cb, data) \ - eo_event_callback_priority_add(obj, desc, \ - EO_CALLBACK_PRIORITY_DEFAULT, cb, data) - -/** - * @brief Add a callback for an event with a specific priority. - * @param obj The object to listen to events on. - * @param desc The description of the event to listen to. - * @param priority The priority of the callback. - * @param cb the callback to call. - * @param data additional data to pass to the callback. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * callbacks of the same priority are called in reverse order of creation. - * - * @see #eo_event_callback_add - */ -EAPI Eina_Bool eo_event_callback_priority_add(Eo *obj, const Eo_Event_Description *desc, Eo_Callback_Priority priority, Eo_Event_Cb cb, const void *data); - -/** - * @brief Del a callback for an event - * @param obj The object to listen to delete from. - * @param desc The description of the event to listen to. - * @param func the callback to delete. - * @return The additional data that was set to be passed to the callback. - * - * @see eo_event_callback_del() - */ -EAPI void *eo_event_callback_del_lazy(Eo *obj, const Eo_Event_Description *desc, Eo_Event_Cb func); - -/** - * @brief Del a callback with a specific data associated to it for an event. - * @param obj The object to listen to delete from. - * @param desc The description of the event to listen to. - * @param func the callback to delete. - * @param user_data The data to compare. - * @return The additional data that was set to be passed to the callback. - * - * @see eo_event_callback_del_lazy() - */ -EAPI void *eo_event_callback_del(Eo *obj, const Eo_Event_Description *desc, Eo_Event_Cb func, const void *user_data); - -/** - * @brief Call the callbacks for an event of an object. - * @param obj The object to work on. - * @param desc The description of the event to call. - * @param event_info Extra event info to pass to the callbacks. - * @return @c EINA_FALSE if one of the callbacks aborted the callback calls or @c EINA_TRUE otherwise. - */ -EAPI Eina_Bool eo_event_callback_call(Eo *obj, const Eo_Event_Description *desc, const void *event_info); - -/** - * @} - */ - -/** * @addtogroup Eo_Class_Base Eo's Base class. * @{ */ @@ -843,6 +693,12 @@ enum { EO_BASE_SUB_ID_DATA_DEL, EO_BASE_SUB_ID_WREF_ADD, EO_BASE_SUB_ID_WREF_DEL, + EO_BASE_SUB_ID_EVENT_CALLBACK_PRIORITY_ADD, + EO_BASE_SUB_ID_EVENT_CALLBACK_DEL, + EO_BASE_SUB_ID_EVENT_CALLBACK_DEL_LAZY, + EO_BASE_SUB_ID_EVENT_CALLBACK_CALL, + EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD, + EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL, EO_BASE_SUB_ID_LAST }; @@ -925,6 +781,145 @@ enum { } while (0) /** + * @addtogroup Eo_Events Eo's Event Handling + * @{ + */ + +/** + * @def EO_CALLBACK_PRIORITY_BEFORE + * Slightly more prioritized than default. + */ +#define EO_CALLBACK_PRIORITY_BEFORE -100 +/** + * @def EO_CALLBACK_PRIORITY_DEFAULT + * Default callback priority level + */ +#define EO_CALLBACK_PRIORITY_DEFAULT 0 +/** + * @def EO_CALLBACK_PRIORITY_AFTER + * Slightly less prioritized than default. + */ +#define EO_CALLBACK_PRIORITY_AFTER 100 + +/** + * @typedef Eo_Callback_Priority + * + * Callback priority value. Range is -32k - 32k. The lower the number, the + * higher the priority. + * + * @see EO_CALLBACK_PRIORITY_AFTER + * @see EO_CALLBACK_PRIORITY_BEFORE + * @see EO_CALLBACK_PRIORITY_DEFAULT + */ +typedef short Eo_Callback_Priority; + +/** + * @def EO_CALLBACK_STOP + * Stop calling callbacks for the even of which the callback was called for. + * @see EO_CALLBACK_CONTINUE + */ +#define EO_CALLBACK_STOP EINA_FALSE + +/** + * @def EO_CALLBACK_CONTINUE + * Continue calling callbacks for the even of which the callback was called for. + * @see EO_CALLBACK_STOP + */ +#define EO_CALLBACK_CONTINUE EINA_TRUE + +/** + * @typedef Eo_Event_Cb + * + * An event callback prototype. + * + * @param data The user data registered with the callback. + * @param obj The object which initiated the event. + * @param desc The event's description. + * @param event_info additional data passed with the event. + * @return #EO_CALLBACK_STOP to stop calling additional callbacks for the event, #EO_CALLBACK_CONTINUE to continue. + */ +typedef Eina_Bool (*Eo_Event_Cb)(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); + +/** + * @brief Add an event callback forwarder for an event and an object. + * @param desc[in] The description of the event to listen to. + * @param new_obj[in] The object to emit events from. + * + * @see eo_event_callback_forwarder_del() + */ +#define eo_event_callback_forwarder_add(desc, new_obj) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo *, new_obj) + +/** + * @brief Remove an event callback forwarder for an event and an object. + * @param desc[in] The description of the event to listen to. + * @param new_obj[in] The object to emit events from. + * + * @see eo_event_callback_forwarder_add() + */ +#define eo_event_callback_forwarder_del(desc, new_obj) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo *, new_obj) + +/** + * @def eo_event_callback_add(obj, desc, cb, data) + * Add a callback for an event. + * @param desc[in] The description of the event to listen to. + * @param cb[in] the callback to call. + * @param data[in] additional data to pass to the callback. + * + * callbacks of the same priority are called in reverse order of creation. + * + * @see eo_event_callback_priority_add() + */ +#define eo_event_callback_add(desc, cb, data) \ + eo_event_callback_priority_add(desc, \ + EO_CALLBACK_PRIORITY_DEFAULT, cb, data) + +/** + * @brief Add a callback for an event with a specific priority. + * @param desc[in] The description of the event to listen to. + * @param priority[in] The priority of the callback. + * @param cb[in] the callback to call. + * @param data[in] additional data to pass to the callback. + * + * callbacks of the same priority are called in reverse order of creation. + * + * @see #eo_event_callback_add + */ +#define eo_event_callback_priority_add(desc, priority, cb, data) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_PRIORITY_ADD), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo_Callback_Priority, priority), EO_TYPECHECK(Eo_Event_Cb, cb), EO_TYPECHECK(const void *, data) + + +/** + * @brief Del a callback for an event + * @param desc[in] The description of the event to listen to. + * @param func[in] the callback to delete. + * @param user_data[out] The user data associated with the callback func. + * + * @see eo_event_callback_del() + */ +#define eo_event_callback_del_lazy(desc, func, user_data) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_DEL_LAZY), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo_Event_Cb, func), EO_TYPECHECK(void **, user_data) + +/** + * @brief Del a callback with a specific data associated to it for an event. + * @param desc[in] The description of the event to listen to. + * @param func[in] the callback to delete. + * @param user_data[in] The data to compare. + * + * @see eo_event_callback_del_lazy() + */ +#define eo_event_callback_del(desc, func, user_data) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_DEL), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo_Event_Cb, func), EO_TYPECHECK(const void *, user_data) + +/** + * @brief Call the callbacks for an event of an object. + * @param desc[in] The description of the event to call. + * @param event_info[in] Extra event info to pass to the callbacks. + * @param aborted[out] @c EINA_TRUE if one of the callbacks aborted the call, @c EINA_FALSE otherwise. + */ +#define eo_event_callback_call(desc, event_info, aborted) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(const void *, event_info), EO_TYPECHECK(Eina_Bool *, aborted) + +/** + * @} + */ + +/** * @var _EO_EV_CALLBACK_ADD * see EO_EV_CALLBACK_ADD */ diff --git a/lib/eo.c b/lib/eo.c index a807049..d1ae8da 100644 --- a/lib/eo.c +++ b/lib/eo.c @@ -15,7 +15,6 @@ static Eo_Class **_eo_classes; static Eo_Class_Id _eo_classes_last_id; static Eina_Bool _eo_init_count = 0; -static void _eo_callback_remove_all(Eo *obj); static void _eo_constructor(Eo *obj, const Eo_Class *klass); static void _eo_destructor(Eo *obj, const Eo_Class *klass); static void eo_constructor_error_unset(Eo *obj); @@ -23,39 +22,12 @@ static inline void *_eo_data_get(const Eo *obj, const Eo_Class *klass); static inline Eo *_eo_ref(Eo *obj); static inline void _eo_unref(Eo *obj); -typedef struct _Eo_Callback_Description Eo_Callback_Description; - typedef struct { Eo_Op op; const Eo_Class **kls_itr; } Eo_Kls_Itr; -#define EO_EINA_MAGIC 0xa186bc32 /* Nothing magical about this number. */ -#define EO_EINA_MAGIC_STR "Eo" -#define EO_DELETED_EINA_MAGIC 0xa186bb32 /* Nothing magical about this number. */ -#define EO_DELETED_EINA_MAGIC_STR "Eo - Deleted object" -#define EO_CLASS_EINA_MAGIC 0xa186ba32 /* Nothing magical about this number. */ -#define EO_CLASS_EINA_MAGIC_STR "Eo Class" - -#define EO_MAGIC_RETURN_VAL(d, magic, ret) \ - do { \ - if (!EINA_MAGIC_CHECK(d, magic)) \ - { \ - EINA_MAGIC_FAIL(d, magic); \ - return ret; \ - } \ - } while (0) - -#define EO_MAGIC_RETURN(d, magic) \ - do { \ - if (!EINA_MAGIC_CHECK(d, magic)) \ - { \ - EINA_MAGIC_FAIL(d, magic); \ - return; \ - } \ - } while (0) - struct _Eo { EINA_MAGIC Eo *parent; @@ -67,9 +39,6 @@ struct _Eo { Eina_List *composite_objects; - Eina_Inlist *callbacks; - int walking_list; - Eo_Kls_Itr mro_itr; Eina_Bool del:1; @@ -1058,8 +1027,9 @@ _eo_ref(Eo *obj) } EAPI Eo * -eo_ref(Eo *obj) +eo_ref(const Eo *_obj) { + Eo *obj = (Eo *) _obj; EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, obj); return _eo_ref(obj); @@ -1073,7 +1043,7 @@ _eo_del_internal(Eo *obj) /* We need that for the event callbacks that may ref/unref. */ obj->refcount++; - eo_event_callback_call(obj, EO_EV_DEL, NULL); + eo_do(obj, eo_event_callback_call(EO_EV_DEL, NULL, NULL)); obj->del = EINA_TRUE; const Eo_Class *klass = eo_class_get(obj); @@ -1122,16 +1092,15 @@ _eo_unref(Eo *obj) } #endif - _eo_callback_remove_all(obj); - EINA_MAGIC_SET(obj, EO_DELETED_EINA_MAGIC); free(obj); } } EAPI void -eo_unref(Eo *obj) +eo_unref(const Eo *_obj) { + Eo *obj = (Eo *) _obj; EO_MAGIC_RETURN(obj, EO_EINA_MAGIC); _eo_unref(obj); @@ -1396,207 +1365,4 @@ eo_composite_is(Eo *emb_obj) return EINA_FALSE; } -/* Callbacks */ -struct _Eo_Callback_Description -{ - EINA_INLIST; - const Eo_Event_Description *event; - Eo_Event_Cb func; - void *func_data; - Eo_Callback_Priority priority; - Eina_Bool delete_me : 1; -}; - -/* Actually remove, doesn't care about walking list, or delete_me */ -static void -_eo_callback_remove(Eo *obj, Eo_Callback_Description *cb) -{ - obj->callbacks = eina_inlist_remove(obj->callbacks, - EINA_INLIST_GET(cb)); - free(cb); -} - -/* Actually remove, doesn't care about walking list, or delete_me */ -static void -_eo_callback_remove_all(Eo *obj) -{ - Eina_Inlist *initr; - Eo_Callback_Description *cb = NULL; - EINA_INLIST_FOREACH_SAFE(obj->callbacks, initr, cb) - { - _eo_callback_remove(obj, cb); - } -} - -static void -_eo_callbacks_clear(Eo *obj) -{ - Eina_Inlist *itn; - Eo_Callback_Description *cb = NULL; - - /* Abort if we are currently walking the list. */ - if (obj->walking_list > 0) - return; - - EINA_INLIST_FOREACH_SAFE(obj->callbacks, itn, cb) - { - if (cb->delete_me) - { - _eo_callback_remove(obj, cb); - } - } -} - -static int -_callback_priority_cmp(const void *_a, const void *_b) -{ - const Eo_Callback_Description *a, *b; - a = (const Eo_Callback_Description *) _a; - b = (const Eo_Callback_Description *) _b; - if (a->priority < b->priority) - return -1; - else - return 1; -} - -EAPI Eina_Bool -eo_event_callback_priority_add(Eo *obj, - const Eo_Event_Description *desc, - Eo_Callback_Priority priority, - Eo_Event_Cb func, - const void *data) -{ - EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE); - - Eo_Callback_Description *cb = calloc(1, sizeof(*cb)); - cb->event = desc; - cb->func = func; - cb->func_data = (void *) data; - cb->priority = priority; - obj->callbacks = eina_inlist_sorted_insert(obj->callbacks, - EINA_INLIST_GET(cb), _callback_priority_cmp); - - eo_event_callback_call(obj, EO_EV_CALLBACK_ADD, desc); - - return EINA_TRUE; -} - -EAPI void * -eo_event_callback_del_lazy(Eo *obj, const Eo_Event_Description *desc, Eo_Event_Cb func) -{ - EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, NULL); - - void *ret = NULL; - Eo_Callback_Description *cb; - EINA_INLIST_FOREACH(obj->callbacks, cb) - { - if ((cb->event == desc) && (cb->func == func)) - { - void *data; - - data = cb->func_data; - cb->delete_me = EINA_TRUE; - _eo_callbacks_clear(obj); - ret = data; - goto found; - } - } - - return NULL; - -found: - eo_event_callback_call(obj, EO_EV_CALLBACK_DEL, desc); - return ret; -} - -EAPI void * -eo_event_callback_del(Eo *obj, const Eo_Event_Description *desc, Eo_Event_Cb func, const void *user_data) -{ - EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, NULL); - - void *ret = NULL; - Eo_Callback_Description *cb; - EINA_INLIST_FOREACH(obj->callbacks, cb) - { - if ((cb->event == desc) && (cb->func == func) && - (cb->func_data == user_data)) - { - void *data; - - data = cb->func_data; - cb->delete_me = EINA_TRUE; - _eo_callbacks_clear(obj); - ret = data; - goto found; - } - } - - return NULL; - -found: - eo_event_callback_call(obj, EO_EV_CALLBACK_DEL, desc); - return ret; -} - -EAPI Eina_Bool -eo_event_callback_call(Eo *obj, const Eo_Event_Description *desc, - const void *event_info) -{ - EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE); - - Eina_Bool ret = EINA_TRUE; - Eo_Callback_Description *cb; - - _eo_ref(obj); - obj->walking_list++; - - EINA_INLIST_FOREACH(obj->callbacks, cb) - { - if (!cb->delete_me && (cb->event == desc)) - { - /* Abort callback calling if the func says so. */ - if (!cb->func((void *) cb->func_data, obj, desc, - (void *) event_info)) - { - ret = EINA_FALSE; - break; - } - } - if (obj->del) - break; - } - obj->walking_list--; - _eo_callbacks_clear(obj); - _eo_unref(obj); - - return ret; -} - -static Eina_Bool -_eo_event_forwarder_callback(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info) -{ - (void) obj; - Eo *new_obj = (Eo *) data; - return eo_event_callback_call(new_obj, desc, event_info); -} - -/* FIXME: Change default priority? Maybe call later? */ -EAPI Eina_Bool -eo_event_callback_forwarder_add(Eo *obj, const Eo_Event_Description *desc, Eo *new_obj) -{ - EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE); - EO_MAGIC_RETURN_VAL(new_obj, EO_EINA_MAGIC, EINA_FALSE); - - return eo_event_callback_add(obj, desc, _eo_event_forwarder_callback, new_obj); -} - -EAPI Eina_Bool -eo_event_callback_forwarder_del(Eo *obj, const Eo_Event_Description *desc, Eo *new_obj) -{ - EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE); - EO_MAGIC_RETURN_VAL(new_obj, EO_EINA_MAGIC, EINA_FALSE); - - eo_event_callback_del(obj, desc, _eo_event_forwarder_callback, new_obj); - return EINA_TRUE; -} diff --git a/lib/eo_base_class.c b/lib/eo_base_class.c index 8620754..c350430 100644 --- a/lib/eo_base_class.c +++ b/lib/eo_base_class.c @@ -11,6 +11,9 @@ typedef struct { Eina_Inlist *generic_data; Eo ***wrefs; + + Eina_Inlist *callbacks; + int walking_list; } Private_Data; typedef struct @@ -222,6 +225,209 @@ _wref_destruct(Private_Data *pd) /* EOF Weak reference. */ +/* Event callbacks */ + +/* Callbacks */ + +typedef struct +{ + EINA_INLIST; + const Eo_Event_Description *event; + Eo_Event_Cb func; + void *func_data; + Eo_Callback_Priority priority; + Eina_Bool delete_me : 1; +} Eo_Callback_Description; + +/* Actually remove, doesn't care about walking list, or delete_me */ +static void +_eo_callback_remove(Private_Data *pd, Eo_Callback_Description *cb) +{ + pd->callbacks = eina_inlist_remove(pd->callbacks, + EINA_INLIST_GET(cb)); + free(cb); +} + +/* Actually remove, doesn't care about walking list, or delete_me */ +static void +_eo_callback_remove_all(Private_Data *pd) +{ + Eina_Inlist *initr; + Eo_Callback_Description *cb = NULL; + EINA_INLIST_FOREACH_SAFE(pd->callbacks, initr, cb) + { + _eo_callback_remove(pd, cb); + } +} + +static void +_eo_callbacks_clear(Private_Data *pd) +{ + Eina_Inlist *itn; + Eo_Callback_Description *cb = NULL; + + /* Abort if we are currently walking the list. */ + if (pd->walking_list > 0) + return; + + EINA_INLIST_FOREACH_SAFE(pd->callbacks, itn, cb) + { + if (cb->delete_me) + { + _eo_callback_remove(pd, cb); + } + } +} + +static int +_callback_priority_cmp(const void *_a, const void *_b) +{ + const Eo_Callback_Description *a, *b; + a = (const Eo_Callback_Description *) _a; + b = (const Eo_Callback_Description *) _b; + if (a->priority < b->priority) + return -1; + else + return 1; +} + +static void +_ev_cb_priority_add(Eo *obj, void *class_data, va_list *list) +{ + Private_Data *pd = (Private_Data *) class_data; + const Eo_Event_Description *desc = va_arg(*list, const Eo_Event_Description *); + Eo_Callback_Priority priority = va_arg(*list, int); + Eo_Event_Cb func = va_arg(*list, Eo_Event_Cb); + const void *data = va_arg(*list, const void *); + + Eo_Callback_Description *cb = calloc(1, sizeof(*cb)); + cb->event = desc; + cb->func = func; + cb->func_data = (void *) data; + cb->priority = priority; + pd->callbacks = eina_inlist_sorted_insert(pd->callbacks, + EINA_INLIST_GET(cb), _callback_priority_cmp); + + eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_ADD, desc, NULL)); +} + +static void +_ev_cb_del_lazy(Eo *obj, void *class_data, va_list *list) +{ + Private_Data *pd = (Private_Data *) class_data; + const Eo_Event_Description *desc = va_arg(*list, const Eo_Event_Description *); + Eo_Event_Cb func = va_arg(*list, Eo_Event_Cb); + void **ret = va_arg(*list, void **); + + Eo_Callback_Description *cb; + EINA_INLIST_FOREACH(pd->callbacks, cb) + { + if ((cb->event == desc) && (cb->func == func)) + { + void *data; + + data = cb->func_data; + cb->delete_me = EINA_TRUE; + _eo_callbacks_clear(pd); + if (ret) *ret = data; + eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_DEL, desc, NULL)); + return; + } + } + + if (ret) *ret = NULL; +} + +static void +_ev_cb_del(Eo *obj, void *class_data, va_list *list) +{ + Private_Data *pd = (Private_Data *) class_data; + const Eo_Event_Description *desc = va_arg(*list, const Eo_Event_Description *); + Eo_Event_Cb func = va_arg(*list, Eo_Event_Cb); + void *user_data = va_arg(*list, void *); + + Eo_Callback_Description *cb; + EINA_INLIST_FOREACH(pd->callbacks, cb) + { + if ((cb->event == desc) && (cb->func == func) && + (cb->func_data == user_data)) + { + cb->delete_me = EINA_TRUE; + _eo_callbacks_clear(pd); + eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_DEL, desc, NULL)); + return; + } + } +} + +static void +_ev_cb_call(const Eo *_obj, const void *class_data, va_list *list) +{ + Private_Data *pd = (Private_Data *) class_data; + Eo *obj = (Eo *) _obj; + const Eo_Event_Description *desc = va_arg(*list, const Eo_Event_Description *); + void *event_info = va_arg(*list, void *); + Eina_Bool *ret = va_arg(*list, Eina_Bool *); + + Eo_Callback_Description *cb; + + if (ret) *ret = EINA_TRUE; + + /* FIXME: Change eo_ref to _eo_ref and unref. */ + eo_ref(obj); + pd->walking_list++; + + EINA_INLIST_FOREACH(pd->callbacks, cb) + { + if (!cb->delete_me && (cb->event == desc)) + { + /* Abort callback calling if the func says so. */ + if (!cb->func((void *) cb->func_data, obj, desc, + (void *) event_info)) + { + if (ret) *ret = EINA_FALSE; + break; + } + } + } + pd->walking_list--; + _eo_callbacks_clear(pd); + eo_unref(obj); +} + +static Eina_Bool +_eo_event_forwarder_callback(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info) +{ + (void) obj; + Eo *new_obj = (Eo *) data; + Eina_Bool ret; + eo_do(new_obj, eo_event_callback_call(desc, event_info, &ret)); + return ret; +} + +/* FIXME: Change default priority? Maybe call later? */ +static void +_ev_cb_forwarder_add(Eo *obj, void *class_data EINA_UNUSED, va_list *list) +{ + const Eo_Event_Description *desc = va_arg(*list, const Eo_Event_Description *); + Eo *new_obj = va_arg(*list, Eo *); + /* FIXME: Add it EO_MAGIC_RETURN(new_obj, EO_EINA_MAGIC); */ + + eo_do(obj, eo_event_callback_add(desc, _eo_event_forwarder_callback, new_obj)); +} + +static void +_ev_cb_forwarder_del(Eo *obj, void *class_data EINA_UNUSED, va_list *list) +{ + const Eo_Event_Description *desc = va_arg(*list, const Eo_Event_Description *); + Eo *new_obj = va_arg(*list, Eo *); + /* FIXME: Add it EO_MAGIC_RETURN(new_obj, EO_EINA_MAGIC); */ + + eo_do(obj, eo_event_callback_del(desc, _eo_event_forwarder_callback, new_obj)); +} + +/* EOF event callbacks */ + /* EO_BASE_CLASS stuff */ #define MY_CLASS EO_BASE_CLASS @@ -247,6 +453,7 @@ _destructor(Eo *obj, void *class_data) _eo_generic_data_del_all(class_data); _wref_destruct(class_data); + _eo_callback_remove_all(class_data); } static void @@ -258,6 +465,12 @@ _class_constructor(Eo_Class *klass) EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DATA_DEL), _data_del), EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_WREF_ADD), _wref_add), EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_WREF_DEL), _wref_del), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_PRIORITY_ADD), _ev_cb_priority_add), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_DEL), _ev_cb_del), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_DEL_LAZY), _ev_cb_del_lazy), + EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL), _ev_cb_call), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD), _ev_cb_forwarder_add), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL), _ev_cb_forwarder_del), EO_OP_FUNC_SENTINEL }; @@ -270,12 +483,16 @@ static const Eo_Op_Description op_desc[] = { EO_OP_DESCRIPTION(EO_BASE_SUB_ID_DATA_DEL, "?", "Del key."), EO_OP_DESCRIPTION_CONST(EO_BASE_SUB_ID_WREF_ADD, "?", "Add a weak ref to the object."), EO_OP_DESCRIPTION_CONST(EO_BASE_SUB_ID_WREF_DEL, "?", "Delete the weak ref."), + EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_PRIORITY_ADD, "?", "Add an event callback with a priority."), + EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_DEL, "?", "Delete an event callback"), + EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_DEL_LAZY, "?", "Delete an event callback in a lazy way."), + EO_OP_DESCRIPTION_CONST(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL, "?", "Call the event callbacks for an event."), + EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD, "?", "Add an event forwarder."), + EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL, "?", "Delete an event forwarder."), EO_OP_DESCRIPTION_SENTINEL }; static const Eo_Event_Description *event_desc[] = { - EO_EV_CALLBACK_ADD, - EO_EV_CALLBACK_DEL, EO_EV_DEL, NULL }; diff --git a/lib/eo_private.h b/lib/eo_private.h index bdaa01e..3559355 100644 --- a/lib/eo_private.h +++ b/lib/eo_private.h @@ -1,6 +1,32 @@ #ifndef _EO_PRIVATE_H #define _EO_PRIVATE_H +#define EO_EINA_MAGIC 0xa186bc32 /* Nothing magical about this number. */ +#define EO_EINA_MAGIC_STR "Eo" +#define EO_DELETED_EINA_MAGIC 0xa186bb32 /* Nothing magical about this number. */ +#define EO_DELETED_EINA_MAGIC_STR "Eo - Deleted object" +#define EO_CLASS_EINA_MAGIC 0xa186ba32 /* Nothing magical about this number. */ +#define EO_CLASS_EINA_MAGIC_STR "Eo Class" + +#define EO_MAGIC_RETURN_VAL(d, magic, ret) \ + do { \ + if (!EINA_MAGIC_CHECK(d, magic)) \ + { \ + EINA_MAGIC_FAIL(d, magic); \ + return ret; \ + } \ + } while (0) + +#define EO_MAGIC_RETURN(d, magic) \ + do { \ + if (!EINA_MAGIC_CHECK(d, magic)) \ + { \ + EINA_MAGIC_FAIL(d, magic); \ + return; \ + } \ + } while (0) + + extern int _eo_log_dom; #ifdef CRITICAL diff --git a/tests/eo_test_general.c b/tests/eo_test_general.c index 9f3fc21..dfc7663 100644 --- a/tests/eo_test_general.c +++ b/tests/eo_test_general.c @@ -369,15 +369,8 @@ START_TEST(eo_magic_checks) eo_composite_object_detach(obj, (Eo *) buf); eo_composite_is((Eo *) buf); - fail_if(eo_event_callback_add((Eo *) buf, NULL, NULL, NULL)); - fail_if(eo_event_callback_del_lazy((Eo *) buf, NULL, NULL)); - fail_if(eo_event_callback_del((Eo *) buf, NULL, NULL, NULL)); - fail_if(eo_event_callback_call((Eo *) buf, NULL, NULL)); - - fail_if(eo_event_callback_forwarder_add((Eo *) buf, NULL, obj)); - fail_if(eo_event_callback_forwarder_add(obj, NULL, (Eo *) buf)); - fail_if(eo_event_callback_forwarder_del((Eo *) buf, NULL, obj)); - fail_if(eo_event_callback_forwarder_del(obj, NULL, (Eo *) buf)); + eo_do(obj, eo_event_callback_forwarder_add(NULL, (Eo *) buf)); + eo_do(obj, eo_event_callback_forwarder_del(NULL, (Eo *) buf)); eo_unref(obj);