edje_signal: reduce member count when deleted edje_signal_callback is found
authorSungtaek Hong <sth253.hong@samsung.com>
Mon, 17 Jul 2017 06:05:19 +0000 (15:05 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 17 Jul 2017 06:05:20 +0000 (15:05 +0900)
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
src/lib/edje/edje_signal.c
src/tests/edje/data/test_signal_callback_del_full.edc [new file with mode: 0644]
src/tests/edje/edje_test_edje.c

index b982d1a..4ca20e5 100644 (file)
@@ -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)
index 12f22ef..0e381c1 100644 (file)
@@ -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 (file)
index 0000000..af9acc1
--- /dev/null
@@ -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;
+               }
+            }
+         }
+      }
+   }
+}
index af88fa8..f7b0175 100644 (file)
@@ -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);
 }