forked from enlightenment/efl
edje: reduce memory usage of Edje signal callbacks and automates.
This patch try to share signal callbacks and automate accross all Edje object. It does use an Eina_Hash on the callback description (signal, source, func). There is no need to check it against Edje file or group only the callbacks matter. This version remove all use of size_t as it should never be above 32bits. We have a hard limit on the number of callback to 2^32 now. I am considering it would be sane to make it a short.
This commit is contained in:
parent
c78f4d7bfa
commit
488ea9ec82
|
@ -46,7 +46,8 @@ lib/edje/edje_smart.c \
|
|||
lib/edje/edje_text.c \
|
||||
lib/edje/edje_textblock_styles.c \
|
||||
lib/edje/edje_util.c \
|
||||
lib/edje/edje_var.c
|
||||
lib/edje/edje_var.c \
|
||||
lib/edje/edje_signal.c
|
||||
|
||||
lib_edje_libedje_la_CPPFLAGS = $(EDJE_COMMON_CPPFLAGS)
|
||||
lib_edje_libedje_la_LIBADD = @EDJE_LIBS@
|
||||
|
|
|
@ -893,7 +893,6 @@ enum
|
|||
|
||||
EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD,
|
||||
EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL,
|
||||
EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL_FULL,
|
||||
EDJE_OBJ_SUB_ID_SIGNAL_EMIT,
|
||||
EDJE_OBJ_SUB_ID_PLAY_SET,
|
||||
EDJE_OBJ_SUB_ID_PLAY_GET,
|
||||
|
@ -2709,23 +2708,7 @@ enum
|
|||
*
|
||||
* @see edje_object_signal_callback_del
|
||||
*/
|
||||
#define edje_obj_signal_callback_del(emission, source, func, ret) EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL), EO_TYPECHECK(const char *, emission), EO_TYPECHECK(const char *, source), EO_TYPECHECK(Edje_Signal_Cb, func), EO_TYPECHECK(void **, ret)
|
||||
|
||||
/**
|
||||
* @def edje_obj_signal_callback_del_full
|
||||
* @since 1.8
|
||||
*
|
||||
* @brief Unregister/delete a callback set for an arriving Edje
|
||||
*
|
||||
* @param[in] emission
|
||||
* @param[in] source
|
||||
* @param[in] func
|
||||
* @param[in] data
|
||||
* @param[out] ret
|
||||
*
|
||||
* @see edje_object_signal_callback_del_full
|
||||
*/
|
||||
#define edje_obj_signal_callback_del_full(emission, source, func, data, ret) EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL_FULL), EO_TYPECHECK(const char *, emission), EO_TYPECHECK(const char *, source), EO_TYPECHECK(Edje_Signal_Cb, func), EO_TYPECHECK(void *, data), EO_TYPECHECK(void **, ret)
|
||||
#define edje_obj_signal_callback_del(emission, source, func, data, ret) EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL), EO_TYPECHECK(const char *, emission), EO_TYPECHECK(const char *, source), EO_TYPECHECK(Edje_Signal_Cb, func), EO_TYPECHECK(void *, data), EO_TYPECHECK(void **, ret)
|
||||
|
||||
/**
|
||||
* @def edje_obj_signal_emit
|
||||
|
|
|
@ -78,6 +78,7 @@ edje_init(void)
|
|||
_edje_module_init();
|
||||
_edje_message_init();
|
||||
_edje_multisense_init();
|
||||
edje_signal_init();
|
||||
|
||||
_edje_real_part_mp = eina_mempool_add("chained_mempool",
|
||||
"Edje_Real_Part", NULL,
|
||||
|
@ -147,6 +148,7 @@ _edje_shutdown_core(void)
|
|||
_edje_real_part_state_mp = NULL;
|
||||
_edje_real_part_mp = NULL;
|
||||
|
||||
edje_signal_shutdown();
|
||||
_edje_multisense_shutdown();
|
||||
_edje_message_shutdown();
|
||||
_edje_module_shutdown();
|
||||
|
@ -242,7 +244,6 @@ _edje_del(Edje *ed)
|
|||
{
|
||||
Edje_Running_Program *runp;
|
||||
Edje_Pending_Program *pp;
|
||||
Edje_Signal_Callback *escb;
|
||||
Edje_Text_Class *tc;
|
||||
Edje_Text_Insert_Filter_Callback *cb;
|
||||
|
||||
|
@ -252,7 +253,7 @@ _edje_del(Edje *ed)
|
|||
return;
|
||||
}
|
||||
_edje_message_del(ed);
|
||||
_edje_callbacks_patterns_clean(ed);
|
||||
_edje_signal_callback_free(ed->callbacks);
|
||||
_edje_file_del(ed);
|
||||
if (ed->path) eina_stringshare_del(ed->path);
|
||||
if (ed->group) eina_stringshare_del(ed->group);
|
||||
|
@ -267,12 +268,6 @@ _edje_del(Edje *ed)
|
|||
free(runp);
|
||||
EINA_LIST_FREE(ed->pending_actions, pp)
|
||||
free(pp);
|
||||
EINA_LIST_FREE(ed->callbacks, escb)
|
||||
{
|
||||
if (escb->signal) eina_stringshare_del(escb->signal);
|
||||
if (escb->source) eina_stringshare_del(escb->source);
|
||||
free(escb);
|
||||
}
|
||||
eina_hash_free(ed->color_classes);
|
||||
EINA_LIST_FREE(ed->text_classes, tc)
|
||||
{
|
||||
|
|
|
@ -5,20 +5,20 @@
|
|||
typedef struct _Edje_State Edje_State;
|
||||
struct _Edje_State
|
||||
{
|
||||
size_t idx;
|
||||
size_t pos;
|
||||
unsigned int idx;
|
||||
unsigned int pos;
|
||||
};
|
||||
|
||||
struct _Edje_States
|
||||
{
|
||||
size_t size;
|
||||
unsigned int size;
|
||||
Edje_State *states;
|
||||
Eina_Bool *has;
|
||||
};
|
||||
|
||||
static void
|
||||
_edje_match_states_free(Edje_States *states,
|
||||
size_t states_size)
|
||||
_edje_match_states_free(Edje_States *states,
|
||||
unsigned int states_size)
|
||||
{
|
||||
(void) states_size;
|
||||
free(states);
|
||||
|
@ -36,15 +36,15 @@ _edje_match_states_alloc(Edje_Patterns *ppat, int n)
|
|||
{
|
||||
Edje_States *l;
|
||||
|
||||
const size_t patterns_size = ppat->patterns_size;
|
||||
const size_t patterns_max_length = ppat->max_length;
|
||||
const unsigned int patterns_size = ppat->patterns_size;
|
||||
const unsigned int patterns_max_length = ppat->max_length;
|
||||
|
||||
const size_t array_len = (patterns_max_length + 1) * patterns_size;
|
||||
const unsigned int array_len = (patterns_max_length + 1) * patterns_size;
|
||||
|
||||
size_t states_size;
|
||||
size_t has_size;
|
||||
size_t states_has_size;
|
||||
size_t struct_size;
|
||||
unsigned int states_size;
|
||||
unsigned int has_size;
|
||||
unsigned int states_has_size;
|
||||
unsigned int struct_size;
|
||||
|
||||
unsigned char *states;
|
||||
unsigned char *has;
|
||||
|
@ -88,12 +88,12 @@ _edje_match_states_alloc(Edje_Patterns *ppat, int n)
|
|||
}
|
||||
|
||||
static void
|
||||
_edje_match_states_insert(Edje_States *list,
|
||||
size_t patterns_max_length,
|
||||
size_t idx,
|
||||
size_t pos)
|
||||
_edje_match_states_insert(Edje_States *list,
|
||||
unsigned int patterns_max_length,
|
||||
unsigned int idx,
|
||||
unsigned int pos)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int i;
|
||||
|
||||
i = (idx * (patterns_max_length + 1)) + pos;
|
||||
|
||||
|
@ -112,8 +112,8 @@ _edje_match_states_insert(Edje_States *list,
|
|||
|
||||
static void
|
||||
_edje_match_states_clear(Edje_States *list,
|
||||
EINA_UNUSED size_t patterns_size,
|
||||
EINA_UNUSED size_t patterns_max_length)
|
||||
EINA_UNUSED unsigned int patterns_size,
|
||||
EINA_UNUSED unsigned int patterns_max_length)
|
||||
{
|
||||
list->size = 0;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ enum status
|
|||
patterns_syntax_error = 2
|
||||
};
|
||||
|
||||
static size_t
|
||||
static unsigned int
|
||||
_edje_match_patterns_exec_class_token(enum status *status,
|
||||
const char *cl_tok,
|
||||
char c)
|
||||
|
@ -152,7 +152,7 @@ _edje_match_patterns_exec_class_token(enum status *status,
|
|||
}
|
||||
|
||||
static Edje_Match_Error
|
||||
_edje_match_patterns_exec_class_complement(const char *cl_tok, size_t *ret)
|
||||
_edje_match_patterns_exec_class_complement(const char *cl_tok, unsigned int *ret)
|
||||
{
|
||||
switch (*cl_tok)
|
||||
{
|
||||
|
@ -170,13 +170,13 @@ _edje_match_patterns_exec_class_complement(const char *cl_tok, size_t *ret)
|
|||
}
|
||||
|
||||
static Edje_Match_Error
|
||||
_edje_match_patterns_exec_class(const char *cl,
|
||||
char c,
|
||||
size_t *ret)
|
||||
_edje_match_patterns_exec_class(const char *cl,
|
||||
char c,
|
||||
unsigned int *ret)
|
||||
{
|
||||
enum status status = patterns_not_found;
|
||||
int pos = 1;
|
||||
size_t neg;
|
||||
enum status status = patterns_not_found;
|
||||
int pos = 1;
|
||||
size_t neg;
|
||||
|
||||
if (_edje_match_patterns_exec_class_complement(cl + 1, &neg) != EDJE_MATCH_OK)
|
||||
return EDJE_MATCH_SYNTAX_ERROR;
|
||||
|
@ -201,9 +201,9 @@ _edje_match_patterns_exec_class(const char *cl,
|
|||
}
|
||||
|
||||
static Edje_Match_Error
|
||||
_edje_match_patterns_exec_token(const char *tok,
|
||||
char c,
|
||||
size_t *ret)
|
||||
_edje_match_patterns_exec_token(const char *tok,
|
||||
char c,
|
||||
unsigned int *ret)
|
||||
{
|
||||
switch (*tok)
|
||||
{
|
||||
|
@ -229,11 +229,11 @@ _edje_match_patterns_exec_token(const char *tok,
|
|||
}
|
||||
|
||||
static void
|
||||
_edje_match_patterns_exec_init_states(Edje_States *states,
|
||||
size_t patterns_size,
|
||||
size_t patterns_max_length)
|
||||
_edje_match_patterns_exec_init_states(Edje_States *states,
|
||||
unsigned int patterns_size,
|
||||
unsigned int patterns_max_length)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int i;
|
||||
|
||||
states->size = patterns_size;
|
||||
|
||||
|
@ -251,8 +251,8 @@ _edje_match_patterns_exec_init_states(Edje_States *states,
|
|||
Edje_Patterns* \
|
||||
Func(const Eina_List *lst) \
|
||||
{ \
|
||||
Edje_Patterns *r; \
|
||||
size_t i; \
|
||||
Edje_Patterns *r; \
|
||||
unsigned int i; \
|
||||
\
|
||||
if (!lst || eina_list_count(lst) <= 0) \
|
||||
return NULL; \
|
||||
|
@ -273,7 +273,7 @@ _edje_match_patterns_exec_init_states(Edje_States *states,
|
|||
{ \
|
||||
const char *str; \
|
||||
Type *data; \
|
||||
size_t j; \
|
||||
unsigned int j; \
|
||||
int special = 0; \
|
||||
\
|
||||
data = eina_list_data_get(lst); \
|
||||
|
@ -318,8 +318,8 @@ _edje_match_patterns_exec_init_states(Edje_States *states,
|
|||
Edje_Patterns* \
|
||||
Func(Type * const *lst, unsigned int count) \
|
||||
{ \
|
||||
Edje_Patterns *r; \
|
||||
size_t i; \
|
||||
Edje_Patterns *r; \
|
||||
unsigned int i; \
|
||||
\
|
||||
if (!lst || count == 0) \
|
||||
return NULL; \
|
||||
|
@ -339,7 +339,7 @@ _edje_match_patterns_exec_init_states(Edje_States *states,
|
|||
for (i = 0; i < count; ++i) \
|
||||
{ \
|
||||
const char *str; \
|
||||
size_t j; \
|
||||
unsigned int j; \
|
||||
int special = 0; \
|
||||
\
|
||||
if (!lst[i]) \
|
||||
|
@ -377,6 +377,66 @@ _edje_match_patterns_exec_init_states(Edje_States *states,
|
|||
return r; \
|
||||
}
|
||||
|
||||
#define EDJE_MATCH_INIT_INARRAY(Func, Source, Show) \
|
||||
Edje_Patterns* \
|
||||
Func(const Eina_Inarray *array, const Edje_Signal_Callback_Match *matches) \
|
||||
{ \
|
||||
Edje_Patterns *r; \
|
||||
int *it; \
|
||||
unsigned int i = 0; \
|
||||
\
|
||||
if (!matches) \
|
||||
return NULL; \
|
||||
\
|
||||
r = malloc(sizeof (Edje_Patterns) + \
|
||||
eina_inarray_count(array) \
|
||||
* sizeof(*r->finals) \
|
||||
* sizeof(*r->patterns)); \
|
||||
if (!r) return NULL; \
|
||||
\
|
||||
r->ref = 1; \
|
||||
r->delete_me = EINA_FALSE; \
|
||||
r->patterns_size = eina_inarray_count(array); \
|
||||
r->max_length = 0; \
|
||||
r->patterns = (const char **) r->finals + r->patterns_size + 1; \
|
||||
\
|
||||
EINA_INARRAY_FOREACH(array, it) \
|
||||
{ \
|
||||
const char *str; \
|
||||
unsigned int j; \
|
||||
int special = 0; \
|
||||
\
|
||||
str = (matches + *it)->Source; \
|
||||
if (!str) str = ""; \
|
||||
r->patterns[i] = str; \
|
||||
\
|
||||
if (Show) \
|
||||
INF("%lu [%s]", (unsigned long)i, str); \
|
||||
\
|
||||
r->finals[i] = 0; \
|
||||
for (j = 0; str[j]; ++j) \
|
||||
if (str[j] != '*') \
|
||||
{ \
|
||||
r->finals[i] = j + 1; \
|
||||
special++; \
|
||||
} \
|
||||
j += special ? special + 1 : 0; \
|
||||
\
|
||||
if (j > r->max_length) \
|
||||
r->max_length = j; \
|
||||
\
|
||||
i++; \
|
||||
} \
|
||||
\
|
||||
if (!_edje_match_states_alloc(r, 2)) \
|
||||
{ \
|
||||
free(r); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
return r; \
|
||||
}
|
||||
|
||||
EDJE_MATCH_INIT_LIST(edje_match_collection_dir_init,
|
||||
Edje_Part_Collection_Directory_Entry,
|
||||
entry, 0);
|
||||
|
@ -386,18 +446,16 @@ EDJE_MATCH_INIT_ARRAY(edje_match_programs_signal_init,
|
|||
EDJE_MATCH_INIT_ARRAY(edje_match_programs_source_init,
|
||||
Edje_Program,
|
||||
source, 0);
|
||||
EDJE_MATCH_INIT_LIST(edje_match_callback_signal_init,
|
||||
Edje_Signal_Callback,
|
||||
signal, 0);
|
||||
EDJE_MATCH_INIT_LIST(edje_match_callback_source_init,
|
||||
Edje_Signal_Callback,
|
||||
source, 0);
|
||||
EDJE_MATCH_INIT_INARRAY(edje_match_callback_signal_init,
|
||||
signal, 0);
|
||||
EDJE_MATCH_INIT_INARRAY(edje_match_callback_source_init,
|
||||
source, 0);
|
||||
|
||||
static Eina_Bool
|
||||
_edje_match_collection_dir_exec_finals(const size_t *finals,
|
||||
const Edje_States *states)
|
||||
_edje_match_collection_dir_exec_finals(const unsigned int *finals,
|
||||
const Edje_States *states)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < states->size; ++i)
|
||||
{
|
||||
|
@ -408,17 +466,17 @@ _edje_match_collection_dir_exec_finals(const size_t *finals,
|
|||
}
|
||||
|
||||
static Eina_Bool
|
||||
edje_match_programs_exec_check_finals(const size_t *signal_finals,
|
||||
const size_t *source_finals,
|
||||
const Edje_States *signal_states,
|
||||
const Edje_States *source_states,
|
||||
Edje_Program **programs,
|
||||
edje_match_programs_exec_check_finals(const unsigned int *signal_finals,
|
||||
const unsigned int *source_finals,
|
||||
const Edje_States *signal_states,
|
||||
const Edje_States *source_states,
|
||||
Edje_Program **programs,
|
||||
Eina_Bool (*func)(Edje_Program *pr, void *data),
|
||||
void *data,
|
||||
Eina_Bool prop EINA_UNUSED)
|
||||
void *data,
|
||||
Eina_Bool prop EINA_UNUSED)
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
/* when not enought memory, they could be NULL */
|
||||
if (!signal_finals || !source_finals) return EINA_TRUE;
|
||||
|
@ -449,61 +507,59 @@ edje_match_programs_exec_check_finals(const size_t *signal_finals,
|
|||
}
|
||||
|
||||
static int
|
||||
edje_match_callback_exec_check_finals(const Edje_Patterns *signal_ppat,
|
||||
const Edje_Patterns *source_ppat,
|
||||
const size_t *signal_finals,
|
||||
const size_t *source_finals,
|
||||
edje_match_callback_exec_check_finals(const Edje_Signals_Sources_Patterns *ssp,
|
||||
const Edje_Signal_Callback_Match *matches,
|
||||
const void **custom_data,
|
||||
const Eina_Bool *flags,
|
||||
const Edje_States *signal_states,
|
||||
const Edje_States *source_states,
|
||||
const char *sig,
|
||||
const char *source,
|
||||
Eina_List *callbacks,
|
||||
Edje *ed,
|
||||
Eina_Bool prop
|
||||
)
|
||||
Eina_Bool prop)
|
||||
{
|
||||
Edje_Signal_Callback *escb;
|
||||
const Edje_Signal_Callback_Match *cb;
|
||||
Eina_Array run;
|
||||
size_t i;
|
||||
size_t j;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
int r = 1;
|
||||
|
||||
eina_array_step_set(&run, sizeof (Eina_Array), 4);
|
||||
|
||||
for (i = 0; i < signal_states->size; ++i)
|
||||
{
|
||||
if (signal_states->states[i].pos >= signal_finals[signal_states->states[i].idx])
|
||||
{
|
||||
for (j = 0; j < source_states->size; ++j)
|
||||
{
|
||||
if (signal_states->states[i].idx == source_states->states[j].idx
|
||||
&& source_states->states[j].pos >= source_finals[source_states->states[j].idx])
|
||||
{
|
||||
escb = eina_list_nth(callbacks, signal_states->states[i].idx);
|
||||
if (escb)
|
||||
{
|
||||
if ((prop) && (escb->propagate)) continue;
|
||||
if ((!escb->just_added)
|
||||
&& (!escb->delete_me))
|
||||
{
|
||||
eina_array_push(&run, escb);
|
||||
r = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (signal_states->states[i].pos >= ssp->signals_patterns->finals[signal_states->states[i].idx])
|
||||
{
|
||||
for (j = 0; j < source_states->size; ++j)
|
||||
{
|
||||
if (signal_states->states[i].idx == source_states->states[j].idx
|
||||
&& source_states->states[j].pos >= ssp->sources_patterns->finals[source_states->states[j].idx])
|
||||
{
|
||||
int *e;
|
||||
|
||||
while ((escb = eina_array_pop(&run)))
|
||||
e = eina_inarray_nth(&ssp->u.callbacks.globing, signal_states->states[i].idx);
|
||||
|
||||
cb = &matches[*e];
|
||||
if (cb)
|
||||
{
|
||||
if ((prop) && _edje_signal_callback_prop(flags, *e)) continue;
|
||||
eina_array_push(&run, cb);
|
||||
r = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((cb = eina_array_pop(&run)))
|
||||
{
|
||||
escb->func(escb->data, ed->obj, sig, source);
|
||||
int idx = cb - matches;
|
||||
|
||||
cb->func((void*) custom_data[idx], ed->obj, sig, source);
|
||||
if (_edje_block_break(ed))
|
||||
{
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
if ((signal_ppat->delete_me) || (source_ppat->delete_me))
|
||||
if ((ssp->signals_patterns->delete_me) || (ssp->sources_patterns->delete_me))
|
||||
{
|
||||
r = 0;
|
||||
break;
|
||||
|
@ -526,14 +582,14 @@ _edje_match_fn(const Edje_Patterns *ppat,
|
|||
|
||||
for (c = string; *c && states->size; ++c)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int i;
|
||||
|
||||
_edje_match_states_clear(new_states, ppat->patterns_size, ppat->max_length);
|
||||
|
||||
for (i = 0; i < states->size; ++i)
|
||||
{
|
||||
const size_t idx = states->states[i].idx;
|
||||
const size_t pos = states->states[i].pos;
|
||||
const unsigned int idx = states->states[i].idx;
|
||||
const unsigned int pos = states->states[i].pos;
|
||||
|
||||
if (!ppat->patterns[idx][pos])
|
||||
continue;
|
||||
|
@ -544,7 +600,7 @@ _edje_match_fn(const Edje_Patterns *ppat,
|
|||
}
|
||||
else
|
||||
{
|
||||
size_t m;
|
||||
unsigned int m;
|
||||
|
||||
if (_edje_match_patterns_exec_token(ppat->patterns[idx] + pos,
|
||||
*c,
|
||||
|
@ -626,50 +682,49 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal,
|
|||
}
|
||||
|
||||
int
|
||||
edje_match_callback_exec(Edje_Patterns *ppat_signal,
|
||||
Edje_Patterns *ppat_source,
|
||||
const char *sig,
|
||||
const char *source,
|
||||
Eina_List *callbacks,
|
||||
Edje *ed,
|
||||
Eina_Bool prop
|
||||
)
|
||||
edje_match_callback_exec(const Edje_Signals_Sources_Patterns *ssp,
|
||||
const Edje_Signal_Callback_Match *matches,
|
||||
const void **custom_data,
|
||||
const Eina_Bool *flags,
|
||||
const char *sig,
|
||||
const char *source,
|
||||
Edje *ed,
|
||||
Eina_Bool prop)
|
||||
{
|
||||
Edje_States *signal_result;
|
||||
Edje_States *source_result;
|
||||
int r = 0;
|
||||
|
||||
/* under high memory presure, they could be NULL */
|
||||
if (!ppat_source || !ppat_signal) return 0;
|
||||
if (!ssp->sources_patterns || !ssp->signals_patterns) return 0;
|
||||
|
||||
ppat_signal->ref++;
|
||||
ppat_source->ref++;
|
||||
_edje_match_patterns_exec_init_states(ppat_signal->states,
|
||||
ppat_signal->patterns_size,
|
||||
ppat_signal->max_length);
|
||||
_edje_match_patterns_exec_init_states(ppat_source->states,
|
||||
ppat_source->patterns_size,
|
||||
ppat_source->max_length);
|
||||
ssp->signals_patterns->ref++;
|
||||
ssp->sources_patterns->ref++;
|
||||
_edje_match_patterns_exec_init_states(ssp->signals_patterns->states,
|
||||
ssp->signals_patterns->patterns_size,
|
||||
ssp->signals_patterns->max_length);
|
||||
_edje_match_patterns_exec_init_states(ssp->sources_patterns->states,
|
||||
ssp->sources_patterns->patterns_size,
|
||||
ssp->sources_patterns->max_length);
|
||||
|
||||
signal_result = _edje_match_fn(ppat_signal, sig, ppat_signal->states);
|
||||
source_result = _edje_match_fn(ppat_source, source, ppat_source->states);
|
||||
signal_result = _edje_match_fn(ssp->signals_patterns, sig, ssp->signals_patterns->states);
|
||||
source_result = _edje_match_fn(ssp->sources_patterns, source, ssp->sources_patterns->states);
|
||||
|
||||
if (signal_result && source_result)
|
||||
r = edje_match_callback_exec_check_finals(ppat_signal,
|
||||
ppat_source,
|
||||
ppat_signal->finals,
|
||||
ppat_source->finals,
|
||||
signal_result,
|
||||
source_result,
|
||||
sig,
|
||||
source,
|
||||
callbacks,
|
||||
ed,
|
||||
prop);
|
||||
ppat_signal->ref--;
|
||||
ppat_source->ref--;
|
||||
if (ppat_signal->ref <= 0) edje_match_patterns_free(ppat_signal);
|
||||
if (ppat_source->ref <= 0) edje_match_patterns_free(ppat_source);
|
||||
r = edje_match_callback_exec_check_finals(ssp,
|
||||
matches,
|
||||
custom_data,
|
||||
flags,
|
||||
signal_result,
|
||||
source_result,
|
||||
sig,
|
||||
source,
|
||||
ed,
|
||||
prop);
|
||||
ssp->signals_patterns->ref--;
|
||||
ssp->sources_patterns->ref--;
|
||||
if (ssp->signals_patterns->ref <= 0) edje_match_patterns_free(ssp->signals_patterns);
|
||||
if (ssp->sources_patterns->ref <= 0) edje_match_patterns_free(ssp->sources_patterns);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -750,13 +805,13 @@ edje_match_program_hash_build(Edje_Program * const *programs,
|
|||
|
||||
item->signal = programs[i]->signal;
|
||||
item->source = programs[i]->source;
|
||||
eina_array_step_set(&item->list, sizeof (Eina_Array), 8);
|
||||
eina_inarray_step_set(&item->list, sizeof (Eina_Inarray), sizeof (void*), 8);
|
||||
|
||||
new = eina_rbtree_inline_insert(new, EINA_RBTREE_GET(item),
|
||||
EINA_RBTREE_CMP_NODE_CB(_edje_signal_source_node_cmp), NULL);
|
||||
}
|
||||
|
||||
eina_array_push(&item->list, programs[i]);
|
||||
eina_inarray_push(&item->list, &programs[i]);
|
||||
}
|
||||
else
|
||||
result = eina_list_prepend(result, programs[i]);
|
||||
|
@ -766,48 +821,51 @@ edje_match_program_hash_build(Edje_Program * const *programs,
|
|||
return result;
|
||||
}
|
||||
|
||||
Eina_List *
|
||||
edje_match_callback_hash_build(const Eina_List *callbacks,
|
||||
Eina_Rbtree **tree)
|
||||
void
|
||||
edje_match_callback_hash_build(const Edje_Signal_Callback_Match *callbacks,
|
||||
int callbacks_count,
|
||||
Eina_Rbtree **tree,
|
||||
Eina_Inarray *result)
|
||||
{
|
||||
Eina_List *result = NULL;
|
||||
Eina_Rbtree *new = NULL;
|
||||
Edje_Signal_Callback *callback;
|
||||
const Eina_List *l;
|
||||
int i;
|
||||
|
||||
EINA_LIST_FOREACH(callbacks, l, callback)
|
||||
eina_inarray_step_set(result, sizeof (Eina_Inarray), sizeof (int), 8);
|
||||
|
||||
for (i = 0; i < callbacks_count; ++i, ++callbacks)
|
||||
{
|
||||
if (callback->signal && !strpbrk(callback->signal, "*?[\\")
|
||||
&& callback->source && !strpbrk(callback->source, "*?[\\"))
|
||||
if (callbacks->signal && !strpbrk(callbacks->signal, "*?[\\")
|
||||
&& callbacks->source && !strpbrk(callbacks->source, "*?[\\"))
|
||||
{
|
||||
Edje_Signal_Source_Char *item;
|
||||
|
||||
item = (Edje_Signal_Source_Char*) eina_rbtree_inline_lookup(new, callback->signal, 0,
|
||||
EINA_RBTREE_CMP_KEY_CB(_edje_signal_source_key_cmp), callback->source);
|
||||
item = (Edje_Signal_Source_Char*) eina_rbtree_inline_lookup(new, callbacks->signal, 0,
|
||||
EINA_RBTREE_CMP_KEY_CB(_edje_signal_source_key_cmp), callbacks->source);
|
||||
if (!item)
|
||||
{
|
||||
item = malloc(sizeof (Edje_Signal_Source_Char));
|
||||
if (!item) continue;
|
||||
|
||||
item->signal = callback->signal;
|
||||
item->source = callback->source;
|
||||
eina_array_step_set(&item->list, sizeof (Eina_Array), 8);
|
||||
item->signal = callbacks->signal;
|
||||
item->source = callbacks->source;
|
||||
eina_inarray_step_set(&item->list, sizeof (Eina_Inarray), sizeof (int), 8);
|
||||
|
||||
new = eina_rbtree_inline_insert(new, EINA_RBTREE_GET(item),
|
||||
EINA_RBTREE_CMP_NODE_CB(_edje_signal_source_node_cmp), NULL);
|
||||
}
|
||||
|
||||
eina_array_push(&item->list, callback);
|
||||
eina_inarray_push(&item->list, &i);
|
||||
}
|
||||
else
|
||||
result = eina_list_prepend(result, callback);
|
||||
{
|
||||
eina_inarray_push(result, &i);
|
||||
}
|
||||
}
|
||||
|
||||
*tree = new;
|
||||
return result;
|
||||
}
|
||||
|
||||
const Eina_Array *
|
||||
const Eina_Inarray *
|
||||
edje_match_signal_source_hash_get(const char *sig,
|
||||
const char *source,
|
||||
const Eina_Rbtree *tree)
|
||||
|
@ -824,6 +882,6 @@ edje_match_signal_source_hash_get(const char *sig,
|
|||
void
|
||||
edje_match_signal_source_free(Edje_Signal_Source_Char *key, EINA_UNUSED void *data)
|
||||
{
|
||||
eina_array_flush(&key->list);
|
||||
eina_inarray_flush(&key->list);
|
||||
free(key);
|
||||
}
|
||||
|
|
|
@ -323,6 +323,10 @@ typedef struct _Edje_Signal_Source_Char Edje_Signal_Source_Char;
|
|||
typedef struct _Edje_Text_Insert_Filter_Callback Edje_Text_Insert_Filter_Callback;
|
||||
typedef struct _Edje_Markup_Filter_Callback Edje_Markup_Filter_Callback;
|
||||
typedef struct _Edje_Signals_Sources_Patterns Edje_Signals_Sources_Patterns;
|
||||
typedef struct _Edje_Signal_Callback_Group Edje_Signal_Callback_Group;
|
||||
typedef struct _Edje_Signal_Callback_Match Edje_Signal_Callback_Match;
|
||||
typedef struct _Edje_Signal_Callback_Matches Edje_Signal_Callback_Matches;
|
||||
typedef struct _Edje_Signal_Callback_Custom Edje_Signal_Callback_Custom;
|
||||
|
||||
#define EDJE_INF_MAX_W 100000
|
||||
#define EDJE_INF_MAX_H 100000
|
||||
|
@ -772,6 +776,7 @@ struct _Edje_Part_Limit
|
|||
|
||||
struct _Edje_Signals_Sources_Patterns
|
||||
{
|
||||
EINA_REFCOUNT;
|
||||
Edje_Patterns *signals_patterns;
|
||||
Edje_Patterns *sources_patterns;
|
||||
|
||||
|
@ -783,11 +788,39 @@ struct _Edje_Signals_Sources_Patterns
|
|||
unsigned int count;
|
||||
} programs;
|
||||
struct {
|
||||
Eina_List *globing;
|
||||
Eina_Inarray globing;
|
||||
} callbacks;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct _Edje_Signal_Callback_Match
|
||||
{
|
||||
const char *signal;
|
||||
const char *source;
|
||||
Edje_Signal_Cb func;
|
||||
};
|
||||
|
||||
struct _Edje_Signal_Callback_Matches
|
||||
{
|
||||
Edje_Signal_Callback_Match *matches;
|
||||
|
||||
Edje_Signals_Sources_Patterns *patterns;
|
||||
|
||||
unsigned int matches_count;
|
||||
EINA_REFCOUNT;
|
||||
|
||||
Eina_Bool hashed : 1;
|
||||
};
|
||||
|
||||
struct _Edje_Signal_Callback_Group
|
||||
{
|
||||
const Edje_Signal_Callback_Matches *matches;
|
||||
|
||||
void **custom_data;
|
||||
|
||||
Eina_Bool *flags; /* 4 bits per custom data (delete_me, just_added, propagate) */
|
||||
};
|
||||
|
||||
/*----------*/
|
||||
|
||||
struct _Edje_Part_Collection
|
||||
|
@ -1189,7 +1222,7 @@ struct _Edje_Signal_Source_Char
|
|||
const char *signal;
|
||||
const char *source;
|
||||
|
||||
Eina_Array list;
|
||||
Eina_Inarray list;
|
||||
};
|
||||
|
||||
struct _Edje
|
||||
|
@ -1207,7 +1240,6 @@ struct _Edje
|
|||
Edje_File *file; /* the file the data comes form */
|
||||
Edje_Part_Collection *collection; /* the description being used */
|
||||
Eina_List *actions; /* currently running actions */
|
||||
Eina_List *callbacks;
|
||||
Eina_List *pending_actions;
|
||||
Eina_Hash *color_classes;
|
||||
Eina_List *text_classes;
|
||||
|
@ -1230,9 +1262,7 @@ struct _Edje
|
|||
|
||||
Edje_Perspective *persp;
|
||||
|
||||
struct {
|
||||
Edje_Signals_Sources_Patterns callbacks;
|
||||
} patterns;
|
||||
const Edje_Signal_Callback_Group *callbacks;
|
||||
|
||||
struct {
|
||||
Edje_Text_Change_Cb func;
|
||||
|
@ -1789,8 +1819,10 @@ Edje_Patterns *edje_match_programs_signal_init(Edje_Program * const *array,
|
|||
unsigned int count);
|
||||
Edje_Patterns *edje_match_programs_source_init(Edje_Program * const *array,
|
||||
unsigned int count);
|
||||
Edje_Patterns *edje_match_callback_signal_init(const Eina_List *lst);
|
||||
Edje_Patterns *edje_match_callback_source_init(const Eina_List *lst);
|
||||
Edje_Patterns *edje_match_callback_signal_init(const Eina_Inarray *lst,
|
||||
const Edje_Signal_Callback_Match *matches);
|
||||
Edje_Patterns *edje_match_callback_source_init(const Eina_Inarray *lst,
|
||||
const Edje_Signal_Callback_Match *matches);
|
||||
|
||||
Eina_Bool edje_match_collection_dir_exec(const Edje_Patterns *ppat,
|
||||
const char *string);
|
||||
|
@ -1802,25 +1834,29 @@ Eina_Bool edje_match_programs_exec(const Edje_Patterns *ppat_signal,
|
|||
Eina_Bool (*func)(Edje_Program *pr, void *data),
|
||||
void *data,
|
||||
Eina_Bool prop);
|
||||
int edje_match_callback_exec(Edje_Patterns *ppat_signal,
|
||||
Edje_Patterns *ppat_source,
|
||||
const char *signal,
|
||||
const char *source,
|
||||
Eina_List *callbacks,
|
||||
Edje *ed,
|
||||
Eina_Bool prop);
|
||||
int edje_match_callback_exec(const Edje_Signals_Sources_Patterns *ssp,
|
||||
const Edje_Signal_Callback_Match *matches,
|
||||
const void **custom_data,
|
||||
const Eina_Bool *flags,
|
||||
const char *sig,
|
||||
const char *source,
|
||||
Edje *ed,
|
||||
Eina_Bool prop);
|
||||
|
||||
void edje_match_patterns_free(Edje_Patterns *ppat);
|
||||
|
||||
Eina_List *edje_match_program_hash_build(Edje_Program * const * programs,
|
||||
unsigned int count,
|
||||
Eina_Rbtree **tree);
|
||||
Eina_List *edje_match_callback_hash_build(const Eina_List *callbacks,
|
||||
Eina_Rbtree **tree);
|
||||
const Eina_Array *edje_match_signal_source_hash_get(const char *signal,
|
||||
const char *source,
|
||||
const Eina_Rbtree *tree);
|
||||
void edje_match_callback_hash_build(const Edje_Signal_Callback_Match *callback,
|
||||
int callbacks_count,
|
||||
Eina_Rbtree **tree,
|
||||
Eina_Inarray *result);
|
||||
const Eina_Inarray *edje_match_signal_source_hash_get(const char *signal,
|
||||
const char *source,
|
||||
const Eina_Rbtree *tree);
|
||||
void edje_match_signal_source_free(Edje_Signal_Source_Char *key, void *data);
|
||||
void _edje_signal_callback_matches_unref(Edje_Signal_Callback_Matches *m);
|
||||
|
||||
// FIXME remove below 3 eapi decls when edje_convert goes
|
||||
EAPI void _edje_edd_init(void);
|
||||
|
@ -1881,6 +1917,16 @@ void _edje_callbacks_focus_add(Evas_Object *obj, Edje *ed, Edje_Real_Part *rp);
|
|||
void _edje_callbacks_del(Evas_Object *obj, Edje *ed);
|
||||
void _edje_callbacks_focus_del(Evas_Object *obj, Edje *ed);
|
||||
|
||||
const Edje_Signal_Callback_Group *_edje_signal_callback_alloc(void);
|
||||
void _edje_signal_callback_free(const Edje_Signal_Callback_Group *cgp);
|
||||
void _edje_signal_callback_push(const Edje_Signal_Callback_Group *cgp,
|
||||
const char *signal, const char *source,
|
||||
Edje_Signal_Cb func, void *data,
|
||||
Eina_Bool propagate);
|
||||
void *_edje_signal_callback_disable(const Edje_Signal_Callback_Group *cgp,
|
||||
const char *signal, const char *source,
|
||||
Edje_Signal_Cb func, void *data);
|
||||
|
||||
EAPI void _edje_edd_init(void);
|
||||
EAPI void _edje_edd_shutdown(void);
|
||||
|
||||
|
@ -1917,7 +1963,12 @@ void _edje_emit(Edje *ed, const char *sig, const char *src);
|
|||
void _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*free_func)(void *));
|
||||
void _edje_emit_handle(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop);
|
||||
void _edje_signals_sources_patterns_clean(Edje_Signals_Sources_Patterns *ssp);
|
||||
void _edje_callbacks_patterns_clean(Edje *ed);
|
||||
|
||||
const Edje_Signals_Sources_Patterns *_edje_signal_callback_patterns_ref(const Edje_Signal_Callback_Group *gp);
|
||||
void _edje_signal_callback_patterns_unref(const Edje_Signals_Sources_Patterns *essp);
|
||||
Eina_Bool _edje_signal_callback_prop(const Eina_Bool *flags, int i);
|
||||
|
||||
void _edje_signal_callback_free(const Edje_Signal_Callback_Group *gp);
|
||||
|
||||
void _edje_text_init(void);
|
||||
void _edje_text_part_on_add(Edje *ed, Edje_Real_Part *ep);
|
||||
|
@ -2462,6 +2513,9 @@ void _play_get(Eo *obj, void *_pd, va_list *list);
|
|||
void _animation_set(Eo *obj, void *_pd, va_list *list);
|
||||
void _animation_get(Eo *obj, void *_pd, va_list *list);
|
||||
|
||||
void edje_signal_init(void);
|
||||
void edje_signal_shutdown(void);
|
||||
|
||||
#ifdef HAVE_LIBREMIX
|
||||
#include <remix/remix.h>
|
||||
#endif
|
||||
|
|
|
@ -28,26 +28,27 @@ edje_frametime_get(void)
|
|||
void
|
||||
edje_object_propagate_callback_add(Evas_Object *obj, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
|
||||
{
|
||||
const char *sig;
|
||||
const char *src;
|
||||
Edje *ed;
|
||||
Edje_Signal_Callback *escb;
|
||||
|
||||
ed = _edje_fetch(obj);
|
||||
if (!ed) return;
|
||||
if (ed->delete_me) return;
|
||||
escb = calloc(1, sizeof(Edje_Signal_Callback));
|
||||
escb->propagate = EINA_TRUE;
|
||||
escb->signal = eina_stringshare_add("*");
|
||||
escb->source = eina_stringshare_add("*");
|
||||
escb->func = func;
|
||||
escb->data = data;
|
||||
ed->callbacks = eina_list_append(ed->callbacks, escb);
|
||||
if (ed->walking_callbacks)
|
||||
{
|
||||
escb->just_added = 1;
|
||||
ed->just_added_callbacks = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
_edje_callbacks_patterns_clean(ed);
|
||||
|
||||
if (!ed->callbacks)
|
||||
ed->callbacks = _edje_signal_callback_alloc();
|
||||
|
||||
sig = eina_stringshare_add("*");
|
||||
src = eina_stringshare_add("*");
|
||||
|
||||
_edje_signal_callback_push(ed->callbacks,
|
||||
sig, src,
|
||||
func, data,
|
||||
EINA_TRUE);
|
||||
|
||||
eina_stringshare_del(sig);
|
||||
eina_stringshare_del(src);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -66,27 +67,24 @@ _signal_callback_add(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
|
|||
void *data = va_arg(*list, void *);
|
||||
|
||||
Edje *ed = _pd;
|
||||
Edje_Signal_Callback *escb;
|
||||
|
||||
if ((!emission) || (!source) || (!func)) return;
|
||||
ed = _pd;
|
||||
if (!ed) return;
|
||||
if (ed->delete_me) return;
|
||||
escb = calloc(1, sizeof(Edje_Signal_Callback));
|
||||
if (emission[0])
|
||||
escb->signal = eina_stringshare_add(emission);
|
||||
if (source[0])
|
||||
escb->source = eina_stringshare_add(source);
|
||||
escb->func = func;
|
||||
escb->data = data;
|
||||
ed->callbacks = eina_list_append(ed->callbacks, escb);
|
||||
if (ed->walking_callbacks)
|
||||
{
|
||||
escb->just_added = 1;
|
||||
ed->just_added_callbacks = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
_edje_callbacks_patterns_clean(ed);
|
||||
|
||||
emission = eina_stringshare_add(emission);
|
||||
source = eina_stringshare_add(source);
|
||||
|
||||
if (!ed->callbacks)
|
||||
ed->callbacks = _edje_signal_callback_alloc();
|
||||
|
||||
_edje_signal_callback_push(ed->callbacks,
|
||||
emission, source,
|
||||
func, data, EINA_FALSE);
|
||||
|
||||
eina_stringshare_del(emission);
|
||||
eina_stringshare_del(source);
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
|
@ -94,7 +92,7 @@ edje_object_signal_callback_del(Evas_Object *obj, const char *emission, const ch
|
|||
{
|
||||
if (!obj) return NULL;
|
||||
void *ret = NULL;
|
||||
eo_do(obj, edje_obj_signal_callback_del(emission, source, (Edje_Signal_Cb)func, &ret));
|
||||
eo_do(obj, edje_obj_signal_callback_del(emission, source, (Edje_Signal_Cb)func, NULL, &ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -104,46 +102,25 @@ _signal_callback_del(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
|
|||
const char *emission = va_arg(*list, const char *);
|
||||
const char *source = va_arg(*list, const char *);
|
||||
Edje_Signal_Cb func = va_arg(*list, Edje_Signal_Cb);
|
||||
void *data = va_arg(*list, void *);
|
||||
void **ret = va_arg(*list, void **);
|
||||
if (ret) *ret = NULL;
|
||||
|
||||
Edje *ed = _pd;
|
||||
Eina_List *l;
|
||||
Edje_Signal_Callback *escb;
|
||||
|
||||
if (ret) *ret = NULL;
|
||||
|
||||
if ((!emission) || (!source) || (!func)) return;
|
||||
if (!ed) return;
|
||||
if (ed->delete_me) return;
|
||||
EINA_LIST_FOREACH(ed->callbacks, l, escb)
|
||||
{
|
||||
if ((escb->func == func) &&
|
||||
((!escb->signal && !emission[0]) ||
|
||||
(escb->signal && !strcmp(escb->signal, emission))) &&
|
||||
((!escb->source && !source[0]) ||
|
||||
(escb->source && !strcmp(escb->source, source))))
|
||||
{
|
||||
void *data;
|
||||
|
||||
data = escb->data;
|
||||
if (ed->walking_callbacks)
|
||||
{
|
||||
escb->delete_me = EINA_TRUE;
|
||||
ed->delete_callbacks = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_edje_callbacks_patterns_clean(ed);
|
||||
emission = eina_stringshare_add(emission);
|
||||
source = eina_stringshare_add(source);
|
||||
|
||||
ed->callbacks = eina_list_remove_list(ed->callbacks, l);
|
||||
if (escb->signal) eina_stringshare_del(escb->signal);
|
||||
if (escb->source) eina_stringshare_del(escb->source);
|
||||
free(escb);
|
||||
}
|
||||
if (ret) *ret = data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
_edje_signal_callback_disable(ed->callbacks,
|
||||
emission, source,
|
||||
func, data);
|
||||
|
||||
eina_stringshare_del(emission);
|
||||
eina_stringshare_del(source);
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
|
@ -151,59 +128,10 @@ edje_object_signal_callback_del_full(Evas_Object *obj, const char *emission, con
|
|||
{
|
||||
if (!obj) return NULL;
|
||||
void *ret = NULL;
|
||||
eo_do(obj, edje_obj_signal_callback_del_full(emission, source, func, data, &ret));
|
||||
eo_do(obj, edje_obj_signal_callback_del(emission, source, func, data, &ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_signal_callback_del_full(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
|
||||
{
|
||||
const char *emission = va_arg(*list, const char *);
|
||||
const char *source = va_arg(*list, const char *);
|
||||
Edje_Signal_Cb func = va_arg(*list, Edje_Signal_Cb);
|
||||
void *data = va_arg(*list, void *);
|
||||
void **ret = va_arg(*list, void **);
|
||||
if (ret) *ret = NULL;
|
||||
|
||||
Edje *ed = _pd;
|
||||
Eina_List *l;
|
||||
Edje_Signal_Callback *escb;
|
||||
|
||||
if ((!emission) || (!source) || (!func)) return;
|
||||
if (!ed) return;
|
||||
if (ed->delete_me) return;
|
||||
EINA_LIST_FOREACH(ed->callbacks, l, escb)
|
||||
{
|
||||
if ((escb->func == func) && (escb->data == data) &&
|
||||
((!escb->signal && !emission[0]) ||
|
||||
(escb->signal && !strcmp(escb->signal, emission))) &&
|
||||
((!escb->source && !source[0]) ||
|
||||
(escb->source && !strcmp(escb->source, source))))
|
||||
{
|
||||
void *data2;
|
||||
|
||||
data2 = escb->data;
|
||||
if (ed->walking_callbacks)
|
||||
{
|
||||
escb->delete_me = EINA_TRUE;
|
||||
ed->delete_callbacks = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_edje_callbacks_patterns_clean(ed);
|
||||
|
||||
ed->callbacks = eina_list_remove_list(ed->callbacks, l);
|
||||
if (escb->signal) eina_stringshare_del(escb->signal);
|
||||
if (escb->source) eina_stringshare_del(escb->source);
|
||||
free(escb);
|
||||
}
|
||||
if (ret) *ret = data2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edje_object_signal_emit(Evas_Object *obj, const char *emission, const char *source)
|
||||
{
|
||||
|
@ -627,9 +555,20 @@ _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig,
|
|||
|
||||
tmp = calloc(1, sizeof(Edje_Calc_Params));
|
||||
if (!tmp) goto low_mem_current;
|
||||
tmp->map = eina_cow_alloc(_edje_calc_params_map_cow);
|
||||
#ifdef HAVE_EPHYSICS
|
||||
tmp->physics = eina_cow_alloc(_edje_calc_params_physics_cow);
|
||||
#endif
|
||||
_edje_part_recalc(ed, rp, FLAG_XY, tmp);
|
||||
|
||||
if (rp->current) free(rp->current);
|
||||
if (rp->current)
|
||||
{
|
||||
eina_cow_free(_edje_calc_params_map_cow, rp->current->map);
|
||||
#ifdef HAVE_EPHYSICS
|
||||
eina_cow_free(_edje_calc_params_physics_cow, rp->current->physics);
|
||||
#endif
|
||||
free(rp->current);
|
||||
}
|
||||
rp->current = tmp;
|
||||
|
||||
rp->current->x -= ed->x;
|
||||
|
@ -650,7 +589,14 @@ _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig,
|
|||
else
|
||||
{
|
||||
low_mem_current:
|
||||
if (rp->current) free(rp->current);
|
||||
if (rp->current)
|
||||
{
|
||||
eina_cow_free(_edje_calc_params_map_cow, rp->current->map);
|
||||
#ifdef HAVE_EPHYSICS
|
||||
eina_cow_free(_edje_calc_params_physics_cow, rp->current->physics);
|
||||
#endif
|
||||
free(rp->current);
|
||||
}
|
||||
rp->current = NULL;
|
||||
}
|
||||
|
||||
|
@ -1093,7 +1039,7 @@ _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*f
|
|||
Edje *ed2;
|
||||
char *part;
|
||||
char *idx;
|
||||
size_t length;
|
||||
unsigned int length;
|
||||
|
||||
/* the signal contains a colon, split the signal into "parts:signal" */
|
||||
length = sep - sig + 1;
|
||||
|
@ -1279,37 +1225,6 @@ static Eina_Bool _edje_glob_callback(Edje_Program *pr, void *dt)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_edje_callbacks_patterns_clean(Edje *ed)
|
||||
{
|
||||
if (ed->walking_callbacks > 0) return;
|
||||
|
||||
_edje_signals_sources_patterns_clean(&ed->patterns.callbacks);
|
||||
|
||||
eina_rbtree_delete(ed->patterns.callbacks.exact_match,
|
||||
EINA_RBTREE_FREE_CB(edje_match_signal_source_free),
|
||||
NULL);
|
||||
ed->patterns.callbacks.exact_match = NULL;
|
||||
|
||||
ed->patterns.callbacks.u.callbacks.globing = eina_list_free(ed->patterns.callbacks.u.callbacks.globing);
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_callbacks_patterns_init(Edje *ed)
|
||||
{
|
||||
Edje_Signals_Sources_Patterns *ssp = &ed->patterns.callbacks;
|
||||
|
||||
if ((ssp->signals_patterns) || (ssp->sources_patterns) ||
|
||||
(ssp->u.callbacks.globing) || (ssp->exact_match))
|
||||
return;
|
||||
|
||||
ssp->u.callbacks.globing = edje_match_callback_hash_build(ed->callbacks,
|
||||
&ssp->exact_match);
|
||||
|
||||
ssp->signals_patterns = edje_match_callback_signal_init(ssp->u.callbacks.globing);
|
||||
ssp->sources_patterns = edje_match_callback_source_init(ssp->u.callbacks.globing);
|
||||
}
|
||||
|
||||
/* FIXME: what if we delete the evas object??? */
|
||||
void
|
||||
_edje_emit_handle(Edje *ed, const char *sig, const char *src,
|
||||
|
@ -1403,13 +1318,11 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src,
|
|||
|
||||
if (ed->collection->patterns.table_programs_size > 0)
|
||||
{
|
||||
const Eina_Array *match;
|
||||
const Eina_Inarray *match;
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
const Eina_List *l;
|
||||
#endif
|
||||
Edje_Program *pr;
|
||||
Eina_Array_Iterator iterator;
|
||||
unsigned int i;
|
||||
|
||||
if (ed->collection->patterns.programs.u.programs.globing)
|
||||
if (edje_match_programs_exec(ed->collection->patterns.programs.signals_patterns,
|
||||
|
@ -1420,13 +1333,17 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src,
|
|||
_edje_glob_callback,
|
||||
&data,
|
||||
prop) == 0)
|
||||
goto break_prog;
|
||||
goto break_prog;
|
||||
|
||||
match = edje_match_signal_source_hash_get(sig, src,
|
||||
ed->collection->patterns.programs.exact_match);
|
||||
if (match)
|
||||
EINA_ARRAY_ITER_NEXT(match, i, pr, iterator)
|
||||
_edje_glob_callback(pr, &data);
|
||||
{
|
||||
Edje_Program **tpr;
|
||||
|
||||
EINA_INARRAY_FOREACH(match, tpr)
|
||||
_edje_glob_callback(*tpr, &data);
|
||||
}
|
||||
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
EINA_LIST_FOREACH(data.matches, l, pr)
|
||||
|
@ -1489,82 +1406,68 @@ edje_object_signal_callback_extra_data_get(void)
|
|||
static void
|
||||
_edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop)
|
||||
{
|
||||
Eina_List *l;
|
||||
const Edje_Signals_Sources_Patterns *ssp;
|
||||
Edje_Signal_Callback_Matches *m;
|
||||
const void **custom_data;
|
||||
Eina_Bool *flags;
|
||||
const Eina_Inarray *match;
|
||||
int r = 1;
|
||||
|
||||
if (ed->delete_me) return;
|
||||
if (!ed->callbacks || !ed->callbacks->matches) return;
|
||||
|
||||
_edje_ref(ed);
|
||||
_edje_freeze(ed);
|
||||
_edje_block(ed);
|
||||
|
||||
if (ed->just_added_callbacks)
|
||||
_edje_callbacks_patterns_clean(ed);
|
||||
ssp = _edje_signal_callback_patterns_ref(ed->callbacks);
|
||||
|
||||
ed->walking_callbacks++;
|
||||
m = (Edje_Signal_Callback_Matches*) ed->callbacks->matches;
|
||||
EINA_REFCOUNT_REF(m);
|
||||
|
||||
if (ed->callbacks)
|
||||
callback_extra_data = (data) ? data->data : NULL;
|
||||
custom_data = alloca(sizeof (void*) * m->matches_count);
|
||||
memcpy(custom_data, ed->callbacks->custom_data, sizeof (void*) * m->matches_count);
|
||||
flags = alloca(sizeof (Eina_Bool) * m->matches_count);
|
||||
memcpy(flags, ed->callbacks->flags, sizeof (Eina_Bool) * (m->matches_count >> 1));
|
||||
|
||||
if (eina_inarray_count(&ssp->u.callbacks.globing))
|
||||
r = edje_match_callback_exec(ssp,
|
||||
m->matches,
|
||||
custom_data,
|
||||
flags,
|
||||
sig,
|
||||
src,
|
||||
ed,
|
||||
prop);
|
||||
|
||||
if (!r)
|
||||
goto break_prog;
|
||||
|
||||
match = edje_match_signal_source_hash_get(sig, src,
|
||||
ssp->exact_match);
|
||||
if (match)
|
||||
{
|
||||
Edje_Signal_Callback *escb;
|
||||
const Eina_Array *match;
|
||||
Eina_Array_Iterator iterator;
|
||||
unsigned int i;
|
||||
int r = 1;
|
||||
callback_extra_data = (data) ? data->data : NULL;
|
||||
const Edje_Signal_Callback_Match *cb;
|
||||
unsigned int *i;
|
||||
|
||||
_edje_callbacks_patterns_init(ed);
|
||||
if (ed->patterns.callbacks.u.callbacks.globing)
|
||||
r = edje_match_callback_exec(ed->patterns.callbacks.signals_patterns,
|
||||
ed->patterns.callbacks.sources_patterns,
|
||||
sig,
|
||||
src,
|
||||
ed->patterns.callbacks.u.callbacks.globing,
|
||||
ed,
|
||||
prop);
|
||||
EINA_INARRAY_FOREACH(match, i)
|
||||
{
|
||||
cb = &m->matches[*i];
|
||||
|
||||
if (!r)
|
||||
goto break_prog;
|
||||
if ((prop) && (_edje_signal_callback_prop(flags, *i))) continue;
|
||||
|
||||
match = edje_match_signal_source_hash_get(sig, src,
|
||||
ed->patterns.callbacks.exact_match);
|
||||
if (match)
|
||||
EINA_ARRAY_ITER_NEXT(match, i, escb, iterator)
|
||||
{
|
||||
if ((prop) && (escb->propagate)) continue;
|
||||
if ((!escb->just_added) && (!escb->delete_me))
|
||||
{
|
||||
escb->func(escb->data, ed->obj, sig, src);
|
||||
if (_edje_block_break(ed))
|
||||
break;
|
||||
}
|
||||
}
|
||||
cb->func((void*) custom_data[*i], ed->obj, sig, src);
|
||||
if (_edje_block_break(ed))
|
||||
break;
|
||||
}
|
||||
}
|
||||
break_prog:
|
||||
|
||||
ed->walking_callbacks--;
|
||||
if (!ed->walking_callbacks &&
|
||||
((ed->delete_callbacks) || (ed->just_added_callbacks)))
|
||||
{
|
||||
ed->delete_callbacks = EINA_FALSE;
|
||||
ed->just_added_callbacks = EINA_FALSE;
|
||||
l = ed->callbacks;
|
||||
while (l)
|
||||
{
|
||||
Edje_Signal_Callback *escb = l->data;
|
||||
Eina_List *next_l = l->next;
|
||||
break_prog:
|
||||
_edje_signal_callback_matches_unref(m);
|
||||
|
||||
if (escb->just_added)
|
||||
escb->just_added = 0;
|
||||
if (escb->delete_me)
|
||||
{
|
||||
ed->callbacks = eina_list_remove_list(ed->callbacks, l);
|
||||
if (escb->signal) eina_stringshare_del(escb->signal);
|
||||
if (escb->source) eina_stringshare_del(escb->source);
|
||||
free(escb);
|
||||
}
|
||||
l = next_l;
|
||||
}
|
||||
_edje_signal_callback_patterns_unref(ssp);
|
||||
|
||||
_edje_callbacks_patterns_clean(ed);
|
||||
}
|
||||
_edje_unblock(ed);
|
||||
_edje_thaw(ed);
|
||||
_edje_unref(ed);
|
||||
|
|
|
@ -0,0 +1,477 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "edje_private.h"
|
||||
|
||||
#define _DELETE_ME 0x4
|
||||
#define _JUST_ADDED 0x2
|
||||
#define _PROPAGATE 0x1
|
||||
|
||||
static Eina_Hash *signal_match = NULL;
|
||||
|
||||
static unsigned int
|
||||
_edje_signal_match_key_length(const void *key EINA_UNUSED)
|
||||
{
|
||||
return sizeof (Edje_Signal_Callback_Matches);
|
||||
}
|
||||
|
||||
static int
|
||||
_edje_signal_match_key_cmp(const void *key1, int key1_length EINA_UNUSED, const void *key2, int key2_length EINA_UNUSED)
|
||||
{
|
||||
const Edje_Signal_Callback_Matches *a = key1;
|
||||
const Edje_Signal_Callback_Matches *b = key2;
|
||||
unsigned int i;
|
||||
|
||||
if (a->matches_count != b->matches_count) return a->matches_count - b->matches_count;
|
||||
for (i = 0; i < a->matches_count; ++i)
|
||||
{
|
||||
if (a->matches[i].signal != b->matches[i].signal) return a->matches[i].signal - b->matches[i].signal;
|
||||
if (a->matches[i].source != b->matches[i].source) return a->matches[i].source - b->matches[i].source;
|
||||
if (a->matches[i].func != b->matches[i].func) return (unsigned char*) a->matches[i].func - (unsigned char*) b->matches[i].func;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_edje_signal_match_key_hash(const void *key, int key_length EINA_UNUSED)
|
||||
{
|
||||
const Edje_Signal_Callback_Matches *a = key;
|
||||
unsigned int hash, i;
|
||||
|
||||
hash = eina_hash_int32(&a->matches_count, sizeof (int));
|
||||
for (i = 0; i < a->matches_count; ++i)
|
||||
{
|
||||
#ifdef __LP64__
|
||||
hash ^= eina_hash_int64((const unsigned long int*) &a->matches[i].signal, sizeof (char *));
|
||||
hash ^= eina_hash_int64((const unsigned long int*) &a->matches[i].source, sizeof (char *));
|
||||
hash ^= eina_hash_int64((const unsigned long int*) &a->matches[i].func, sizeof (Edje_Signal_Cb));
|
||||
#else
|
||||
hash ^= eina_hash_int32((const unsigned int*) a->matches[i].signal, sizeof (char *));
|
||||
hash ^= eina_hash_int32((const unsigned int*) a->matches[i].source, sizeof (char *));
|
||||
hash ^= eina_hash_int32((const unsigned int*) a->matches[i].func, sizeof (Edje_Signal_Cb));
|
||||
#endif
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
static const Edje_Signal_Callback_Matches *
|
||||
_edje_signal_callback_matches_dup(const Edje_Signal_Callback_Matches *src)
|
||||
{
|
||||
Edje_Signal_Callback_Matches *result;
|
||||
unsigned int i;
|
||||
|
||||
result = calloc(1, sizeof (Edje_Signal_Callback_Matches));
|
||||
if (!result) return NULL;
|
||||
|
||||
result->hashed = EINA_FALSE;
|
||||
result->matches = malloc(sizeof (Edje_Signal_Callback_Match) * src->matches_count);
|
||||
result->matches_count = src->matches_count;
|
||||
result->patterns = NULL;
|
||||
EINA_REFCOUNT_REF(result);
|
||||
|
||||
for (i = 0; i < src->matches_count; i++)
|
||||
{
|
||||
result->matches[i].signal = eina_stringshare_ref(src->matches[i].signal);
|
||||
result->matches[i].source = eina_stringshare_ref(src->matches[i].source);
|
||||
result->matches[i].func = src->matches[i].func;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
_edje_callbacks_patterns_clean(Edje_Signal_Callback_Group *gp)
|
||||
{
|
||||
Edje_Signal_Callback_Matches *tmp;
|
||||
|
||||
assert(EINA_REFCOUNT_GET(gp->matches) == 1);
|
||||
tmp = (Edje_Signal_Callback_Matches*) gp->matches;
|
||||
|
||||
_edje_signal_callback_patterns_unref(tmp->patterns);
|
||||
tmp->patterns = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_callbacks_patterns_init(Edje_Signal_Callback_Group *gp)
|
||||
{
|
||||
Edje_Signals_Sources_Patterns *ssp;
|
||||
Edje_Signal_Callback_Matches *tmp;
|
||||
|
||||
if (gp->matches->patterns) return ;
|
||||
|
||||
tmp = (Edje_Signal_Callback_Matches*) gp->matches;
|
||||
tmp->patterns = calloc(1, sizeof (Edje_Signals_Sources_Patterns));
|
||||
if (!gp->matches->patterns) return ;
|
||||
|
||||
ssp = gp->matches->patterns;
|
||||
edje_match_callback_hash_build(gp->matches->matches,
|
||||
gp->matches->matches_count,
|
||||
&ssp->exact_match,
|
||||
&ssp->u.callbacks.globing);
|
||||
|
||||
ssp->signals_patterns = edje_match_callback_signal_init(&ssp->u.callbacks.globing, tmp->matches);
|
||||
ssp->sources_patterns = edje_match_callback_source_init(&ssp->u.callbacks.globing, tmp->matches);
|
||||
EINA_REFCOUNT_REF(ssp);
|
||||
}
|
||||
|
||||
void
|
||||
edje_signal_init(void)
|
||||
{
|
||||
signal_match = eina_hash_new(_edje_signal_match_key_length,
|
||||
_edje_signal_match_key_cmp,
|
||||
_edje_signal_match_key_hash,
|
||||
NULL,
|
||||
3);
|
||||
}
|
||||
|
||||
void
|
||||
edje_signal_shutdown(void)
|
||||
{
|
||||
// FIXME: iterate and destroy leftover signal matcher
|
||||
eina_hash_free(signal_match);
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_signal_callback_unset(Edje_Signal_Callback_Group *gp, int idx)
|
||||
{
|
||||
Edje_Signal_Callback_Match *m;
|
||||
|
||||
m = gp->matches->matches + idx;
|
||||
eina_stringshare_del(m->signal);
|
||||
m->signal = NULL;
|
||||
eina_stringshare_del(m->source);
|
||||
m->source = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_signal_callback_set(Edje_Signal_Callback_Group *gp, int idx,
|
||||
const char *sig, const char *src,
|
||||
Edje_Signal_Cb func, void *data, Eina_Bool flags)
|
||||
{
|
||||
Edje_Signal_Callback_Match *m;
|
||||
|
||||
m = gp->matches->matches + idx;
|
||||
m->signal = eina_stringshare_ref(sig);
|
||||
m->source = eina_stringshare_ref(src);
|
||||
m->func = func;
|
||||
|
||||
gp->custom_data[idx] = data;
|
||||
|
||||
gp->flags[idx >> 1] = (gp->flags[idx >> 1] & (0xF << (((idx & 1) ^ 1) * 4))) |
|
||||
((flags & 0xF) << ((idx & 1) * 4));
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_edje_signal_callback_prop(const Eina_Bool *flags, int i)
|
||||
{
|
||||
Eina_Bool b;
|
||||
|
||||
b = flags[i >> 1];
|
||||
return b & (_PROPAGATE << ((i & 1) * 4));
|
||||
}
|
||||
|
||||
static Edje_Signal_Callback_Group *
|
||||
_edje_signal_callback_grow(Edje_Signal_Callback_Group *gp)
|
||||
{
|
||||
Edje_Signal_Callback_Matches *tmp;
|
||||
unsigned int c;
|
||||
|
||||
tmp = (Edje_Signal_Callback_Matches*) gp->matches;
|
||||
tmp->matches_count++;
|
||||
tmp->matches = realloc(tmp->matches, sizeof (Edje_Signal_Callback_Match) * tmp->matches_count);
|
||||
gp->custom_data = realloc(gp->custom_data, sizeof (void*) * tmp->matches_count);
|
||||
|
||||
c = ((tmp->matches_count >> 1) | (tmp->matches_count & 1));
|
||||
gp->flags = realloc(gp->flags, sizeof (Edje_Signal_Callback_Group) + c);
|
||||
// We have just expanded by one char, set it to 0
|
||||
if (tmp->matches_count & 1) gp->flags[tmp->matches_count >> 1] = 0;
|
||||
|
||||
return gp;
|
||||
}
|
||||
|
||||
void
|
||||
_edje_signal_callback_push(const Edje_Signal_Callback_Group *cgp,
|
||||
const char *sig, const char *src,
|
||||
Edje_Signal_Cb func, void *data, Eina_Bool propagate)
|
||||
{
|
||||
Edje_Signal_Callback_Group *gp = (Edje_Signal_Callback_Group*) cgp;
|
||||
unsigned int i;
|
||||
|
||||
// let's first try to see if we do find an empty matching stop
|
||||
for (i = 0; i < gp->matches->matches_count; i++)
|
||||
if (sig == gp->matches->matches[i].signal &&
|
||||
src == gp->matches->matches[i].source &&
|
||||
func == gp->matches->matches[i].func)
|
||||
{
|
||||
Eina_Bool flags;
|
||||
|
||||
flags = gp->flags[i >> 1] & (0xF << ((i & 1) * 4));
|
||||
if (flags & _DELETE_ME)
|
||||
{
|
||||
_edje_signal_callback_unset(gp, i);
|
||||
_edje_signal_callback_set(gp, i,
|
||||
sig, src, func, data,
|
||||
(((!!propagate) & 1) | _JUST_ADDED));
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
if (gp->matches->hashed)
|
||||
{
|
||||
Edje_Signal_Callback_Matches *tmp;
|
||||
|
||||
tmp = (Edje_Signal_Callback_Matches*) gp->matches;
|
||||
if (EINA_REFCOUNT_GET(tmp) == 1)
|
||||
{
|
||||
eina_hash_del(signal_match, tmp, tmp);
|
||||
tmp->hashed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Edje_Signal_Callback_Matches *tmp_dup;
|
||||
tmp_dup = (Edje_Signal_Callback_Matches*) _edje_signal_callback_matches_dup(tmp);
|
||||
if (!tmp_dup) return ;
|
||||
EINA_REFCOUNT_UNREF(tmp)
|
||||
(void) 0; // Nothing to do because the case where refcount == 1 was already handle above.
|
||||
gp->matches = tmp_dup;
|
||||
}
|
||||
}
|
||||
|
||||
// search an empty spot now
|
||||
for (i = 0; i < gp->matches->matches_count; i += 2)
|
||||
if (gp->flags[i >> 1] & (_DELETE_ME | (_DELETE_ME << 4)))
|
||||
{
|
||||
if (gp->flags[i >> 1] & _DELETE_ME)
|
||||
{
|
||||
_edje_signal_callback_unset(gp, i);
|
||||
_edje_signal_callback_set(gp, i,
|
||||
sig, src, func, data,
|
||||
(((!!propagate) & 1) | _JUST_ADDED));
|
||||
return ;
|
||||
}
|
||||
if (gp->flags[i >> 1] & (_DELETE_ME << 4))
|
||||
{
|
||||
_edje_signal_callback_unset(gp, i + 1);
|
||||
_edje_signal_callback_set(gp, i + 1,
|
||||
sig, src, func, data,
|
||||
(((!!propagate) & 1) | _JUST_ADDED));
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
_edje_signal_callback_grow(gp);
|
||||
|
||||
// Set propagate and just_added flags
|
||||
_edje_signal_callback_set(gp, gp->matches->matches_count - 1,
|
||||
sig, src, func, data, (((!!propagate) & 1) | _JUST_ADDED));
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
const Edje_Signal_Callback_Group *
|
||||
_edje_signal_callback_alloc(void)
|
||||
{
|
||||
Edje_Signal_Callback_Group *escg;
|
||||
Edje_Signal_Callback_Matches *m;
|
||||
|
||||
escg = calloc(1, sizeof (Edje_Signal_Callback_Group));
|
||||
if (!escg) return NULL;
|
||||
|
||||
m = calloc(1, sizeof (Edje_Signal_Callback_Matches));
|
||||
if (!m)
|
||||
{
|
||||
free(escg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EINA_REFCOUNT_REF(m);
|
||||
escg->matches = m;
|
||||
|
||||
return escg;
|
||||
}
|
||||
|
||||
void
|
||||
_edje_signal_callback_matches_unref(Edje_Signal_Callback_Matches *m)
|
||||
{
|
||||
EINA_REFCOUNT_UNREF(m)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
_edje_signal_callback_patterns_unref(m->patterns);
|
||||
|
||||
if (m->hashed)
|
||||
eina_hash_del(signal_match, m, m);
|
||||
|
||||
for (i = 0; i < m->matches_count; ++i)
|
||||
{
|
||||
eina_stringshare_del(m->matches[i].signal);
|
||||
eina_stringshare_del(m->matches[i].source);
|
||||
}
|
||||
free(m->matches);
|
||||
free(m);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_edje_signal_callback_free(const Edje_Signal_Callback_Group *cgp)
|
||||
{
|
||||
Edje_Signal_Callback_Group *gp = (Edje_Signal_Callback_Group*) cgp;
|
||||
|
||||
if (!gp) return ;
|
||||
|
||||
_edje_signal_callback_matches_unref((Edje_Signal_Callback_Matches*) gp->matches);
|
||||
gp->matches = NULL;
|
||||
free(gp->custom_data);
|
||||
free(gp);
|
||||
}
|
||||
|
||||
void *
|
||||
_edje_signal_callback_disable(const Edje_Signal_Callback_Group *cgp,
|
||||
const char *sig, const char *src,
|
||||
Edje_Signal_Cb func, void *data)
|
||||
{
|
||||
Edje_Signal_Callback_Group *gp = (Edje_Signal_Callback_Group*) cgp;
|
||||
unsigned int i;
|
||||
|
||||
// FIXME: Shall we check DELETE_ME flags ?
|
||||
for (i = 0; i < gp->matches->matches_count; ++i)
|
||||
{
|
||||
if (sig == gp->matches->matches[i].signal &&
|
||||
src == gp->matches->matches[i].source &&
|
||||
func == gp->matches->matches[i].func &&
|
||||
gp->custom_data[i] == data)
|
||||
{
|
||||
Eina_Bool flags;
|
||||
|
||||
flags = gp->flags[i >> 1] | (_DELETE_ME << ((i & 1) * 4));
|
||||
gp->flags[i >> 1] = flags;
|
||||
return gp->custom_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
for (i = 0; i < gp->matches->matches_count; ++i)
|
||||
{
|
||||
if (sig == gp->matches->matches[i].signal &&
|
||||
src == gp->matches->matches[i].source &&
|
||||
func == gp->matches->matches[i].func)
|
||||
{
|
||||
Eina_Bool flags;
|
||||
|
||||
flags = gp->flags[i >> 1] | (_DELETE_ME << ((i & 1) * 4));
|
||||
gp->flags[i >> 1] = flags;
|
||||
return gp->custom_data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_signal_callback_move_last(Edje_Signal_Callback_Group *gp,
|
||||
int i)
|
||||
{
|
||||
Edje_Signal_Callback_Matches *m;
|
||||
int j;
|
||||
|
||||
m = (Edje_Signal_Callback_Matches*) gp->matches;
|
||||
|
||||
for (j = (int) --m->matches_count; j > i; --j)
|
||||
{
|
||||
if (!(gp->flags[j >> 1] & (_DELETE_ME << ((j & 1) * 4))))
|
||||
{
|
||||
m->matches[i].signal = m->matches[j].signal;
|
||||
m->matches[i].source = m->matches[j].source;
|
||||
m->matches[i].func = m->matches[j].func;
|
||||
gp->flags[i] = (gp->flags[i >> 1] & (0xF << (((i & 1) ^ 1) * 4))) |
|
||||
(gp->flags[j >> 1] & (0xF << (((j & 1) * 4))));
|
||||
return ;
|
||||
}
|
||||
--m->matches_count;
|
||||
}
|
||||
}
|
||||
|
||||
const Edje_Signals_Sources_Patterns *
|
||||
_edje_signal_callback_patterns_ref(const Edje_Signal_Callback_Group *gp)
|
||||
{
|
||||
const Edje_Signal_Callback_Matches *m;
|
||||
Edje_Signal_Callback_Matches *tmp;
|
||||
|
||||
if (gp->matches->hashed)
|
||||
goto got_it;
|
||||
|
||||
m = eina_hash_find(signal_match, gp->matches);
|
||||
if (!m)
|
||||
{
|
||||
tmp = (Edje_Signal_Callback_Matches*) gp->matches;
|
||||
if (!(tmp->patterns && (EINA_REFCOUNT_GET(tmp->patterns) > 1)))
|
||||
{
|
||||
// Let compact it and remove uneeded pattern before building it
|
||||
// We can do that because the custom data are kept local into the matching code.
|
||||
Eina_Bool delete_me = _DELETE_ME | (_DELETE_ME << 4);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < tmp->matches_count; i += 2)
|
||||
{
|
||||
if (gp->flags[i >> 1] & delete_me)
|
||||
{
|
||||
if (gp->flags[i >> 1] & _DELETE_ME)
|
||||
{
|
||||
_edje_signal_callback_move_last((Edje_Signal_Callback_Group*) gp, i);
|
||||
}
|
||||
if (i + 1 < gp->matches->matches_count &&
|
||||
(gp->flags[i >> 1] & (_DELETE_ME << 4)))
|
||||
{
|
||||
_edje_signal_callback_move_last((Edje_Signal_Callback_Group*) gp, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_edje_signal_callback_patterns_unref(tmp->patterns);
|
||||
tmp->patterns = NULL;
|
||||
|
||||
_edje_callbacks_patterns_init((Edje_Signal_Callback_Group*) gp);
|
||||
eina_hash_add(signal_match, tmp, tmp);
|
||||
tmp->hashed = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_edje_signal_callback_matches_unref((Edje_Signal_Callback_Matches*) gp->matches);
|
||||
((Edje_Signal_Callback_Group*)gp)->matches = m;
|
||||
tmp = (Edje_Signal_Callback_Matches*) gp->matches;
|
||||
EINA_REFCOUNT_REF(tmp);
|
||||
}
|
||||
|
||||
got_it:
|
||||
tmp = (Edje_Signal_Callback_Matches*) gp->matches;
|
||||
|
||||
EINA_REFCOUNT_REF(tmp->patterns);
|
||||
return gp->matches->patterns;
|
||||
}
|
||||
|
||||
void
|
||||
_edje_signal_callback_patterns_unref(const Edje_Signals_Sources_Patterns *essp)
|
||||
{
|
||||
Edje_Signals_Sources_Patterns *ssp;
|
||||
|
||||
if (!essp) return ;
|
||||
|
||||
ssp = (Edje_Signals_Sources_Patterns*) essp;
|
||||
|
||||
EINA_REFCOUNT_UNREF(ssp)
|
||||
{
|
||||
_edje_signals_sources_patterns_clean(ssp);
|
||||
|
||||
eina_rbtree_delete(ssp->exact_match,
|
||||
EINA_RBTREE_FREE_CB(edje_match_signal_source_free),
|
||||
NULL);
|
||||
ssp->exact_match = NULL;
|
||||
|
||||
eina_inarray_flush(&ssp->u.callbacks.globing);
|
||||
|
||||
free(ssp);
|
||||
}
|
||||
}
|
|
@ -480,7 +480,6 @@ _edje_smart_class_constructor(Eo_Class *klass)
|
|||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_MESSAGE_SIGNAL_PROCESS), _message_signal_process),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD), _signal_callback_add),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL), _signal_callback_del),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL_FULL), _signal_callback_del_full),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_SIGNAL_EMIT), _signal_emit),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_PLAY_SET), _play_set),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_PLAY_GET), _play_get),
|
||||
|
@ -626,7 +625,6 @@ static const Eo_Op_Description op_desc[] = {
|
|||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_MESSAGE_SIGNAL_PROCESS, "Process an object's message queue."),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD, "Add a callback for an arriving Edje signal, emitted by"),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL, "Remove a signal-triggered callback from an object."),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL_FULL, "Unregister/delete a callback set for an arriving Edje"),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_SIGNAL_EMIT, "Send/emit an Edje signal to a given Edje object"),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_PLAY_SET, "Set the Edje object to playing or paused states."),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_PLAY_GET, "Get the Edje object's state."),
|
||||
|
|
Loading…
Reference in New Issue