From d545929845925997e8a8a4f0e4a43d7662e2a457 Mon Sep 17 00:00:00 2001 From: Sungtaek Hong Date: Mon, 17 Jul 2017 15:05:19 +0900 Subject: [PATCH] edje_signal: reduce member count when deleted edje_signal_callback is found Summary: - when deleted callback is found _edje_signal_callback_move_last() is called in order to pack match array. - during _edje_signal_callback_move_last() index skips when another deleted callback is found, but does not reduce members_count. - this duplicates a remaining callback and calls the callback twice. Test Plan: 1. add multiple edje_signal_callback by edje_object_signal_callback_add() which have the same source, signal, func but different data. 2. delete first and last callback by edje_object_signal_callback_del/edje_object_signal_callback_del_full. 3. emit edje_signal. 4. observe one callback is called twice. Reviewers: SanghyeonLee, conr2d, jpeg Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4985 --- src/Makefile_Edje.am | 2 + src/lib/edje/edje_signal.c | 5 +++ .../data/test_signal_callback_del_full.edc | 24 ++++++++++ src/tests/edje/edje_test_edje.c | 44 +++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 src/tests/edje/data/test_signal_callback_del_full.edc diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am index b982d1a739..4ca20e570b 100644 --- a/src/Makefile_Edje.am +++ b/src/Makefile_Edje.am @@ -286,6 +286,7 @@ tests/edje/data/test_table.edc \ tests/edje/data/test_combine_keywords.edc \ tests/edje/data/test_messages.edc \ tests/edje/data/test_signals.edc \ +tests/edje/data/test_signal_callback_del_full.edc \ tests/edje/data/filter.lua @@ -328,6 +329,7 @@ EDJE_TEST_FILES = tests/edje/data/test_layout.edj \ tests/edje/data/test_combine_keywords.edj \ tests/edje/data/test_messages.edj \ tests/edje/data/test_signals.edj \ + tests/edje/data/test_signal_callback_del_full.edj \ $(NULL) CLEANFILES += $(EDJE_TEST_FILES) diff --git a/src/lib/edje/edje_signal.c b/src/lib/edje/edje_signal.c index 12f22ef791..0e381c17a6 100644 --- a/src/lib/edje/edje_signal.c +++ b/src/lib/edje/edje_signal.c @@ -363,6 +363,11 @@ _edje_signal_callback_move_last(Edje_Signal_Callback_Group *gp, gp->custom_data[i] = gp->custom_data[j]; return; } + else + { + _edje_signal_callback_unset(gp, j); + m->matches_count--; + } } } diff --git a/src/tests/edje/data/test_signal_callback_del_full.edc b/src/tests/edje/data/test_signal_callback_del_full.edc new file mode 100644 index 0000000000..af9acc1b45 --- /dev/null +++ b/src/tests/edje/data/test_signal_callback_del_full.edc @@ -0,0 +1,24 @@ +// compile: edje_cc test_signal_callback_del_full.edc +collections { + group { + name: "test"; + + parts { + part { + name: "event"; + type: RECT; + description { + state: "default" 0.0; + rel1 { + relative: 0.0 0.0; + offset: 0 0; + } + rel2 { + relative: 1.0 1.0; + offset: -1 -1; + } + } + } + } + } +} diff --git a/src/tests/edje/edje_test_edje.c b/src/tests/edje/edje_test_edje.c index af88fa8d84..f7b017566f 100644 --- a/src/tests/edje/edje_test_edje.c +++ b/src/tests/edje/edje_test_edje.c @@ -900,6 +900,49 @@ START_TEST(edje_test_signals) } END_TEST +static int _signal_count; + +static void +_signal_callback_count_cb(void *data, Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, const char *source EINA_UNUSED) +{ + int *_data = data; + _signal_count += *_data; +} + +START_TEST(edje_test_signal_callback_del_full) +{ + Evas *evas; + Evas_Object *obj; + int data[4] = { 1, 2, 4, 8 }; + + evas = EDJE_TEST_INIT_EVAS(); + + obj = efl_add(EDJE_OBJECT_CLASS, evas, + efl_file_set(efl_added, + test_layout_get("test_signal_callback_del_full.edj"), "test"), + efl_gfx_size_set(efl_added, 320, 240), + efl_gfx_visible_set(efl_added, 1)); + + edje_object_signal_callback_add(obj, "some_signal", "event", _signal_callback_count_cb, &data[0]); + edje_object_signal_callback_add(obj, "some_signal", "event", _signal_callback_count_cb, &data[1]); + edje_object_signal_callback_add(obj, "some_signal", "event", _signal_callback_count_cb, &data[2]); + edje_object_signal_callback_add(obj, "some_signal", "event", _signal_callback_count_cb, &data[3]); + + edje_object_signal_callback_del_full(obj, "some_signal", "event", _signal_callback_count_cb, &data[0]); + edje_object_signal_callback_del_full(obj, "some_signal", "event", _signal_callback_count_cb, &data[3]); + + edje_object_signal_emit(obj, "some_signal", "event"); + + edje_object_message_signal_process(obj); + ck_assert_int_eq(_signal_count, (data[1] + data[2])); + + efl_del(obj); + + EDJE_TEST_FREE_EVAS(); +} +END_TEST + void edje_test_edje(TCase *tc) { tcase_add_test(tc, edje_test_edje_init); @@ -924,4 +967,5 @@ void edje_test_edje(TCase *tc) tcase_add_test(tc, edje_test_message_send_legacy); tcase_add_test(tc, edje_test_message_send_eo); tcase_add_test(tc, edje_test_signals); + tcase_add_test(tc, edje_test_signal_callback_del_full); }