forked from enlightenment/efl
did some tests - this seems to be faster and seems to match correctly in some
test cases i brewed up. doesnt seem to break e so far and thats a fairly comprehensive test. SVN revision: 33515
This commit is contained in:
parent
1683d650d4
commit
fff9c738a2
|
@ -34,6 +34,7 @@ edje_container.h \
|
|||
edje_message_queue.c \
|
||||
edje_private.h \
|
||||
edje_cache.c \
|
||||
edje_match.c \
|
||||
edje_textblock_styles.c
|
||||
|
||||
libedje_la_LIBADD = -lm @EDJE_LIBS@ @fnmatch_libs@
|
||||
|
|
|
@ -158,15 +158,16 @@ edje_file_group_exists(const char *file, const char *glob)
|
|||
{
|
||||
if (edf->collection_dir)
|
||||
{
|
||||
Evas_List *l;
|
||||
Edje_Patterns *patterns;
|
||||
|
||||
for (l = edf->collection_dir->entries; l; l = l->next)
|
||||
patterns = edje_match_collection_dir_init(edf->collection_dir->entries);
|
||||
if (edje_match_collection_dir_exec(patterns,
|
||||
glob))
|
||||
{
|
||||
Edje_Part_Collection_Directory_Entry *ce;
|
||||
|
||||
ce = l->data;
|
||||
if (_edje_glob_match(ce->entry, glob)) return 1;
|
||||
edje_match_patterns_free(patterns);
|
||||
return 1;
|
||||
}
|
||||
edje_match_patterns_free(patterns);
|
||||
}
|
||||
_edje_cache_file_unref(edf);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,570 @@
|
|||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <Evas.h>
|
||||
|
||||
#include "Edje.h"
|
||||
#include "edje_private.h"
|
||||
|
||||
/* States manipulations. */
|
||||
|
||||
typedef struct _Edje_State Edje_State;
|
||||
struct _Edje_State
|
||||
{
|
||||
size_t idx;
|
||||
size_t pos;
|
||||
};
|
||||
|
||||
typedef struct _Edje_States Edje_States;
|
||||
struct _Edje_States
|
||||
{
|
||||
size_t size;
|
||||
Edje_State *states;
|
||||
_Bool *has;
|
||||
};
|
||||
|
||||
static void
|
||||
_edje_match_states_free(Edje_States *states,
|
||||
size_t states_size)
|
||||
{
|
||||
(void) states_size;
|
||||
free(states);
|
||||
}
|
||||
|
||||
#define ALIGN(Size) \
|
||||
{ \
|
||||
Size--; \
|
||||
Size |= sizeof (void*) - 1; \
|
||||
Size++; \
|
||||
};
|
||||
|
||||
static Edje_States*
|
||||
_edje_match_states_alloc(size_t n,
|
||||
size_t patterns_size,
|
||||
size_t patterns_max_length)
|
||||
{
|
||||
Edje_States *l;
|
||||
|
||||
const size_t 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 char *states;
|
||||
unsigned char *has;
|
||||
|
||||
size_t i;
|
||||
|
||||
states_size = sizeof (*l->states) * array_len;
|
||||
ALIGN(states_size);
|
||||
|
||||
has_size = sizeof (*l->has) * array_len;
|
||||
ALIGN(has_size);
|
||||
|
||||
states_has_size = states_size + has_size;
|
||||
|
||||
struct_size = sizeof (*l);
|
||||
ALIGN(struct_size);
|
||||
struct_size += states_has_size;
|
||||
|
||||
l = malloc(n * struct_size);
|
||||
if (!l) return NULL;
|
||||
|
||||
states = (unsigned char *) (l + n);
|
||||
has = states + states_size;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
l[i].states = (Edje_State *) states;
|
||||
l[i].has = (_Bool *) has;
|
||||
states += states_has_size;
|
||||
has += states_has_size;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_match_states_insert(Edje_States *list,
|
||||
size_t patterns_max_length,
|
||||
size_t idx,
|
||||
size_t pos)
|
||||
{
|
||||
{
|
||||
const size_t i = idx * (patterns_max_length + 1) + pos;
|
||||
|
||||
if (list->has[i]) return;
|
||||
list->has[i] = 1;
|
||||
}
|
||||
|
||||
const size_t i = list->size;
|
||||
|
||||
list->states[i].idx = idx;
|
||||
list->states[i].pos = pos;
|
||||
++list->size;
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_match_states_clear(Edje_States *list,
|
||||
size_t patterns_size,
|
||||
size_t patterns_max_length)
|
||||
{
|
||||
list->size = 0;
|
||||
memset(list->has, 0, patterns_size * (patterns_max_length + 1) * sizeof (*list->has));
|
||||
}
|
||||
|
||||
/* Token manipulation. */
|
||||
|
||||
enum status
|
||||
{
|
||||
patterns_not_found = 0,
|
||||
patterns_found = 1,
|
||||
patterns_syntax_error = 2
|
||||
};
|
||||
|
||||
static size_t
|
||||
_edje_match_patterns_exec_class_token(enum status *status,
|
||||
const char *cl_tok,
|
||||
char c)
|
||||
{
|
||||
if (! *cl_tok)
|
||||
{
|
||||
*status = patterns_syntax_error;
|
||||
return 0;
|
||||
}
|
||||
else if (cl_tok[1] == '-' && cl_tok[2] != ']')
|
||||
{
|
||||
if (*cl_tok <= c && c <= cl_tok[2])
|
||||
*status = patterns_found;
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c == *cl_tok)
|
||||
*status = patterns_found;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static Edje_Match_Error
|
||||
_edje_match_patterns_exec_class_complement(const char *cl_tok, size_t *ret)
|
||||
{
|
||||
switch (*cl_tok)
|
||||
{
|
||||
case 0:
|
||||
return EDJE_MATCH_SYNTAX_ERROR;
|
||||
|
||||
case '!':
|
||||
*ret = 1;
|
||||
return EDJE_MATCH_OK;
|
||||
|
||||
default:
|
||||
*ret = 0;
|
||||
return EDJE_MATCH_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static Edje_Match_Error
|
||||
_edje_match_patterns_exec_class(const char *cl,
|
||||
char c,
|
||||
size_t *ret)
|
||||
{
|
||||
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;
|
||||
|
||||
pos += neg;
|
||||
|
||||
do
|
||||
pos += _edje_match_patterns_exec_class_token(&status, cl + pos, c);
|
||||
while (cl[pos] && cl[pos] != ']');
|
||||
|
||||
if (status == patterns_syntax_error || ! cl[pos])
|
||||
return EDJE_MATCH_SYNTAX_ERROR;
|
||||
|
||||
if (status == patterns_found)
|
||||
*ret = neg ? 0 : pos + 1;
|
||||
else
|
||||
*ret = neg ? pos + 1 : 0;
|
||||
|
||||
return EDJE_MATCH_OK;
|
||||
}
|
||||
|
||||
static Edje_Match_Error
|
||||
_edje_match_patterns_exec_token(const char *tok,
|
||||
char c,
|
||||
size_t *ret)
|
||||
{
|
||||
switch (*tok)
|
||||
{
|
||||
case '\\':
|
||||
if (tok[1])
|
||||
{
|
||||
*ret = tok[1] == c ? 2 : 0;
|
||||
return EDJE_MATCH_OK;
|
||||
}
|
||||
return EDJE_MATCH_SYNTAX_ERROR;
|
||||
|
||||
case '?':
|
||||
*ret = 1;
|
||||
return EDJE_MATCH_OK;
|
||||
|
||||
case '[':
|
||||
return _edje_match_patterns_exec_class(tok, c, ret);
|
||||
|
||||
default:
|
||||
*ret = *tok == c ? 1 : 0;
|
||||
return EDJE_MATCH_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_match_patterns_exec_init_states(Edje_States *states,
|
||||
size_t patterns_size,
|
||||
size_t patterns_max_length)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
states->size = patterns_size;
|
||||
|
||||
memset(states->has,
|
||||
0,
|
||||
patterns_size * (patterns_max_length + 1) * sizeof (*states->has));
|
||||
for (i = 0; i < patterns_size; ++i)
|
||||
{
|
||||
states->states[i].idx = i;
|
||||
states->states[i].pos = 0;
|
||||
states->has[i * (patterns_max_length + 1)] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Exported function. */
|
||||
|
||||
#define EDJE_MATCH_INIT(Func, Type, Source, Show) \
|
||||
Edje_Patterns* \
|
||||
Func(Evas_List *lst) \
|
||||
{ \
|
||||
Edje_Patterns *r; \
|
||||
size_t i; \
|
||||
\
|
||||
if (!lst || evas_list_count(lst) <= 0) \
|
||||
return NULL; \
|
||||
\
|
||||
r = malloc(sizeof (Edje_Patterns) + \
|
||||
evas_list_count(lst) \
|
||||
* sizeof (*r->finals) \
|
||||
* sizeof(*r->patterns)); \
|
||||
if (!r) return NULL; \
|
||||
\
|
||||
r->patterns_size = evas_list_count(lst); \
|
||||
r->max_length = 0; \
|
||||
r->patterns = (const char **) r->finals + r->patterns_size + 1; \
|
||||
\
|
||||
for (i = 0; lst; ++i) \
|
||||
{ \
|
||||
const char *str; \
|
||||
Type *data; \
|
||||
size_t j; \
|
||||
\
|
||||
data = evas_list_data(lst); \
|
||||
if (!data) \
|
||||
{ \
|
||||
free(r); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
str = data->Source; \
|
||||
if (!str) str = ""; \
|
||||
r->patterns[i] = str; \
|
||||
\
|
||||
if (Show) \
|
||||
fprintf(stderr, "%i [%s]\n", i, str); \
|
||||
\
|
||||
r->finals[i] = 0; \
|
||||
for (j = 0; str[j]; ++j) \
|
||||
if (str[j] != '*') \
|
||||
r->finals[i] = j + 1; \
|
||||
\
|
||||
if (j > r->max_length) \
|
||||
r->max_length = j; \
|
||||
\
|
||||
lst = evas_list_next(lst); \
|
||||
} \
|
||||
\
|
||||
return r; \
|
||||
}
|
||||
|
||||
EDJE_MATCH_INIT(edje_match_collection_dir_init,
|
||||
Edje_Part_Collection_Directory_Entry,
|
||||
entry, 0);
|
||||
EDJE_MATCH_INIT(edje_match_programs_signal_init,
|
||||
Edje_Program,
|
||||
signal, 0);
|
||||
EDJE_MATCH_INIT(edje_match_programs_source_init,
|
||||
Edje_Program,
|
||||
source, 0);
|
||||
EDJE_MATCH_INIT(edje_match_callback_signal_init,
|
||||
Edje_Signal_Callback,
|
||||
signal, 0);
|
||||
EDJE_MATCH_INIT(edje_match_callback_source_init,
|
||||
Edje_Signal_Callback,
|
||||
source, 0);
|
||||
|
||||
static int
|
||||
_edje_match_collection_dir_exec_finals(const size_t *finals,
|
||||
const Edje_States *states)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < states->size; ++i)
|
||||
if (states->states[i].pos >= finals[states->states[i].idx])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
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,
|
||||
Evas_List *programs,
|
||||
int (*func)(Edje_Program *pr, void *data),
|
||||
void *data)
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
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])
|
||||
{
|
||||
Edje_Program *pr;
|
||||
|
||||
pr = evas_list_nth(programs, signal_states->states[i].idx);
|
||||
if (pr)
|
||||
{
|
||||
if (func(pr, data))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
edje_match_callback_exec_check_finals(const size_t *signal_finals,
|
||||
const size_t *source_finals,
|
||||
const Edje_States *signal_states,
|
||||
const Edje_States *source_states,
|
||||
const char *signal,
|
||||
const char *source,
|
||||
Evas_List *callbacks,
|
||||
Edje *ed)
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
int r = 1;
|
||||
|
||||
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])
|
||||
{
|
||||
Edje_Signal_Callback *escb;
|
||||
|
||||
escb = evas_list_nth(callbacks, signal_states->states[i].idx);
|
||||
if (escb)
|
||||
{
|
||||
if ((!escb->just_added)
|
||||
&& (!escb->delete_me))
|
||||
{
|
||||
escb->func(escb->data, ed->obj, signal, source);
|
||||
r = 2;
|
||||
}
|
||||
if (_edje_block_break(ed))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static Edje_States*
|
||||
_edje_match_fn(const Edje_Patterns *ppat,
|
||||
const char *string,
|
||||
Edje_States *states)
|
||||
{
|
||||
Edje_States *new_states = states + 1;
|
||||
const char *c;
|
||||
|
||||
for (c = string; *c && states->size; ++c)
|
||||
{
|
||||
size_t 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;
|
||||
|
||||
if (!ppat->patterns[idx][pos])
|
||||
continue;
|
||||
else if (ppat->patterns[idx][pos] == '*')
|
||||
{
|
||||
_edje_match_states_insert(states, ppat->max_length, idx, pos + 1);
|
||||
_edje_match_states_insert(new_states, ppat->max_length, idx, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t m;
|
||||
|
||||
if (_edje_match_patterns_exec_token(ppat->patterns[idx] + pos,
|
||||
*c,
|
||||
&m) != EDJE_MATCH_OK)
|
||||
return NULL;
|
||||
|
||||
if (m)
|
||||
_edje_match_states_insert(new_states, ppat->max_length, idx, pos + m);
|
||||
}
|
||||
}
|
||||
{
|
||||
Edje_States *tmp = states;
|
||||
|
||||
states = new_states;
|
||||
new_states = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
int
|
||||
edje_match_collection_dir_exec(const Edje_Patterns *ppat,
|
||||
const char *string)
|
||||
{
|
||||
Edje_States *states = _edje_match_states_alloc(2,
|
||||
ppat->patterns_size,
|
||||
ppat->max_length);
|
||||
Edje_States *result;
|
||||
int r = 0;
|
||||
|
||||
if (!states)
|
||||
return 0;
|
||||
_edje_match_patterns_exec_init_states(states, ppat->patterns_size, ppat->max_length);
|
||||
|
||||
result = _edje_match_fn(ppat, string, states);
|
||||
|
||||
if (result)
|
||||
r = _edje_match_collection_dir_exec_finals(ppat->finals, result);
|
||||
|
||||
_edje_match_states_free(states, 2);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
edje_match_programs_exec(const Edje_Patterns *ppat_signal,
|
||||
const Edje_Patterns *ppat_source,
|
||||
const char *signal,
|
||||
const char *source,
|
||||
Evas_List *programs,
|
||||
int (*func)(Edje_Program *pr, void *data),
|
||||
void *data)
|
||||
{
|
||||
Edje_States *signal_states = _edje_match_states_alloc(2,
|
||||
ppat_signal->patterns_size,
|
||||
ppat_signal->max_length);
|
||||
Edje_States *source_states = _edje_match_states_alloc(2,
|
||||
ppat_source->patterns_size,
|
||||
ppat_source->max_length);
|
||||
Edje_States *signal_result;
|
||||
Edje_States *source_result;
|
||||
int r = 0;
|
||||
|
||||
if (!signal_states || !source_states)
|
||||
return 0;
|
||||
|
||||
_edje_match_patterns_exec_init_states(signal_states,
|
||||
ppat_signal->patterns_size,
|
||||
ppat_signal->max_length);
|
||||
_edje_match_patterns_exec_init_states(source_states,
|
||||
ppat_source->patterns_size,
|
||||
ppat_source->max_length);
|
||||
|
||||
signal_result = _edje_match_fn(ppat_signal, signal, signal_states);
|
||||
source_result = _edje_match_fn(ppat_source, source, source_states);
|
||||
|
||||
if (signal_result && source_result)
|
||||
r = edje_match_programs_exec_check_finals(ppat_signal->finals,
|
||||
ppat_source->finals,
|
||||
signal_result,
|
||||
source_result,
|
||||
programs,
|
||||
func,
|
||||
data);
|
||||
|
||||
_edje_match_states_free(source_states, 2);
|
||||
_edje_match_states_free(signal_states, 2);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
edje_match_callback_exec(const Edje_Patterns *ppat_signal,
|
||||
const Edje_Patterns *ppat_source,
|
||||
const char *signal,
|
||||
const char *source,
|
||||
Evas_List *callbacks,
|
||||
Edje *ed)
|
||||
{
|
||||
Edje_States *signal_states = _edje_match_states_alloc(2,
|
||||
ppat_signal->patterns_size,
|
||||
ppat_signal->max_length);
|
||||
Edje_States *source_states = _edje_match_states_alloc(2,
|
||||
ppat_source->patterns_size,
|
||||
ppat_source->max_length);
|
||||
Edje_States *signal_result;
|
||||
Edje_States *source_result;
|
||||
int r = 0;
|
||||
|
||||
if (!signal_states || !source_states)
|
||||
return 0;
|
||||
|
||||
_edje_match_patterns_exec_init_states(signal_states,
|
||||
ppat_signal->patterns_size,
|
||||
ppat_signal->max_length);
|
||||
_edje_match_patterns_exec_init_states(source_states,
|
||||
ppat_source->patterns_size,
|
||||
ppat_source->max_length);
|
||||
|
||||
signal_result = _edje_match_fn(ppat_signal, signal, signal_states);
|
||||
source_result = _edje_match_fn(ppat_source, source, source_states);
|
||||
|
||||
if (signal_result && source_result)
|
||||
r = edje_match_callback_exec_check_finals(ppat_signal->finals,
|
||||
ppat_source->finals,
|
||||
signal_result,
|
||||
source_result,
|
||||
signal,
|
||||
source,
|
||||
callbacks,
|
||||
ed);
|
||||
|
||||
_edje_match_states_free(source_states, 2);
|
||||
_edje_match_states_free(signal_states, 2);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
edje_match_patterns_free(Edje_Patterns *ppat)
|
||||
{
|
||||
free(ppat);
|
||||
}
|
||||
|
|
@ -906,6 +906,48 @@ typedef enum _Edje_Fill
|
|||
EDJE_FILL_TYPE_TILE
|
||||
} Edje_Fill;
|
||||
|
||||
typedef enum _Edje_Match_Error
|
||||
{
|
||||
EDJE_MATCH_OK,
|
||||
EDJE_MATCH_ALLOC_ERROR,
|
||||
EDJE_MATCH_SYNTAX_ERROR
|
||||
|
||||
} Edje_Match_Error;
|
||||
|
||||
typedef struct _Edje_Patterns Edje_Patterns;
|
||||
struct _Edje_Patterns
|
||||
{
|
||||
const char **patterns;
|
||||
size_t patterns_size;
|
||||
size_t max_length;
|
||||
size_t finals[];
|
||||
|
||||
};
|
||||
|
||||
Edje_Patterns *edje_match_collection_dir_init(Evas_List *lst);
|
||||
Edje_Patterns *edje_match_programs_signal_init(Evas_List *lst);
|
||||
Edje_Patterns *edje_match_programs_source_init(Evas_List *lst);
|
||||
Edje_Patterns *edje_match_callback_signal_init(Evas_List *lst);
|
||||
Edje_Patterns *edje_match_callback_source_init(Evas_List *lst);
|
||||
|
||||
int edje_match_collection_dir_exec(const Edje_Patterns *ppat,
|
||||
const char *string);
|
||||
int edje_match_programs_exec(const Edje_Patterns *ppat_signal,
|
||||
const Edje_Patterns *ppat_source,
|
||||
const char *signal,
|
||||
const char *source,
|
||||
Evas_List *programs,
|
||||
int (*func)(Edje_Program *pr, void *data),
|
||||
void *data);
|
||||
int edje_match_callback_exec(const Edje_Patterns *ppat_signal,
|
||||
const Edje_Patterns *ppat_source,
|
||||
const char *signal,
|
||||
const char *source,
|
||||
Evas_List *callbacks,
|
||||
Edje *ed);
|
||||
|
||||
void edje_match_patterns_free(Edje_Patterns *ppat);
|
||||
|
||||
EAPI extern Eet_Data_Descriptor *_edje_edd_edje_file;
|
||||
EAPI extern Eet_Data_Descriptor *_edje_edd_edje_style;
|
||||
EAPI extern Eet_Data_Descriptor *_edje_edd_edje_style_tag;
|
||||
|
@ -998,7 +1040,6 @@ void _edje_text_class_members_free(void);
|
|||
void _edje_text_class_hash_free(void);
|
||||
|
||||
Edje *_edje_fetch(Evas_Object *obj);
|
||||
int _edje_glob_match(const char *str, const char *glob);
|
||||
int _edje_freeze(Edje *ed);
|
||||
int _edje_thaw(Edje *ed);
|
||||
int _edje_block(Edje *ed);
|
||||
|
|
|
@ -823,12 +823,46 @@ _edje_emit(Edje *ed, const char *sig, const char *src)
|
|||
_edje_message_send(ed, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
|
||||
}
|
||||
|
||||
struct _Edje_Program_Data
|
||||
{
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
Evas_List *matches;
|
||||
int matched;
|
||||
#endif
|
||||
Edje *ed;
|
||||
const char *signal;
|
||||
const char *source;
|
||||
};
|
||||
|
||||
static int _edje_glob_callback(Edje_Program *pr, void *dt)
|
||||
{
|
||||
struct _Edje_Program_Data *data = dt;
|
||||
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
data->matched++;
|
||||
#endif
|
||||
|
||||
_edje_program_run(data->ed, pr, 0, data->signal, data->source);
|
||||
if (_edje_block_break(data->ed))
|
||||
{
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
evas_list_free(data->matches);
|
||||
data->matches = NULL;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
data->matches = evas_list_append(data->matches, pr);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: what if we delete the evas object??? */
|
||||
void
|
||||
_edje_emit_handle(Edje *ed, const char *sig, const char *src)
|
||||
{
|
||||
Evas_List *l;
|
||||
|
||||
if (ed->delete_me) return;
|
||||
if (!sig) sig = "";
|
||||
if (!src) src = "";
|
||||
|
@ -883,35 +917,40 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src)
|
|||
#endif
|
||||
if (!done)
|
||||
{
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
int matched = 0;
|
||||
Evas_List *matches = NULL;
|
||||
#endif
|
||||
struct _Edje_Program_Data data;
|
||||
|
||||
for (l = ed->collection->programs; l; l = l->next)
|
||||
{
|
||||
Edje_Program *pr;
|
||||
data.ed = ed;
|
||||
data.source = src;
|
||||
data.signal = sig;
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
data.matched = 0;
|
||||
data.matches = NULL;
|
||||
#endif
|
||||
Edje_Patterns *signals_patterns;
|
||||
Edje_Patterns *sources_patterns;
|
||||
|
||||
pr = l->data;
|
||||
if ((_edje_glob_match(sig, pr->signal)) &&
|
||||
(_edje_glob_match(src, pr->source)))
|
||||
if (ed->collection->programs)
|
||||
{
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
matched++;
|
||||
#endif
|
||||
_edje_program_run(ed, pr, 0, sig, src);
|
||||
if (_edje_block_break(ed))
|
||||
signals_patterns = edje_match_programs_signal_init(ed->collection->programs);
|
||||
sources_patterns = edje_match_programs_source_init(ed->collection->programs);
|
||||
|
||||
if (edje_match_programs_exec(signals_patterns,
|
||||
sources_patterns,
|
||||
sig,
|
||||
src,
|
||||
ed->collection->programs,
|
||||
_edje_glob_callback,
|
||||
&data) == 0)
|
||||
{
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
evas_list_free(matches);
|
||||
#endif
|
||||
edje_match_patterns_free(signals_patterns);
|
||||
edje_match_patterns_free(sources_patterns);
|
||||
goto break_prog;
|
||||
}
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
matches = evas_list_append(matches, pr);
|
||||
#endif
|
||||
}
|
||||
|
||||
edje_match_patterns_free(signals_patterns);
|
||||
edje_match_patterns_free(sources_patterns);
|
||||
}
|
||||
|
||||
#ifdef EDJE_PROGRAM_CACHE
|
||||
if (tmps)
|
||||
{
|
||||
|
@ -920,7 +959,7 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src)
|
|||
evas_hash_add(ec->prog_cache.no_matches, tmps, ed);
|
||||
else
|
||||
ec->prog_cache.matches =
|
||||
evas_hash_add(ec->prog_cache.matches, tmps, matches);
|
||||
evas_hash_add(ec->prog_cache.matches, tmps, data.matches);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -940,6 +979,8 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src)
|
|||
static void
|
||||
_edje_emit_cb(Edje *ed, const char *sig, const char *src)
|
||||
{
|
||||
Edje_Patterns *signals_patterns;
|
||||
Edje_Patterns *sources_patterns;
|
||||
Evas_List *l;
|
||||
|
||||
if (ed->delete_me) return;
|
||||
|
@ -947,18 +988,32 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src)
|
|||
_edje_freeze(ed);
|
||||
_edje_block(ed);
|
||||
ed->walking_callbacks = 1;
|
||||
for (l = ed->callbacks; l; l = l->next)
|
||||
{
|
||||
Edje_Signal_Callback *escb;
|
||||
|
||||
escb = l->data;
|
||||
if ((!escb->just_added) &&
|
||||
(!escb->delete_me) &&
|
||||
(_edje_glob_match(sig, escb->signal)) &&
|
||||
(_edje_glob_match(src, escb->source)))
|
||||
escb->func(escb->data, ed->obj, sig, src);
|
||||
if (_edje_block_break(ed)) goto break_prog;
|
||||
if (ed->callbacks)
|
||||
{
|
||||
int r;
|
||||
|
||||
signals_patterns = edje_match_callback_signal_init(ed->callbacks);
|
||||
sources_patterns = edje_match_callback_source_init(ed->callbacks);
|
||||
|
||||
r = edje_match_callback_exec(signals_patterns,
|
||||
sources_patterns,
|
||||
sig,
|
||||
src,
|
||||
ed->callbacks,
|
||||
ed);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
edje_match_patterns_free(signals_patterns);
|
||||
edje_match_patterns_free(sources_patterns);
|
||||
goto break_prog;
|
||||
}
|
||||
|
||||
edje_match_patterns_free(signals_patterns);
|
||||
edje_match_patterns_free(sources_patterns);
|
||||
}
|
||||
|
||||
ed->walking_callbacks = 0;
|
||||
if ((ed->delete_callbacks) || (ed->just_added_callbacks))
|
||||
{
|
||||
|
|
|
@ -1950,20 +1950,6 @@ _edje_fetch(Evas_Object *obj)
|
|||
return ed;
|
||||
}
|
||||
|
||||
int
|
||||
_edje_glob_match(const char *str, const char *glob)
|
||||
{
|
||||
if ((!glob) || (glob[0] == 0))
|
||||
{
|
||||
if ((!str) || (str[0] == 0)) return 1;
|
||||
if ((glob) && (glob[0] == '*')) return 1;
|
||||
return 0;
|
||||
}
|
||||
if (glob[0] == '*') return 1;
|
||||
if ((glob) && (str) && (!fnmatch(glob, str, 0))) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_edje_freeze(Edje *ed)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue