summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>2016-12-01 12:40:36 +0100
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>2016-12-02 11:34:21 +0100
commit5d22bb9a884e64830c61e67bb95898bf20f4f58d (patch)
tree836f121403359e16380ec0bfe6cb1debc2891b55
parentfb75e246c2d80195c32c3db177e40e046dd79ec1 (diff)
downloadefl-5d22bb9a884e64830c61e67bb95898bf20f4f58d.tar.gz
eo: use the event stack to define behaviour
subscriptions are only executed if they were already subscriped at the start of the event emission.
-rw-r--r--src/lib/eo/eo_base_class.c36
-rw-r--r--src/tests/eo/suite/eo_test_event.c9
2 files changed, 37 insertions, 8 deletions
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index f096891fc5..1bc80babe0 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -19,6 +19,7 @@ typedef struct {
EINA_INLIST;
unsigned int idx;
unsigned int inserted_before;
+ unsigned char generation;
} Efl_Event_Callback_Frame;
typedef struct
@@ -51,8 +52,8 @@ typedef struct
unsigned short event_cb_efl_event_callback_del_count;
unsigned short event_cb_efl_event_del_count;
#endif
- Eina_Bool deletions_waiting : 1;
Eina_Bool callback_stopped : 1;
+ Eina_Bool need_cleaning : 1;
Eina_Bool parent_sunk : 1; // If parent ref has already been settled (parent has been set, or we are in add_ref mode
} Efl_Object_Data;
@@ -920,6 +921,8 @@ struct _Eo_Callback_Description
void *func_data;
Efl_Callback_Priority priority;
+ unsigned char generation;
+
Eina_Bool delete_me : 1;
Eina_Bool func_array : 1;
};
@@ -1054,16 +1057,20 @@ _eo_callbacks_clear(Efl_Object_Data *pd)
unsigned int i = 0;
/* If there are no deletions waiting. */
- if (!pd->deletions_waiting) return;
+ if (!pd->need_cleaning) return;
/* Abort if we are currently walking the list. */
if (pd->event_frame) return;
- pd->deletions_waiting = EINA_FALSE;
+ pd->need_cleaning = EINA_FALSE;
while (i < pd->callbacks_count)
{
itr = pd->callbacks + i;
if ((*itr)->delete_me) _eo_callback_remove(pd, itr);
- else i++;
+ else
+ {
+ (*itr)->generation = 0;
+ i++;
+ }
}
}
@@ -1144,6 +1151,14 @@ _eo_callbacks_sorted_insert(Efl_Object_Data *pd, Eo_Callback_Description *cb)
}
}
+static unsigned char
+_efl_event_generation(Efl_Object_Data *pd)
+{
+ if (!pd->event_frame) return 0;
+
+ return ((Efl_Event_Callback_Frame*)pd->event_frame)->generation;
+}
+
EOLIAN static Eina_Bool
_efl_object_event_callback_priority_add(Eo *obj, Efl_Object_Data *pd,
const Efl_Event_Description *desc,
@@ -1160,6 +1175,9 @@ _efl_object_event_callback_priority_add(Eo *obj, Efl_Object_Data *pd,
cb->items.item.func = func;
cb->func_data = (void *)user_data;
cb->priority = priority;
+ cb->generation = _efl_event_generation(pd);
+ if (!!cb->generation) pd->need_cleaning = EINA_TRUE;
+
_eo_callbacks_sorted_insert(pd, cb);
#ifdef EFL_EVENT_SPECIAL_SKIP
_special_event_count_inc(pd, &(cb->items.item));
@@ -1182,7 +1200,7 @@ _efl_object_event_callback_clean(Eo *obj, Efl_Object_Data *pd,
{
(*cb)->delete_me = EINA_TRUE;
if (pd->event_frame)
- pd->deletions_waiting = EINA_TRUE;
+ pd->need_cleaning = EINA_TRUE;
else
_eo_callback_remove(pd, cb);
@@ -1251,6 +1269,9 @@ _efl_object_event_callback_array_priority_add(Eo *obj, Efl_Object_Data *pd,
cb->priority = priority;
cb->items.item_array = array;
cb->func_array = EINA_TRUE;
+ cb->generation = _efl_event_generation(pd);
+ if (!!cb->generation) pd->need_cleaning = EINA_TRUE;
+
_eo_callbacks_sorted_insert(pd, cb);
#ifdef EFL_EVENT_SPECIAL_SKIP
for (it = cb->items.item_array; it->func; it++)
@@ -1325,7 +1346,7 @@ _event_callback_call(Eo *obj_id, Efl_Object_Data *pd,
#endif
memset(&frame, 0, sizeof(Efl_Event_Callback_Frame));
-
+ frame.generation = _efl_event_generation(pd) + 1;
EVENT_STACK_PUSH(pd, &frame);
lookup = NULL;
@@ -1348,6 +1369,9 @@ restart_back:
cb = pd->callbacks + idx - 1;
if (!(*cb)->delete_me)
{
+ if ((*cb)->generation >= frame.generation)
+ continue;
+
if ((*cb)->func_array)
{
const Efl_Callback_Array_Item *it;
diff --git a/src/tests/eo/suite/eo_test_event.c b/src/tests/eo/suite/eo_test_event.c
index f8727fa022..b12280116b 100644
--- a/src/tests/eo/suite/eo_test_event.c
+++ b/src/tests/eo/suite/eo_test_event.c
@@ -60,13 +60,18 @@ START_TEST(eo_event)
efl_object_init();
Eo *obj;
- memset(&data, 0, sizeof(Test_Data));
-
obj = efl_add(efl_test_event_class_get(), NULL);
efl_event_callback_priority_add(obj, EFL_TEST_EVENT_EVENT_TESTER, EFL_CALLBACK_PRIORITY_BEFORE, _cb2, &data);
efl_event_callback_priority_add(obj, EFL_TEST_EVENT_EVENT_TESTER, EFL_CALLBACK_PRIORITY_BEFORE, _cb1, &data);
+
+ memset(&data, 0, sizeof(Test_Data));
efl_event_callback_call(obj, EFL_TEST_EVENT_EVENT_TESTER, NULL);
+ ck_assert_int_ne(data.event1, 0);
+ ck_assert_int_ne(data.event2, 0);
+ ck_assert_int_eq(data.event3, 0);
+ memset(&data, 0, sizeof(Test_Data));
+ efl_event_callback_call(obj, EFL_TEST_EVENT_EVENT_TESTER, NULL);
ck_assert_int_ne(data.event1, 0);
ck_assert_int_ne(data.event2, 0);
ck_assert_int_ne(data.event3, 0);