summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile_Edje.am2
-rw-r--r--src/lib/edje/edje_message_queue.c108
-rw-r--r--src/lib/edje/edje_object.eo17
-rw-r--r--src/tests/edje/data/test_messages.edc67
-rw-r--r--src/tests/edje/edje_test_edje.c144
5 files changed, 327 insertions, 11 deletions
diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am
index a4f5073..34a2cb7 100644
--- a/src/Makefile_Edje.am
+++ b/src/Makefile_Edje.am
@@ -277,6 +277,7 @@ tests/edje/data/test_swallows.edc \
277tests/edje/data/test_box.edc \ 277tests/edje/data/test_box.edc \
278tests/edje/data/test_table.edc \ 278tests/edje/data/test_table.edc \
279tests/edje/data/test_combine_keywords.edc \ 279tests/edje/data/test_combine_keywords.edc \
280tests/edje/data/test_messages.edc \
280tests/edje/data/filter.lua 281tests/edje/data/filter.lua
281 282
282 283
@@ -317,6 +318,7 @@ EDJE_TEST_FILES = tests/edje/data/test_layout.edj \
317 tests/edje/data/test_box.edj \ 318 tests/edje/data/test_box.edj \
318 tests/edje/data/test_table.edj \ 319 tests/edje/data/test_table.edj \
319 tests/edje/data/test_combine_keywords.edj \ 320 tests/edje/data/test_combine_keywords.edj \
321 tests/edje/data/test_messages.edj \
320 $(NULL) 322 $(NULL)
321 323
322CLEANFILES += $(EDJE_TEST_FILES) 324CLEANFILES += $(EDJE_TEST_FILES)
diff --git a/src/lib/edje/edje_message_queue.c b/src/lib/edje/edje_message_queue.c
index 7dfc062..31fed48 100644
--- a/src/lib/edje/edje_message_queue.c
+++ b/src/lib/edje/edje_message_queue.c
@@ -32,9 +32,113 @@ _edje_object_message_propagate_send(Evas_Object *obj, Edje_Message_Type type, in
32} 32}
33 33
34EOLIAN void 34EOLIAN void
35_edje_object_message_send(Eo *obj, Edje *pd EINA_UNUSED, int id, const Eina_Value *val) 35_edje_object_message_send(Eo *obj, Edje *pd EINA_UNUSED, int id, const Eina_Value val)
36{ 36{
37 /* TODO */ 37 const Eina_Value_Type *valtype;
38 Edje_Message_Type msgtype;
39
40 /* Note: Only primitive types & arrays of them are supported.
41 * This reduces complexity and I couldn't find many real uses for combo
42 * types (string+int or string+float).
43 */
44
45 union {
46 Edje_Message_String str;
47 Edje_Message_Int i;
48 Edje_Message_Float f;
49 Edje_Message_String_Set ss;
50 Edje_Message_Int_Set is;
51 Edje_Message_Float_Set fs;
52 //Edje_Message_String_Int si;
53 //Edje_Message_String_Float sf;
54 //Edje_Message_String_Int_Set sis;
55 //Edje_Message_String_Float_Set sfs;
56 } msg, *pmsg;
57
58 valtype = eina_value_type_get(&val);
59 if (!valtype) goto bad_type;
60
61 pmsg = &msg;
62 if ((valtype == EINA_VALUE_TYPE_STRING) ||
63 (valtype == EINA_VALUE_TYPE_STRINGSHARE))
64 {
65 eina_value_get(&val, &msg.str.str);
66 msgtype = EDJE_MESSAGE_STRING;
67 }
68 else if (valtype == EINA_VALUE_TYPE_INT)
69 {
70 eina_value_get(&val, &msg.i.val);
71 msgtype = EDJE_MESSAGE_INT;
72 }
73 else if (valtype == EINA_VALUE_TYPE_FLOAT)
74 {
75 float f;
76 eina_value_get(&val, &f);
77 msg.f.val = (double) f;
78 msgtype = EDJE_MESSAGE_FLOAT;
79 }
80 else if (valtype == EINA_VALUE_TYPE_DOUBLE)
81 {
82 eina_value_get(&val, &msg.f.val);
83 msgtype = EDJE_MESSAGE_FLOAT;
84 }
85 else if (valtype == EINA_VALUE_TYPE_ARRAY)
86 {
87 Eina_Value_Array array = {};
88 size_t sz, k, count;
89
90 eina_value_get(&val, &array);
91 count = eina_inarray_count(array.array);
92 if ((array.subtype == EINA_VALUE_TYPE_STRING) ||
93 (array.subtype == EINA_VALUE_TYPE_STRINGSHARE))
94 {
95 sz = sizeof(char *);
96 msgtype = EDJE_MESSAGE_STRING_SET;
97 pmsg = alloca(sizeof(*pmsg) + sz * count);
98 pmsg->ss.count = count;
99 for (k = 0; k < count; k++)
100 pmsg->ss.str[k] = eina_inarray_nth(array.array, k);
101 }
102 else if (array.subtype == EINA_VALUE_TYPE_INT)
103 {
104 sz = sizeof(int);
105 msgtype = EDJE_MESSAGE_INT_SET;
106 pmsg = alloca(sizeof(*pmsg) + sz * count);
107 pmsg->is.count = count;
108 for (k = 0; k < count; k++)
109 pmsg->is.val[k] = *((int *) eina_inarray_nth(array.array, k));
110 }
111 else if (array.subtype == EINA_VALUE_TYPE_DOUBLE)
112 {
113 sz = sizeof(double);
114 msgtype = EDJE_MESSAGE_FLOAT_SET;
115 pmsg = alloca(sizeof(*pmsg) + sz * count);
116 pmsg->fs.count = count;
117 for (k = 0; k < count; k++)
118 pmsg->fs.val[k] = *((double *) eina_inarray_nth(array.array, k));
119 }
120 else if (array.subtype == EINA_VALUE_TYPE_FLOAT)
121 {
122 sz = sizeof(double);
123 msgtype = EDJE_MESSAGE_FLOAT_SET;
124 pmsg = alloca(sizeof(*pmsg) + sz * count);
125 pmsg->fs.count = count;
126 for (k = 0; k < count; k++)
127 pmsg->fs.val[k] = (double) *((float *) eina_inarray_nth(array.array, k));
128 }
129 else goto bad_type;
130
131 }
132 else goto bad_type;
133
134 _edje_object_message_propagate_send(obj, msgtype, id, pmsg, EINA_FALSE);
135 return;
136
137bad_type:
138 ERR("Unsupported value type: %s. Only primitives types int, real "
139 "(float or double), string or arrays of those types are supported.",
140 eina_value_type_name_get(valtype));
141 return;
38} 142}
39 143
40EOLIAN void 144EOLIAN void
diff --git a/src/lib/edje/edje_object.eo b/src/lib/edje/edje_object.eo
index c0870df..a9e3694 100644
--- a/src/lib/edje/edje_object.eo
+++ b/src/lib/edje/edje_object.eo
@@ -466,18 +466,17 @@ class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part,
466 466
467 This function sends an Edje message to obj and to all of its 467 This function sends an Edje message to obj and to all of its
468 child objects, if it has any (swallowed objects are one kind of 468 child objects, if it has any (swallowed objects are one kind of
469 child object). type and msg must be matched accordingly, 469 child object). Only a few types are supported:
470 as documented in #Edje_Message_Type. 470 - int,
471 - float/double,
472 - string/stringshare,
473 - arrays of int, float, double or strings.
471 474
472 The id argument as a form of code and theme defining a common 475 The id argument as a form of code and theme defining a common
473 interface on message communication. One should define the same IDs 476 interface on message communication. One should define the same IDs
474 on both code and EDC declaration (see \@ref edcref "the syntax" for 477 on both code and EDC declaration, to individualize messages
475 EDC files), to individualize messages (binding them to a given 478 (binding them to a given context).
476 context). 479 ]]
477
478 The function to handle messages arriving from obj is set with
479 edje_object_message_handler_set().]]
480
481 params { 480 params {
482 @in id: int; [[A identification number for the message to be sent]] 481 @in id: int; [[A identification number for the message to be sent]]
483 @in msg: const(generic_value); [[The message's payload]] 482 @in msg: const(generic_value); [[The message's payload]]
diff --git a/src/tests/edje/data/test_messages.edc b/src/tests/edje/data/test_messages.edc
new file mode 100644
index 0000000..bd207cd
--- /dev/null
+++ b/src/tests/edje/data/test_messages.edc
@@ -0,0 +1,67 @@
1collections {
2 group { "test_group";
3 parts {
4 rect { "bg";
5 desc { "default";
6 color: 0 0 0 255;
7 }
8 }
9 text { "text";
10 desc { "default";
11 text {
12 font: "Sans";
13 size: 24;
14 text: "HELLO";
15 }
16 }
17 }
18 }
19
20// Messages IDs:
21 // 0. string, text string
22 // 1. int, text size
23 // 2. int set, bg color (4 ints)
24 // 3. float, sends signal
25
26 script {
27 public message(Msg_Type:type, id, ...) {
28 if ((type == MSG_STRING) && (id == 0)) {
29 new str[64], buf[64];
30
31 getsarg(2, str, sizeof(str));
32 set_text(PART:"text", str);
33
34 snprintf(buf, sizeof(buf), "str %s", str);
35 emit(buf, "edc");
36 }
37 else if ((type == MSG_INT) && (id == 1)) {
38 new i, buf[64];
39
40 i = getarg(2);
41 set_state_val(PART:"text", STATE_TEXT_SIZE, i);
42
43 snprintf(buf, sizeof(buf), "int %d", i);
44 emit(buf, "edc");
45 }
46 else if ((type == MSG_FLOAT) && (id == 2)) {
47 new f, buf[64];
48
49 f = getarg(2);
50 snprintf(buf, sizeof(buf), "float %f", f);
51 emit(buf, "edc");
52 }
53 else if ((type == MSG_INT_SET) && (id == 3)) {
54 new r, g, b, a, buf[64];
55
56 r = getarg(2);
57 g = getarg(3);
58 b = getarg(4);
59 a = getarg(5);
60 set_state_val(PART:"bg", STATE_COLOR, r, g, b, a);
61
62 snprintf(buf, sizeof(buf), "int set %d %d %d %d", r, g, b, a);
63 emit(buf, "edc");
64 }
65 }
66 }
67 }
diff --git a/src/tests/edje/edje_test_edje.c b/src/tests/edje/edje_test_edje.c
index e2723d8..d92c8c0 100644
--- a/src/tests/edje/edje_test_edje.c
+++ b/src/tests/edje/edje_test_edje.c
@@ -725,6 +725,148 @@ START_TEST(edje_test_combine_keywords)
725} 725}
726END_TEST 726END_TEST
727 727
728static void
729_message_signal_reply_cb(void *data, Evas_Object *obj EINA_UNUSED,
730 const char *emission, const char *source)
731{
732 int *id = data;
733
734 fprintf(stderr, "source %s emit %s id %d\n", source, emission, *id);
735 fflush(stderr);
736 ck_assert_str_eq(source, "edc");
737 ck_assert_ptr_nonnull(emission);
738
739 if (!strncmp(emission, "int set", 7))
740 ck_assert_str_eq(emission, "int set 7 12 42 255");
741 else if (!strncmp(emission, "int", 3))
742 ck_assert_str_eq(emission, "int 42");
743 else if (!strncmp(emission, "float", 5))
744 {
745 char buf[64];
746 sprintf(buf, "float %f", 0.12);
747 ck_assert_str_eq(emission, buf);
748 }
749 else if (!strncmp(emission, "str", 3))
750 ck_assert_str_eq(emission, "str hello world");
751 else ck_abort_msg("Invalid emission!");
752
753 (*id)++;
754}
755
756START_TEST(edje_test_message_send_legacy)
757{
758 Evas *evas;
759 Evas_Object *obj;
760 Edje_Message_Int msgi;
761 Edje_Message_Float msgf;
762 Edje_Message_String msgs;
763 Edje_Message_Int_Set *msgis;
764 int id = 0;
765
766 /* Ugly calls to process:
767 *
768 * 1. Send edje message (async)
769 * 2. Process edje message (sync)
770 * 3. EDC program emits edje signal (async)
771 * 4. Process edje signal (sync)
772 * 5. Finally reached signal cb
773 */
774
775 evas = EDJE_TEST_INIT_EVAS();
776
777 obj = edje_object_add(evas);
778 fail_unless(edje_object_file_set(obj, test_layout_get("test_messages.edj"), "test_group"));
779 edje_object_signal_callback_add(obj, "*", "edc", _message_signal_reply_cb, &id);
780
781 msgs.str = "hello world";
782 edje_object_message_send(obj, EDJE_MESSAGE_STRING, 0, &msgs);
783 edje_message_signal_process();
784 ck_assert_int_eq(id, 1);
785
786 msgi.val = 42;
787 edje_object_message_send(obj, EDJE_MESSAGE_INT, 1, &msgi);
788 edje_message_signal_process();
789 ck_assert_int_eq(id, 2);
790
791 msgf.val = 0.12;
792 edje_object_message_send(obj, EDJE_MESSAGE_FLOAT, 2, &msgf);
793 edje_message_signal_process();
794 ck_assert_int_eq(id, 3);
795
796 msgis = alloca(sizeof(*msgis) + 4 * sizeof(msgis->val));
797 msgis->count = 4;
798 msgis->val[0] = 7;
799 msgis->val[1] = 12;
800 msgis->val[2] = 42;
801 msgis->val[3] = 255;
802 edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 3, msgis);
803 edje_message_signal_process();
804 ck_assert_int_eq(id, 4);
805
806 evas_object_del(obj);
807
808 EDJE_TEST_FREE_EVAS();
809}
810END_TEST
811
812START_TEST(edje_test_message_send_eo)
813{
814 Evas *evas;
815 Evas_Object *obj;
816 Eina_Value v, *va;
817 int id = 0;
818
819 evas = EDJE_TEST_INIT_EVAS();
820
821 obj = efl_add(EDJE_OBJECT_CLASS, evas,
822 efl_file_set(efl_added, test_layout_get("test_messages.edj"), "test_group"));
823
824 // FIXME: EO API HERE
825 edje_object_signal_callback_add(obj, "*", "edc", _message_signal_reply_cb, &id);
826
827 // NOTE: edje_object_message_signal_process may or may not be in EO (TBD)
828
829 eina_value_setup(&v, EINA_VALUE_TYPE_STRING);
830 eina_value_set(&v, "hello world");
831 edje_obj_message_send(obj, 0, v);
832 eina_value_flush(&v);
833 edje_message_signal_process();
834 edje_object_calc_force(obj);
835 ck_assert_int_eq(id, 1);
836
837 eina_value_setup(&v, EINA_VALUE_TYPE_INT);
838 eina_value_set(&v, 42);
839 edje_obj_message_send(obj, 1, v);
840 eina_value_flush(&v);
841 edje_message_signal_process();
842 edje_object_calc_force(obj);
843 ck_assert_int_eq(id, 2);
844
845 eina_value_setup(&v, EINA_VALUE_TYPE_FLOAT);
846 eina_value_set(&v, 0.12);
847 edje_obj_message_send(obj, 2, v);
848 eina_value_flush(&v);
849 edje_message_signal_process();
850 edje_object_calc_force(obj);
851 ck_assert_int_eq(id, 3);
852
853 va = eina_value_array_new(EINA_VALUE_TYPE_INT, 4);
854 eina_value_array_append(va, 7);
855 eina_value_array_append(va, 12);
856 eina_value_array_append(va, 42);
857 eina_value_array_append(va, 255);
858 edje_obj_message_send(obj, 3, *va);
859 eina_value_free(va);
860 edje_message_signal_process();
861 edje_object_calc_force(obj);
862 ck_assert_int_eq(id, 4);
863
864 efl_del(obj);
865
866 EDJE_TEST_FREE_EVAS();
867}
868END_TEST
869
728void edje_test_edje(TCase *tc) 870void edje_test_edje(TCase *tc)
729{ 871{
730 tcase_add_test(tc, edje_test_edje_init); 872 tcase_add_test(tc, edje_test_edje_init);
@@ -746,4 +888,6 @@ void edje_test_edje(TCase *tc)
746 tcase_add_test(tc, edje_test_table); 888 tcase_add_test(tc, edje_test_table);
747 tcase_add_test(tc, edje_test_table_eoapi); 889 tcase_add_test(tc, edje_test_table_eoapi);
748 tcase_add_test(tc, edje_test_combine_keywords); 890 tcase_add_test(tc, edje_test_combine_keywords);
891 tcase_add_test(tc, edje_test_message_send_legacy);
892 tcase_add_test(tc, edje_test_message_send_eo);
749} 893}