edje: Implement EO API for message_send
Since this uses generic_value (aka Eina_Value), there is an implicit type detection and conversion. I did not attempt to cover all types (namely string+int and string+float and even less sets of those) as I believe they aren't really used. Or they most likely could be replaced by multiple messages rather than a single message. Note: should we pass ptr(generic_value) instead of generic_value? The API looks a little odd in C when passing by value. @feature
This commit is contained in:
parent
e7abfba034
commit
9d48350ae4
|
@ -277,6 +277,7 @@ tests/edje/data/test_swallows.edc \
|
|||
tests/edje/data/test_box.edc \
|
||||
tests/edje/data/test_table.edc \
|
||||
tests/edje/data/test_combine_keywords.edc \
|
||||
tests/edje/data/test_messages.edc \
|
||||
tests/edje/data/filter.lua
|
||||
|
||||
|
||||
|
@ -317,6 +318,7 @@ EDJE_TEST_FILES = tests/edje/data/test_layout.edj \
|
|||
tests/edje/data/test_box.edj \
|
||||
tests/edje/data/test_table.edj \
|
||||
tests/edje/data/test_combine_keywords.edj \
|
||||
tests/edje/data/test_messages.edj \
|
||||
$(NULL)
|
||||
|
||||
CLEANFILES += $(EDJE_TEST_FILES)
|
||||
|
|
|
@ -32,9 +32,113 @@ _edje_object_message_propagate_send(Evas_Object *obj, Edje_Message_Type type, in
|
|||
}
|
||||
|
||||
EOLIAN void
|
||||
_edje_object_message_send(Eo *obj, Edje *pd EINA_UNUSED, int id, const Eina_Value *val)
|
||||
_edje_object_message_send(Eo *obj, Edje *pd EINA_UNUSED, int id, const Eina_Value val)
|
||||
{
|
||||
/* TODO */
|
||||
const Eina_Value_Type *valtype;
|
||||
Edje_Message_Type msgtype;
|
||||
|
||||
/* Note: Only primitive types & arrays of them are supported.
|
||||
* This reduces complexity and I couldn't find many real uses for combo
|
||||
* types (string+int or string+float).
|
||||
*/
|
||||
|
||||
union {
|
||||
Edje_Message_String str;
|
||||
Edje_Message_Int i;
|
||||
Edje_Message_Float f;
|
||||
Edje_Message_String_Set ss;
|
||||
Edje_Message_Int_Set is;
|
||||
Edje_Message_Float_Set fs;
|
||||
//Edje_Message_String_Int si;
|
||||
//Edje_Message_String_Float sf;
|
||||
//Edje_Message_String_Int_Set sis;
|
||||
//Edje_Message_String_Float_Set sfs;
|
||||
} msg, *pmsg;
|
||||
|
||||
valtype = eina_value_type_get(&val);
|
||||
if (!valtype) goto bad_type;
|
||||
|
||||
pmsg = &msg;
|
||||
if ((valtype == EINA_VALUE_TYPE_STRING) ||
|
||||
(valtype == EINA_VALUE_TYPE_STRINGSHARE))
|
||||
{
|
||||
eina_value_get(&val, &msg.str.str);
|
||||
msgtype = EDJE_MESSAGE_STRING;
|
||||
}
|
||||
else if (valtype == EINA_VALUE_TYPE_INT)
|
||||
{
|
||||
eina_value_get(&val, &msg.i.val);
|
||||
msgtype = EDJE_MESSAGE_INT;
|
||||
}
|
||||
else if (valtype == EINA_VALUE_TYPE_FLOAT)
|
||||
{
|
||||
float f;
|
||||
eina_value_get(&val, &f);
|
||||
msg.f.val = (double) f;
|
||||
msgtype = EDJE_MESSAGE_FLOAT;
|
||||
}
|
||||
else if (valtype == EINA_VALUE_TYPE_DOUBLE)
|
||||
{
|
||||
eina_value_get(&val, &msg.f.val);
|
||||
msgtype = EDJE_MESSAGE_FLOAT;
|
||||
}
|
||||
else if (valtype == EINA_VALUE_TYPE_ARRAY)
|
||||
{
|
||||
Eina_Value_Array array = {};
|
||||
size_t sz, k, count;
|
||||
|
||||
eina_value_get(&val, &array);
|
||||
count = eina_inarray_count(array.array);
|
||||
if ((array.subtype == EINA_VALUE_TYPE_STRING) ||
|
||||
(array.subtype == EINA_VALUE_TYPE_STRINGSHARE))
|
||||
{
|
||||
sz = sizeof(char *);
|
||||
msgtype = EDJE_MESSAGE_STRING_SET;
|
||||
pmsg = alloca(sizeof(*pmsg) + sz * count);
|
||||
pmsg->ss.count = count;
|
||||
for (k = 0; k < count; k++)
|
||||
pmsg->ss.str[k] = eina_inarray_nth(array.array, k);
|
||||
}
|
||||
else if (array.subtype == EINA_VALUE_TYPE_INT)
|
||||
{
|
||||
sz = sizeof(int);
|
||||
msgtype = EDJE_MESSAGE_INT_SET;
|
||||
pmsg = alloca(sizeof(*pmsg) + sz * count);
|
||||
pmsg->is.count = count;
|
||||
for (k = 0; k < count; k++)
|
||||
pmsg->is.val[k] = *((int *) eina_inarray_nth(array.array, k));
|
||||
}
|
||||
else if (array.subtype == EINA_VALUE_TYPE_DOUBLE)
|
||||
{
|
||||
sz = sizeof(double);
|
||||
msgtype = EDJE_MESSAGE_FLOAT_SET;
|
||||
pmsg = alloca(sizeof(*pmsg) + sz * count);
|
||||
pmsg->fs.count = count;
|
||||
for (k = 0; k < count; k++)
|
||||
pmsg->fs.val[k] = *((double *) eina_inarray_nth(array.array, k));
|
||||
}
|
||||
else if (array.subtype == EINA_VALUE_TYPE_FLOAT)
|
||||
{
|
||||
sz = sizeof(double);
|
||||
msgtype = EDJE_MESSAGE_FLOAT_SET;
|
||||
pmsg = alloca(sizeof(*pmsg) + sz * count);
|
||||
pmsg->fs.count = count;
|
||||
for (k = 0; k < count; k++)
|
||||
pmsg->fs.val[k] = (double) *((float *) eina_inarray_nth(array.array, k));
|
||||
}
|
||||
else goto bad_type;
|
||||
|
||||
}
|
||||
else goto bad_type;
|
||||
|
||||
_edje_object_message_propagate_send(obj, msgtype, id, pmsg, EINA_FALSE);
|
||||
return;
|
||||
|
||||
bad_type:
|
||||
ERR("Unsupported value type: %s. Only primitives types int, real "
|
||||
"(float or double), string or arrays of those types are supported.",
|
||||
eina_value_type_name_get(valtype));
|
||||
return;
|
||||
}
|
||||
|
||||
EOLIAN void
|
||||
|
|
|
@ -466,18 +466,17 @@ class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part,
|
|||
|
||||
This function sends an Edje message to obj and to all of its
|
||||
child objects, if it has any (swallowed objects are one kind of
|
||||
child object). type and msg must be matched accordingly,
|
||||
as documented in #Edje_Message_Type.
|
||||
child object). Only a few types are supported:
|
||||
- int,
|
||||
- float/double,
|
||||
- string/stringshare,
|
||||
- arrays of int, float, double or strings.
|
||||
|
||||
The id argument as a form of code and theme defining a common
|
||||
interface on message communication. One should define the same IDs
|
||||
on both code and EDC declaration (see \@ref edcref "the syntax" for
|
||||
EDC files), to individualize messages (binding them to a given
|
||||
context).
|
||||
|
||||
The function to handle messages arriving from obj is set with
|
||||
edje_object_message_handler_set().]]
|
||||
|
||||
on both code and EDC declaration, to individualize messages
|
||||
(binding them to a given context).
|
||||
]]
|
||||
params {
|
||||
@in id: int; [[A identification number for the message to be sent]]
|
||||
@in msg: const(generic_value); [[The message's payload]]
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
collections {
|
||||
group { "test_group";
|
||||
parts {
|
||||
rect { "bg";
|
||||
desc { "default";
|
||||
color: 0 0 0 255;
|
||||
}
|
||||
}
|
||||
text { "text";
|
||||
desc { "default";
|
||||
text {
|
||||
font: "Sans";
|
||||
size: 24;
|
||||
text: "HELLO";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Messages IDs:
|
||||
// 0. string, text string
|
||||
// 1. int, text size
|
||||
// 2. int set, bg color (4 ints)
|
||||
// 3. float, sends signal
|
||||
|
||||
script {
|
||||
public message(Msg_Type:type, id, ...) {
|
||||
if ((type == MSG_STRING) && (id == 0)) {
|
||||
new str[64], buf[64];
|
||||
|
||||
getsarg(2, str, sizeof(str));
|
||||
set_text(PART:"text", str);
|
||||
|
||||
snprintf(buf, sizeof(buf), "str %s", str);
|
||||
emit(buf, "edc");
|
||||
}
|
||||
else if ((type == MSG_INT) && (id == 1)) {
|
||||
new i, buf[64];
|
||||
|
||||
i = getarg(2);
|
||||
set_state_val(PART:"text", STATE_TEXT_SIZE, i);
|
||||
|
||||
snprintf(buf, sizeof(buf), "int %d", i);
|
||||
emit(buf, "edc");
|
||||
}
|
||||
else if ((type == MSG_FLOAT) && (id == 2)) {
|
||||
new f, buf[64];
|
||||
|
||||
f = getarg(2);
|
||||
snprintf(buf, sizeof(buf), "float %f", f);
|
||||
emit(buf, "edc");
|
||||
}
|
||||
else if ((type == MSG_INT_SET) && (id == 3)) {
|
||||
new r, g, b, a, buf[64];
|
||||
|
||||
r = getarg(2);
|
||||
g = getarg(3);
|
||||
b = getarg(4);
|
||||
a = getarg(5);
|
||||
set_state_val(PART:"bg", STATE_COLOR, r, g, b, a);
|
||||
|
||||
snprintf(buf, sizeof(buf), "int set %d %d %d %d", r, g, b, a);
|
||||
emit(buf, "edc");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -725,6 +725,148 @@ START_TEST(edje_test_combine_keywords)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
_message_signal_reply_cb(void *data, Evas_Object *obj EINA_UNUSED,
|
||||
const char *emission, const char *source)
|
||||
{
|
||||
int *id = data;
|
||||
|
||||
fprintf(stderr, "source %s emit %s id %d\n", source, emission, *id);
|
||||
fflush(stderr);
|
||||
ck_assert_str_eq(source, "edc");
|
||||
ck_assert_ptr_nonnull(emission);
|
||||
|
||||
if (!strncmp(emission, "int set", 7))
|
||||
ck_assert_str_eq(emission, "int set 7 12 42 255");
|
||||
else if (!strncmp(emission, "int", 3))
|
||||
ck_assert_str_eq(emission, "int 42");
|
||||
else if (!strncmp(emission, "float", 5))
|
||||
{
|
||||
char buf[64];
|
||||
sprintf(buf, "float %f", 0.12);
|
||||
ck_assert_str_eq(emission, buf);
|
||||
}
|
||||
else if (!strncmp(emission, "str", 3))
|
||||
ck_assert_str_eq(emission, "str hello world");
|
||||
else ck_abort_msg("Invalid emission!");
|
||||
|
||||
(*id)++;
|
||||
}
|
||||
|
||||
START_TEST(edje_test_message_send_legacy)
|
||||
{
|
||||
Evas *evas;
|
||||
Evas_Object *obj;
|
||||
Edje_Message_Int msgi;
|
||||
Edje_Message_Float msgf;
|
||||
Edje_Message_String msgs;
|
||||
Edje_Message_Int_Set *msgis;
|
||||
int id = 0;
|
||||
|
||||
/* Ugly calls to process:
|
||||
*
|
||||
* 1. Send edje message (async)
|
||||
* 2. Process edje message (sync)
|
||||
* 3. EDC program emits edje signal (async)
|
||||
* 4. Process edje signal (sync)
|
||||
* 5. Finally reached signal cb
|
||||
*/
|
||||
|
||||
evas = EDJE_TEST_INIT_EVAS();
|
||||
|
||||
obj = edje_object_add(evas);
|
||||
fail_unless(edje_object_file_set(obj, test_layout_get("test_messages.edj"), "test_group"));
|
||||
edje_object_signal_callback_add(obj, "*", "edc", _message_signal_reply_cb, &id);
|
||||
|
||||
msgs.str = "hello world";
|
||||
edje_object_message_send(obj, EDJE_MESSAGE_STRING, 0, &msgs);
|
||||
edje_message_signal_process();
|
||||
ck_assert_int_eq(id, 1);
|
||||
|
||||
msgi.val = 42;
|
||||
edje_object_message_send(obj, EDJE_MESSAGE_INT, 1, &msgi);
|
||||
edje_message_signal_process();
|
||||
ck_assert_int_eq(id, 2);
|
||||
|
||||
msgf.val = 0.12;
|
||||
edje_object_message_send(obj, EDJE_MESSAGE_FLOAT, 2, &msgf);
|
||||
edje_message_signal_process();
|
||||
ck_assert_int_eq(id, 3);
|
||||
|
||||
msgis = alloca(sizeof(*msgis) + 4 * sizeof(msgis->val));
|
||||
msgis->count = 4;
|
||||
msgis->val[0] = 7;
|
||||
msgis->val[1] = 12;
|
||||
msgis->val[2] = 42;
|
||||
msgis->val[3] = 255;
|
||||
edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 3, msgis);
|
||||
edje_message_signal_process();
|
||||
ck_assert_int_eq(id, 4);
|
||||
|
||||
evas_object_del(obj);
|
||||
|
||||
EDJE_TEST_FREE_EVAS();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(edje_test_message_send_eo)
|
||||
{
|
||||
Evas *evas;
|
||||
Evas_Object *obj;
|
||||
Eina_Value v, *va;
|
||||
int id = 0;
|
||||
|
||||
evas = EDJE_TEST_INIT_EVAS();
|
||||
|
||||
obj = efl_add(EDJE_OBJECT_CLASS, evas,
|
||||
efl_file_set(efl_added, test_layout_get("test_messages.edj"), "test_group"));
|
||||
|
||||
// FIXME: EO API HERE
|
||||
edje_object_signal_callback_add(obj, "*", "edc", _message_signal_reply_cb, &id);
|
||||
|
||||
// NOTE: edje_object_message_signal_process may or may not be in EO (TBD)
|
||||
|
||||
eina_value_setup(&v, EINA_VALUE_TYPE_STRING);
|
||||
eina_value_set(&v, "hello world");
|
||||
edje_obj_message_send(obj, 0, v);
|
||||
eina_value_flush(&v);
|
||||
edje_message_signal_process();
|
||||
edje_object_calc_force(obj);
|
||||
ck_assert_int_eq(id, 1);
|
||||
|
||||
eina_value_setup(&v, EINA_VALUE_TYPE_INT);
|
||||
eina_value_set(&v, 42);
|
||||
edje_obj_message_send(obj, 1, v);
|
||||
eina_value_flush(&v);
|
||||
edje_message_signal_process();
|
||||
edje_object_calc_force(obj);
|
||||
ck_assert_int_eq(id, 2);
|
||||
|
||||
eina_value_setup(&v, EINA_VALUE_TYPE_FLOAT);
|
||||
eina_value_set(&v, 0.12);
|
||||
edje_obj_message_send(obj, 2, v);
|
||||
eina_value_flush(&v);
|
||||
edje_message_signal_process();
|
||||
edje_object_calc_force(obj);
|
||||
ck_assert_int_eq(id, 3);
|
||||
|
||||
va = eina_value_array_new(EINA_VALUE_TYPE_INT, 4);
|
||||
eina_value_array_append(va, 7);
|
||||
eina_value_array_append(va, 12);
|
||||
eina_value_array_append(va, 42);
|
||||
eina_value_array_append(va, 255);
|
||||
edje_obj_message_send(obj, 3, *va);
|
||||
eina_value_free(va);
|
||||
edje_message_signal_process();
|
||||
edje_object_calc_force(obj);
|
||||
ck_assert_int_eq(id, 4);
|
||||
|
||||
efl_del(obj);
|
||||
|
||||
EDJE_TEST_FREE_EVAS();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void edje_test_edje(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, edje_test_edje_init);
|
||||
|
@ -746,4 +888,6 @@ void edje_test_edje(TCase *tc)
|
|||
tcase_add_test(tc, edje_test_table);
|
||||
tcase_add_test(tc, edje_test_table_eoapi);
|
||||
tcase_add_test(tc, edje_test_combine_keywords);
|
||||
tcase_add_test(tc, edje_test_message_send_legacy);
|
||||
tcase_add_test(tc, edje_test_message_send_eo);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue