forked from enlightenment/efl
Eo/evas events: Fix support of mixing legacy smart events and eo events.
This merge removes the old hash table and a few other things that were wrong in the old way of doing things. This should also make things a bit faster with legacy callbacks. @fix (no backport, as it's too intrusive)
This commit is contained in:
commit
6732ea64a9
|
@ -1108,6 +1108,12 @@ EAPI void eo_destructor(void);
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Don't use.
|
||||
* @internal
|
||||
*/
|
||||
EAPI const Eo_Event_Description *eo_base_legacy_only_event_description_get(const char *_event_name);
|
||||
|
||||
/**
|
||||
* @def EO_CALLBACK_PRIORITY_BEFORE
|
||||
* Slightly more prioritized than default.
|
||||
|
|
|
@ -409,6 +409,39 @@ _wref_destruct(Private_Data *pd)
|
|||
|
||||
/* Callbacks */
|
||||
|
||||
/* XXX: Legacy support, remove when legacy is dead. */
|
||||
static Eina_Hash *_legacy_events_hash = NULL;
|
||||
static const char *_legacy_event_desc = "Dynamically generated legacy event";
|
||||
|
||||
EAPI const Eo_Event_Description *
|
||||
eo_base_legacy_only_event_description_get(const char *_event_name)
|
||||
{
|
||||
Eina_Stringshare *event_name = eina_stringshare_add(_event_name);
|
||||
Eo_Event_Description *event_desc = eina_hash_find(_legacy_events_hash, event_name);
|
||||
if (!event_desc)
|
||||
{
|
||||
event_desc = calloc(1, sizeof(Eo_Event_Description));
|
||||
event_desc->name = event_name;
|
||||
event_desc->doc = _legacy_event_desc;
|
||||
}
|
||||
else
|
||||
{
|
||||
eina_stringshare_del(event_name);
|
||||
}
|
||||
|
||||
return event_desc;
|
||||
}
|
||||
|
||||
static void
|
||||
_legacy_events_hash_free_cb(void *_desc)
|
||||
{
|
||||
Eo_Event_Description *desc = _desc;
|
||||
eina_stringshare_del(desc->name);
|
||||
free(desc);
|
||||
}
|
||||
|
||||
/* EOF Legacy */
|
||||
|
||||
struct _Eo_Callback_Description
|
||||
{
|
||||
Eo_Callback_Description *next;
|
||||
|
@ -636,6 +669,31 @@ EAPI EO_VOID_FUNC_BODYV(eo_event_callback_array_del,
|
|||
const Eo_Callback_Array_Item *array,
|
||||
const void *user_data);
|
||||
|
||||
static Eina_Bool
|
||||
_cb_desc_match(const Eo_Event_Description *a, const Eo_Event_Description *b)
|
||||
{
|
||||
if (!a)
|
||||
return EINA_FALSE;
|
||||
|
||||
/* If either is legacy, fallback to string comparison. */
|
||||
if ((a->doc == _legacy_event_desc) || (b->doc == _legacy_event_desc))
|
||||
{
|
||||
/* Take stringshare shortcut if both are legacy */
|
||||
if (a->doc == b->doc)
|
||||
{
|
||||
return (a->name == b->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return !strcmp(a->name, b->name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return (a == b);
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ev_cb_call(Eo *obj_id, void *class_data,
|
||||
const Eo_Event_Description *desc,
|
||||
|
@ -662,7 +720,7 @@ _ev_cb_call(Eo *obj_id, void *class_data,
|
|||
|
||||
for (it = cb->items.item_array; it->func; it++)
|
||||
{
|
||||
if (it->desc != desc)
|
||||
if (!_cb_desc_match(it->desc, desc))
|
||||
continue;
|
||||
if (!it->desc->unfreezable &&
|
||||
(event_freeze_count || pd->event_freeze_count))
|
||||
|
@ -679,7 +737,7 @@ _ev_cb_call(Eo *obj_id, void *class_data,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (cb->items.item.desc != desc)
|
||||
if (!_cb_desc_match(cb->items.item.desc, desc))
|
||||
continue;
|
||||
if ((!cb->items.item.desc
|
||||
|| !cb->items.item.desc->unfreezable) &&
|
||||
|
@ -910,7 +968,6 @@ EAPI const Eina_Value_Type *EO_DBG_INFO_TYPE = &_EO_DBG_INFO_TYPE;
|
|||
|
||||
/* EOF event callbacks */
|
||||
|
||||
|
||||
/* EO_CLASS stuff */
|
||||
#define MY_CLASS EO_CLASS
|
||||
|
||||
|
@ -953,6 +1010,13 @@ static void
|
|||
_class_constructor(Eo_Class *klass EINA_UNUSED)
|
||||
{
|
||||
event_freeze_count = 0;
|
||||
_legacy_events_hash = eina_hash_stringshared_new(_legacy_events_hash_free_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
_class_destructor(Eo_Class *klass EINA_UNUSED)
|
||||
{
|
||||
eina_hash_free(_legacy_events_hash);
|
||||
}
|
||||
|
||||
static Eo_Op_Description op_descs [] = {
|
||||
|
@ -999,7 +1063,7 @@ static const Eo_Class_Description class_desc = {
|
|||
event_desc,
|
||||
sizeof(Private_Data),
|
||||
_class_constructor,
|
||||
NULL
|
||||
_class_destructor
|
||||
};
|
||||
|
||||
EO_DEFINE_CLASS(eo_base_class_get, &class_desc, NULL, NULL)
|
||||
|
|
|
@ -1,54 +1,20 @@
|
|||
#include "evas_common_private.h"
|
||||
#include "evas_private.h"
|
||||
|
||||
Eina_Hash* signals_hash_table = NULL;
|
||||
|
||||
static const Eo_Event_Description *_evas_clickable_interface_event_desc[];
|
||||
static const Eo_Event_Description *_evas_draggable_interface_event_desc[];
|
||||
static const Eo_Event_Description *_evas_scrollable_interface_event_desc[];
|
||||
static const Eo_Event_Description *_evas_selectable_interface_event_desc[];
|
||||
static const Eo_Event_Description *_evas_zoomable_interface_event_desc[];
|
||||
|
||||
#define ADD_SIGNAL(name, event) eina_hash_add(signals_hash_table, name, event)
|
||||
#define ADD_INTERFACE_SIGNALS(events_desc) \
|
||||
do \
|
||||
{ \
|
||||
int i = 0; \
|
||||
while (events_desc[i]) { \
|
||||
_Evas_Event_Description *desc = calloc(1, sizeof(*desc)); \
|
||||
desc->eo_desc = (Eo_Event_Description *)events_desc[i]; \
|
||||
desc->is_desc_allocated = EINA_FALSE; \
|
||||
ADD_SIGNAL(events_desc[i]->name, desc); \
|
||||
i++; \
|
||||
} \
|
||||
} \
|
||||
while (0);
|
||||
|
||||
static void
|
||||
_signal_interface_del(void *data)
|
||||
{
|
||||
_Evas_Event_Description *desc = data;
|
||||
if (desc->is_desc_allocated) free(desc->eo_desc);
|
||||
free(desc);
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_signal_interface_class_constructor(Eo_Class *klass EINA_UNUSED)
|
||||
{
|
||||
signals_hash_table = eina_hash_string_superfast_new(_signal_interface_del);
|
||||
ADD_INTERFACE_SIGNALS(_evas_clickable_interface_event_desc);
|
||||
ADD_INTERFACE_SIGNALS(_evas_scrollable_interface_event_desc);
|
||||
ADD_INTERFACE_SIGNALS(_evas_zoomable_interface_event_desc);
|
||||
ADD_INTERFACE_SIGNALS(_evas_selectable_interface_event_desc);
|
||||
ADD_INTERFACE_SIGNALS(_evas_draggable_interface_event_desc);
|
||||
}
|
||||
#undef ADD_INTERFACE_SIGNALS
|
||||
#undef ADD_SIGNAL
|
||||
|
||||
static void
|
||||
_evas_signal_interface_class_destructor(Eo_Class *klass EINA_UNUSED)
|
||||
{
|
||||
eina_hash_free(signals_hash_table);
|
||||
}
|
||||
|
||||
#include "canvas/evas_signal_interface.eo.c"
|
||||
|
|
|
@ -45,7 +45,7 @@ typedef struct
|
|||
EINA_INLIST;
|
||||
Evas_Smart_Cb func;
|
||||
void *data;
|
||||
_Evas_Event_Description *desc;
|
||||
const Eo_Event_Description *event;
|
||||
} _eo_evas_smart_cb_info;
|
||||
|
||||
|
||||
|
@ -699,25 +699,16 @@ evas_object_smart_callback_priority_add(Evas_Object *eo_obj, const char *event,
|
|||
if (!event) return;
|
||||
if (!func) return;
|
||||
|
||||
_Evas_Event_Description *event_desc = eina_hash_find(signals_hash_table, event);
|
||||
if (!event_desc)
|
||||
{
|
||||
event_desc = calloc (1, sizeof(*event_desc));
|
||||
event_desc->eo_desc = calloc(1, sizeof(Eo_Event_Description));
|
||||
event_desc->eo_desc->name = eina_stringshare_add(event);
|
||||
event_desc->eo_desc->doc = "";
|
||||
event_desc->is_desc_allocated = EINA_TRUE;
|
||||
eina_hash_add(signals_hash_table, event, event_desc);
|
||||
}
|
||||
const Eo_Event_Description *eo_desc = eo_base_legacy_only_event_description_get(event);
|
||||
_eo_evas_smart_cb_info *cb_info = calloc(1, sizeof(*cb_info));
|
||||
cb_info->func = func;
|
||||
cb_info->data = (void *)data;
|
||||
cb_info->desc = event_desc;
|
||||
cb_info->event = eo_desc;
|
||||
|
||||
o->callbacks = eina_inlist_append(o->callbacks,
|
||||
EINA_INLIST_GET(cb_info));
|
||||
|
||||
eo_do(eo_obj, eo_event_callback_priority_add(event_desc->eo_desc, priority, _eo_evas_smart_cb, cb_info));
|
||||
eo_do(eo_obj, eo_event_callback_priority_add(eo_desc, priority, _eo_evas_smart_cb, cb_info));
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
|
@ -732,16 +723,15 @@ evas_object_smart_callback_del(Evas_Object *eo_obj, const char *event, Evas_Smar
|
|||
o = eo_data_scope_get(eo_obj, MY_CLASS);
|
||||
|
||||
if (!event) return NULL;
|
||||
const _Evas_Event_Description *event_desc = eina_hash_find(signals_hash_table, event);
|
||||
if (!event_desc) return NULL;
|
||||
const Eo_Event_Description *eo_desc = eo_base_legacy_only_event_description_get(event);
|
||||
|
||||
EINA_INLIST_FOREACH(o->callbacks, info)
|
||||
{
|
||||
if ((info->func == func) && (info->desc == event_desc))
|
||||
if ((info->func == func) && (info->event == eo_desc))
|
||||
{
|
||||
void *tmp = info->data;
|
||||
eo_do(eo_obj, eo_event_callback_del(
|
||||
event_desc->eo_desc, _eo_evas_smart_cb, info));
|
||||
eo_desc, _eo_evas_smart_cb, info));
|
||||
|
||||
o->callbacks =
|
||||
eina_inlist_remove(o->callbacks, EINA_INLIST_GET(info));
|
||||
|
@ -765,16 +755,15 @@ evas_object_smart_callback_del_full(Evas_Object *eo_obj, const char *event, Evas
|
|||
o = eo_data_scope_get(eo_obj, MY_CLASS);
|
||||
if (!o) return NULL;
|
||||
|
||||
const _Evas_Event_Description *event_desc = eina_hash_find(signals_hash_table, event);
|
||||
if (!event_desc) return NULL;
|
||||
const Eo_Event_Description *eo_desc = eo_base_legacy_only_event_description_get(event);
|
||||
|
||||
EINA_INLIST_FOREACH(o->callbacks, info)
|
||||
{
|
||||
if ((info->func == func) && (info->desc == event_desc) && (info->data == data))
|
||||
if ((info->func == func) && (info->event == eo_desc) && (info->data == data))
|
||||
{
|
||||
void *tmp = info->data;
|
||||
eo_do(eo_obj, eo_event_callback_del(
|
||||
event_desc->eo_desc, _eo_evas_smart_cb, info));
|
||||
eo_desc, _eo_evas_smart_cb, info));
|
||||
|
||||
o->callbacks =
|
||||
eina_inlist_remove(o->callbacks, EINA_INLIST_GET(info));
|
||||
|
@ -793,9 +782,8 @@ evas_object_smart_callback_call(Evas_Object *eo_obj, const char *event, void *ev
|
|||
MAGIC_CHECK_END();
|
||||
|
||||
if (!event) return;
|
||||
const _Evas_Event_Description *event_desc = eina_hash_find(signals_hash_table, event);
|
||||
if (event_desc)
|
||||
eo_do(eo_obj, eo_event_callback_call(event_desc->eo_desc, event_info));
|
||||
const Eo_Event_Description *eo_desc = eo_base_legacy_only_event_description_get(event);
|
||||
eo_do(eo_obj, eo_event_callback_call(eo_desc, event_info));
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
|
@ -1214,7 +1202,7 @@ evas_object_smart_cleanup(Evas_Object *eo_obj)
|
|||
{
|
||||
_eo_evas_smart_cb_info *info = (_eo_evas_smart_cb_info *)o->callbacks;
|
||||
eo_do(eo_obj, eo_event_callback_del(
|
||||
info->desc->eo_desc, _eo_evas_smart_cb, info));
|
||||
info->event, _eo_evas_smart_cb, info));
|
||||
o->callbacks = eina_inlist_remove(o->callbacks, EINA_INLIST_GET(info));
|
||||
free(info);
|
||||
}
|
||||
|
|
|
@ -1208,13 +1208,6 @@ struct _Evas_Image_Save_Func
|
|||
int (*image_save) (RGBA_Image *im, const char *file, const char *key, int quality, int compress);
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Eo_Event_Description *eo_desc;
|
||||
Eina_Bool is_desc_allocated : 1;
|
||||
} _Evas_Event_Description;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -38,15 +38,15 @@ START_TEST(eo_stack)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
static int _eo_signals_cb_curent = 0;
|
||||
static int _eo_signals_cb_current = 0;
|
||||
static int _eo_signals_cb_flag = 0;
|
||||
|
||||
static Eina_Bool
|
||||
_eo_signals_a_changed_cb(void *_data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
int data = (intptr_t) _data;
|
||||
_eo_signals_cb_curent++;
|
||||
ck_assert_int_eq(data, _eo_signals_cb_curent);
|
||||
_eo_signals_cb_current++;
|
||||
ck_assert_int_eq(data, _eo_signals_cb_current);
|
||||
_eo_signals_cb_flag |= 0x1;
|
||||
return EO_CALLBACK_CONTINUE;
|
||||
}
|
||||
|
@ -115,6 +115,34 @@ START_TEST(eo_signals)
|
|||
|
||||
eo_unref(obj);
|
||||
|
||||
obj = eo_add(SIMPLE_CLASS, NULL);
|
||||
/* Legacy support signals. */
|
||||
{
|
||||
const Eo_Event_Description *a_desc = eo_base_legacy_only_event_description_get("a,changed");
|
||||
fail_if(!a_desc);
|
||||
ck_assert_str_eq(a_desc->name, "a,changed");
|
||||
fail_if(a_desc == EV_A_CHANGED);
|
||||
|
||||
const Eo_Event_Description *bad_desc = eo_base_legacy_only_event_description_get("bad");
|
||||
fail_if(!bad_desc);
|
||||
ck_assert_str_eq(bad_desc->name, "bad");
|
||||
|
||||
/* Call Eo event with legacy and non-legacy callbacks. */
|
||||
_eo_signals_cb_current = 0;
|
||||
eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, -100, _eo_signals_a_changed_cb, (void *) 1));
|
||||
eo_do(obj, eo_event_callback_add(a_desc, _eo_signals_a_changed_cb2, NULL));
|
||||
eo_do(obj, simple_a_set(1));
|
||||
ck_assert_int_eq(_eo_signals_cb_flag, 0x3);
|
||||
|
||||
/* Call legacy event with legacy and non-legacy callbacks. */
|
||||
int a = 3;
|
||||
_eo_signals_cb_current = 0;
|
||||
_eo_signals_cb_flag = 0;
|
||||
eo_do(obj, eo_event_callback_call(a_desc, &a));
|
||||
ck_assert_int_eq(_eo_signals_cb_flag, 0x3);
|
||||
}
|
||||
eo_unref(obj);
|
||||
|
||||
eo_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
|
Loading…
Reference in New Issue