* edje: split programs type in different stack for later speed improvements.

SVN revision: 50810
This commit is contained in:
Cedric BAIL 2010-08-04 14:25:40 +00:00
parent 7bf67b046b
commit c94ae93096
7 changed files with 488 additions and 185 deletions

View File

@ -237,12 +237,52 @@ _edje_file_convert(Eet_File *file, Old_Edje_File *oedf)
return NULL;
}
static void
_edje_collection_program_add(Edje_Program ***array,
unsigned int *count,
Edje_Program *add)
{
Edje_Program **tmp;
tmp = realloc(*array, sizeof (Edje_Program*) * (*count + 1));
if (!tmp) return ;
tmp[(*count)++] = add;
*array = tmp;
}
Eina_Bool
edje_program_is_strncmp(const char *str)
{
unsigned int length;
length = strlen(str);
if (strpbrk(str, "*?[\\") != str + length)
return EINA_FALSE;
if (str[length] == '['
|| str[length] == '\\')
return EINA_FALSE;
return EINA_TRUE;
}
Eina_Bool
edje_program_is_strrncmp(const char *str)
{
if (*str != '*' && *str != '?')
return EINA_FALSE;
if (strpbrk(str + 1, "*?[\\") != NULL)
return EINA_FALSE;
return EINA_TRUE;
}
Edje_Part_Collection *
_edje_collection_convert(Edje_File *file, Old_Edje_Part_Collection *oedc)
{
Edje_Part_Collection_Directory_Entry *ce;
Edje_Part_Collection *edc;
Old_Edje_Part *part;
Edje_Program *pg;
Edje_Data *di;
Eina_List *l;
unsigned int k;
@ -300,8 +340,32 @@ _edje_collection_convert(Edje_File *file, Old_Edje_Part_Collection *oedc)
if (!edc) return NULL;
ce->ref = edc;
edc->programs = oedc->programs;
oedc->programs = NULL;
EINA_LIST_FREE(oedc->programs, pg)
{
if (!pg->signal && !pg->source)
_edje_collection_program_add(&edc->programs.nocmp,
&edc->programs.nocmp_count,
pg);
else if (pg->signal && strpbrk(pg->signal, "*?[\\") == NULL
&& pg->source && strpbrk(pg->source, "*?[\\") == NULL)
_edje_collection_program_add(&edc->programs.strcmp,
&edc->programs.strcmp_count,
pg);
else if (pg->signal && edje_program_is_strncmp(pg->signal)
&& pg->source && edje_program_is_strncmp(pg->source))
_edje_collection_program_add(&edc->programs.strncmp,
&edc->programs.strncmp_count,
pg);
else if (pg->signal && edje_program_is_strrncmp(pg->signal)
&& pg->source && edje_program_is_strrncmp(pg->source))
_edje_collection_program_add(&edc->programs.strrncmp,
&edc->programs.strrncmp_count,
pg);
else
_edje_collection_program_add(&edc->programs.fnmatch,
&edc->programs.fnmatch_count,
pg);
}
edc->data = eina_hash_string_small_new(NULL);
EINA_LIST_FREE(oedc->data, di)

View File

@ -140,4 +140,7 @@ Edje_Part_Description_Common *_edje_description_convert(int type,
const Edje_File *_edje_file_get(void);
void _edje_file_set(const Edje_File *edf);
Eina_Bool edje_program_is_strncmp(const char *str);
Eina_Bool edje_program_is_strrncmp(const char *str);
#endif

View File

@ -474,6 +474,27 @@ _edje_part_description_id_set(int type, Edje_Part_Description_Common *c, int old
}
}
static void
_edje_part_program_id_set(Edje_Program *epr, int old_id, int new_id)
{
Edje_Program_Target *pt;
Eina_List *ll, *l_next;
if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
return;
EINA_LIST_FOREACH_SAFE(epr->targets, ll, l_next, pt)
{
if (pt->id == old_id)
{
if (new_id == -1)
epr->targets = eina_list_remove_list(epr->targets, ll);
else
pt->id = new_id;
}
}
}
static void
_edje_part_id_set(Edje *ed, Edje_Real_Part *rp, int new_id)
{
@ -483,11 +504,9 @@ _edje_part_id_set(Edje *ed, Edje_Real_Part *rp, int new_id)
* is lost.
* If new Id = -1 then all the depencies will be deleted
*/
int old_id;
Edje_Part *part;
Eina_List *l, *ll, *l_next;
Edje_Program *epr;
unsigned int j;
int old_id;
part = rp->part;
@ -522,24 +541,15 @@ _edje_part_id_set(Edje *ed, Edje_Real_Part *rp, int new_id)
}
/*...and also in programs targets */
EINA_LIST_FOREACH(ed->collection->programs, l, epr)
{
Edje_Program_Target *pt;
#define EDJE_EDIT_PROGRAM_ID_SET(Array, Ed, It, Old, New) \
for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
_edje_part_program_id_set(Ed->collection->programs.Array[It], Old, New);
if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
continue;
EINA_LIST_FOREACH_SAFE(epr->targets, ll, l_next, pt)
{
if (pt->id == old_id)
{
if (new_id == -1)
epr->targets = eina_list_remove_list(epr->targets, ll);
else
pt->id = new_id;
}
}
}
EDJE_EDIT_PROGRAM_ID_SET(fnmatch, ed, j, old_id, new_id);
EDJE_EDIT_PROGRAM_ID_SET(strcmp, ed, j, old_id, new_id);
EDJE_EDIT_PROGRAM_ID_SET(strncmp, ed, j, old_id, new_id);
EDJE_EDIT_PROGRAM_ID_SET(strrncmp, ed, j, old_id, new_id);
EDJE_EDIT_PROGRAM_ID_SET(nocmp, ed, j, old_id, new_id);
/* Adjust table_parts */
if (new_id >= 0)
@ -572,6 +582,22 @@ _edje_part_description_id_switch(int type, Edje_Part_Description_Common *c, int
}
}
static void
_edje_part_program_id_switch(Edje_Program *epr, int id1, int id2)
{
Edje_Program_Target *pt;
Eina_List *ll;
if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
return;
EINA_LIST_FOREACH(epr->targets, ll, pt)
{
if (pt->id == id1) pt->id = id2;
else if (pt->id == id2) pt->id = id1;
}
}
static void
_edje_parts_id_switch(Edje *ed, Edje_Real_Part *rp1, Edje_Real_Part *rp2)
{
@ -582,8 +608,6 @@ _edje_parts_id_switch(Edje *ed, Edje_Real_Part *rp1, Edje_Real_Part *rp2)
*/
int id1;
int id2;
Eina_List *l, *ll;
Edje_Program *epr;
unsigned int i;
//printf("SWITCH ID OF PART %d AND %d\n", rp1->part->id, rp2->part->id);
@ -625,19 +649,15 @@ _edje_parts_id_switch(Edje *ed, Edje_Real_Part *rp1, Edje_Real_Part *rp2)
}
//...and also in programs targets
EINA_LIST_FOREACH(ed->collection->programs, l, epr)
{
Edje_Program_Target *pt;
#define EDJE_EDIT_PROGRAM_SWITCH(Array, Ed, It, Id1, Id2) \
for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
_edje_part_program_id_switch(Ed->collection->programs.Array[i], Id1, Id2);
if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
continue;
EINA_LIST_FOREACH(epr->targets, ll, pt)
{
if (pt->id == id1) pt->id = id2;
else if (pt->id == id2) pt->id = id1;
}
}
EDJE_EDIT_PROGRAM_SWITCH(fnmatch, ed, i, id1, id2);
EDJE_EDIT_PROGRAM_SWITCH(strcmp, ed, i, id1, id2);
EDJE_EDIT_PROGRAM_SWITCH(strncmp, ed, i, id1, id2);
EDJE_EDIT_PROGRAM_SWITCH(strrncmp, ed, i, id1, id2);
EDJE_EDIT_PROGRAM_SWITCH(nocmp, ed, i, id1, id2);
//TODO Real part dependencies are ok?
}
@ -909,7 +929,7 @@ edje_edit_group_add(Evas_Object *obj, const char *name)
/* Init Edje_Part_Collection */
pc->id = id;
pc->references = 0;
pc->programs = NULL;
memset(&pc->programs, 0, sizeof (pc->programs));
pc->parts = NULL;
pc->data = NULL;
pc->script = NULL;
@ -4459,10 +4479,14 @@ edje_edit_program_add(Evas_Object *obj, const char *name)
//Add program to group
pc = ed->collection;
pc->programs = eina_list_append(pc->programs, epr);
/* By default, source and signal are empty, so they fill in nocmp category */
ed->collection->programs.nocmp = realloc(ed->collection->programs.nocmp,
sizeof (Edje_Program*) * ed->collection->programs.nocmp_count);
ed->collection->programs.nocmp[ed->collection->programs.nocmp_count++] = epr;
//Init Edje_Program
epr->id = eina_list_count(pc->programs) - 1;
epr->id = ed->table_programs_size;
epr->name = eina_stringshare_add(name);
epr->signal = NULL;
epr->source = NULL;
@ -4494,10 +4518,96 @@ edje_edit_program_add(Evas_Object *obj, const char *name)
return EINA_TRUE;
}
static void
_edje_edit_program_remove(Edje *ed, Edje_Program *p)
{
Edje_Program ***array;
unsigned int *count;
unsigned int i;
if (!p->signal && !p->source)
{
array = &ed->collection->programs.nocmp;
count = &ed->collection->programs.nocmp_count;
}
else if (p->signal && strpbrk(p->signal, "*?[\\") == NULL
&& p->source && strpbrk(p->source, "*?[\\") == NULL)
{
array = &ed->collection->programs.strcmp;
count = &ed->collection->programs.strcmp_count;
}
else if (p->signal && edje_program_is_strncmp(p->signal)
&& p->source && edje_program_is_strncmp(p->source))
{
array = &ed->collection->programs.strncmp;
count = &ed->collection->programs.strncmp_count;
}
else if (p->signal && edje_program_is_strrncmp(p->signal)
&& p->source && edje_program_is_strrncmp(p->source))
{
array = &ed->collection->programs.strrncmp;
count = &ed->collection->programs.strrncmp_count;
}
else
{
array = &ed->collection->programs.fnmatch;
count = &ed->collection->programs.fnmatch_count;
}
for (i = 0; i < *count; ++i)
if ((*array)[i] == p)
{
memmove(*array + i, *array + i + 1, sizeof (Edje_Program *) * (*count - i -1));
(*count)--;
break;
}
}
static void
_edje_edit_program_insert(Edje *ed, Edje_Program *p)
{
Edje_Program ***array;
unsigned int *count;
if (!p->signal && !p->source)
{
array = &ed->collection->programs.nocmp;
count = &ed->collection->programs.nocmp_count;
}
else if (p->signal && strpbrk(p->signal, "*?[\\") == NULL
&& p->source && strpbrk(p->source, "*?[\\") == NULL)
{
array = &ed->collection->programs.strcmp;
count = &ed->collection->programs.strcmp_count;
}
else if (p->signal && edje_program_is_strncmp(p->signal)
&& p->source && edje_program_is_strncmp(p->source))
{
array = &ed->collection->programs.strncmp;
count = &ed->collection->programs.strncmp_count;
}
else if (p->signal && edje_program_is_strrncmp(p->signal)
&& p->source && edje_program_is_strrncmp(p->source))
{
array = &ed->collection->programs.strrncmp;
count = &ed->collection->programs.strrncmp_count;
}
else
{
array = &ed->collection->programs.fnmatch;
count = &ed->collection->programs.fnmatch_count;
}
*array = realloc(*array, sizeof (Edje_Program *) * (*count + 1));
*array[(*count)++] = p;
}
EAPI Eina_Bool
edje_edit_program_del(Evas_Object *obj, const char *prog)
{
Eina_List *l, *l_next, *rem;
Eina_List *l, *l_next;
Edje_Program_Target *prt;
Edje_Program_After *pa;
Edje_Part_Collection *pc;
Edje_Program *p;
int id, i;
@ -4508,25 +4618,20 @@ edje_edit_program_del(Evas_Object *obj, const char *prog)
pc = ed->collection;
rem = eina_list_nth_list(pc->programs, epr->id);
l = eina_list_last(pc->programs);
if (rem != l)
//Remove program from programs list
id = epr->id;
_edje_edit_program_remove(ed, epr);
/* fix table program */
if (epr->id != ed->table_programs_size - 1)
{
/* If the removed program is not the last in the list/table,
* put the last one in its place and update references to it later */
p = eina_list_data_get(l);
pc->programs = eina_list_remove_list(pc->programs, l);
pc->programs = eina_list_append_relative_list(pc->programs, p, rem);
ed->table_programs[epr->id] = p;
old_id = p->id;
p->id = epr->id;
ed->table_programs[epr->id] = ed->table_programs[ed->table_programs_size - 1];
old_id = ed->table_programs_size - 1;
ed->table_programs[epr->id]->id = epr->id;
}
//Remove program from programs list
id = epr->id;
pc->programs = eina_list_remove(pc->programs, epr);
//Free Edje_Program
_edje_if_string_free(ed, epr->name);
_edje_if_string_free(ed, epr->signal);
@ -4536,22 +4641,10 @@ edje_edit_program_del(Evas_Object *obj, const char *prog)
_edje_if_string_free(ed, epr->state);
_edje_if_string_free(ed, epr->state2);
while (epr->targets)
{
Edje_Program_Target *prt;
prt = eina_list_data_get(epr->targets);
epr->targets = eina_list_remove_list(epr->targets, epr->targets);
free(prt);
}
while (epr->after)
{
Edje_Program_After *pa;
pa = eina_list_data_get(epr->after);
epr->after = eina_list_remove_list(epr->after, epr->after);
free(pa);
}
EINA_LIST_FREE(epr->targets, prt)
free(prt);
EINA_LIST_FREE(epr->after, pa)
free(pa);
free(epr);
ed->table_programs_size--;
@ -4645,15 +4738,17 @@ edje_edit_program_source_set(Evas_Object *obj, const char *prog, const char *sou
if (!source) return EINA_FALSE;
//printf("SET SOURCE for program: %s [%s]\n", prog, source);
/* Remove from program array */
_edje_edit_program_remove(ed, epr);
_edje_if_string_free(ed, epr->source);
/* Insert it back */
epr->source = eina_stringshare_add(source);
_edje_edit_program_insert(ed, epr);
//Update patterns
if (ed->patterns.programs.sources_patterns)
edje_match_patterns_free(ed->patterns.programs.sources_patterns);
ed->patterns.programs.sources_patterns = edje_match_programs_source_init(ed->collection->programs);
_edje_programs_patterns_clean(ed);
_edje_programs_patterns_init(ed);
return EINA_TRUE;
}
@ -4722,15 +4817,17 @@ edje_edit_program_signal_set(Evas_Object *obj, const char *prog, const char *sig
if (!signal) return EINA_FALSE;
//printf("SET SIGNAL for program: %s [%s]\n", prog, signal);
/* Remove from program array */
_edje_edit_program_remove(ed, epr);
_edje_if_string_free(ed, epr->signal);
/* Insert it back */
epr->signal = eina_stringshare_add(signal);
_edje_edit_program_insert(ed, epr);
//Update patterns
if (ed->patterns.programs.signals_patterns)
edje_match_patterns_free(ed->patterns.programs.signals_patterns);
ed->patterns.programs.signals_patterns = edje_match_programs_signal_init(ed->collection->programs);
_edje_programs_patterns_clean(ed);
_edje_programs_patterns_init(ed);
return EINA_TRUE;
}
@ -6226,7 +6323,7 @@ _edje_edit_part_save(Edje_Part *ep)
}
static Eina_Bool
_edje_edit_collection_save(Eet_File *eetf, Edje_Part_Collection *epc)
_edje_edit_collection_save(Edje *ed, Eet_File *eetf, Edje_Part_Collection *epc)
{
Old_Edje_Part_Description *oepd;
Old_Edje_Part_Collection oepc;
@ -6236,13 +6333,15 @@ _edje_edit_collection_save(Eet_File *eetf, Edje_Part_Collection *epc)
Edje_Data *di;
char buf[256];
unsigned int i;
int j;
Eina_Bool err = EINA_TRUE;
memset(&oepc, 0, sizeof(oepc));
snprintf(buf, sizeof(buf), "collections/%i", epc->id);
oepc.programs = epc->programs;
for (j = 0; j < ed->table_programs_size; ++j)
oepc.programs = eina_list_append(oepc.programs, ed->table_programs[j]);
it = eina_hash_iterator_tuple_new(epc->data);
EINA_ITERATOR_FOREACH(it, tu)
@ -6276,6 +6375,7 @@ _edje_edit_collection_save(Eet_File *eetf, Edje_Part_Collection *epc)
}
// FIXME
oepc.programs = eina_list_free(oepc.programs);
EINA_LIST_FREE(oepc.data, di)
free(di);
EINA_LIST_FREE(oepc.parts, oep)
@ -6405,7 +6505,7 @@ _edje_edit_internal_save(Evas_Object *obj, int current_only)
{
INF("** Writing Edje_Part_Collection* ed->collection "
"[id: %d]", ed->collection->id);
if (!_edje_edit_collection_save(eetf, ed->collection))
if (!_edje_edit_collection_save(ed, eetf, ed->collection))
{
eet_close(eetf);
return EINA_FALSE;
@ -6428,7 +6528,7 @@ _edje_edit_internal_save(Evas_Object *obj, int current_only)
{
INF("** Writing hash Edje_Part_Collection* ed->collection "
"[id: %d]", ce->id);
if(!_edje_edit_collection_save(eetf, ce->ref))
if(!_edje_edit_collection_save(ed, eetf, ce->ref))
{
eet_close(eetf);
return EINA_FALSE;
@ -6441,7 +6541,7 @@ _edje_edit_internal_save(Evas_Object *obj, int current_only)
{
INF("** Writing cache Edje_Part_Collection* ed->collection "
"[id: %d]", edc->id);
if(!_edje_edit_collection_save(eetf, edc))
if(!_edje_edit_collection_save(ed, eetf, edc))
{
eet_close(eetf);
return EINA_FALSE;
@ -6485,8 +6585,8 @@ EAPI void
edje_edit_print_internal_status(Evas_Object *obj)
{
Edje_Program *epr;
Eina_List *l;
unsigned int i;
int j;
GET_ED_OR_RETURN();
@ -6517,18 +6617,16 @@ edje_edit_print_internal_status(Evas_Object *obj)
WRN(" WRONG (table[%id]->name = '%s')", p->id, rp->part->name);
}
INF("*** Programs [table:%d list:%d]", ed->table_programs_size,
eina_list_count(ed->collection->programs));
EINA_LIST_FOREACH(ed->collection->programs, l, epr)
INF("*** Programs [table:%d list:%d,%d,%d,%d,%d]", ed->table_programs_size,
ed->collection->programs.fnmatch_count,
ed->collection->programs.strcmp_count,
ed->collection->programs.strncmp_count,
ed->collection->programs.strrncmp_count,
ed->collection->programs.nocmp_count);
for(j = 0; j < ed->table_programs_size; ++j)
{
Edje_Program *epr2;
epr2 = ed->table_programs[epr->id % ed->table_programs_size];
printf(" [%d]%s ", epr->id, epr->name);
if (epr == epr2)
printf(" OK!\n");
else
WRN(" WRONG (table[%id]->name = '%s')", epr->id, epr2->name);
epr = ed->table_programs[i % ed->table_programs_size];
printf(" [%d]%s\n", epr->id, epr->name);
}
printf("\n");

View File

@ -272,22 +272,49 @@ _edje_programs_patterns_clean(Edje *ed)
NULL);
ed->patterns.programs.exact_match = NULL;
ed->patterns.programs.globing = eina_list_free(ed->patterns.programs.globing);
free(ed->patterns.programs.u.programs.globing);
ed->patterns.programs.u.programs.globing = NULL;
}
void
_edje_programs_patterns_init(Edje *ed)
{
Edje_Signals_Sources_Patterns *ssp = &ed->patterns.programs;
Edje_Program **all;
unsigned int i, j;
if (ssp->signals_patterns)
return;
ssp->globing = edje_match_program_hash_build(ed->collection->programs,
&ssp->exact_match);
edje_match_program_hash_build(ed->collection->programs.strcmp,
ed->collection->programs.strcmp_count,
&ssp->exact_match);
ssp->signals_patterns = edje_match_programs_signal_init(ssp->globing);
ssp->sources_patterns = edje_match_programs_source_init(ssp->globing);
j = ed->collection->programs.strncmp_count
+ ed->collection->programs.strrncmp_count
+ ed->collection->programs.fnmatch_count
+ ed->collection->programs.nocmp_count;
if (j == 0) return ;
all = malloc(sizeof (Edje_Program *) * j);
if (!all) return ;
j = 0;
/* FIXME: Build specialized data type for each case */
#define EDJE_LOAD_PROGRAMS_ADD(Array, Ed, It, Git, All) \
for (It = 0; It < Ed->collection->programs.Array##_count; ++It, ++Git) \
All[Git] = Ed->collection->programs.Array[It];
EDJE_LOAD_PROGRAMS_ADD(fnmatch, ed, i, j, all);
EDJE_LOAD_PROGRAMS_ADD(strncmp, ed, i, j, all);
EDJE_LOAD_PROGRAMS_ADD(strrncmp, ed, i, j, all);
/* FIXME: Do a special pass for that one */
EDJE_LOAD_PROGRAMS_ADD(nocmp, ed, i, j, all);
ssp->u.programs.globing = all;
ssp->u.programs.count = j;
ssp->signals_patterns = edje_match_programs_signal_init(all, j);
ssp->sources_patterns = edje_match_programs_source_init(all, j);
}
int
@ -567,22 +594,34 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
}
_edje_programs_patterns_init(ed);
n = eina_list_count(ed->collection->programs);
n = ed->collection->programs.fnmatch_count +
ed->collection->programs.strcmp_count +
ed->collection->programs.strncmp_count +
ed->collection->programs.strrncmp_count +
ed->collection->programs.nocmp_count;
if (n > 0)
{
Edje_Program *pr;
Eina_List *l;
unsigned int i;
/* FIXME: keeping a table AND a list is just bad - nuke list */
ed->table_programs = malloc(sizeof(Edje_Program *) * n);
ed->table_programs_size = n;
/* FIXME: check malloc return */
n = 0;
EINA_LIST_FOREACH(ed->collection->programs, l, pr)
if (ed->table_programs)
{
ed->table_programs[n] = pr;
n++;
ed->table_programs_size = n;
#define EDJE_LOAD_BUILD_TABLE(Array, Ed, It, Tmp) \
for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
{ \
Tmp = Ed->collection->programs.Array[It]; \
Ed->table_programs[Tmp->id] = Tmp; \
}
EDJE_LOAD_BUILD_TABLE(fnmatch, ed, i, pr);
EDJE_LOAD_BUILD_TABLE(strcmp, ed, i, pr);
EDJE_LOAD_BUILD_TABLE(strncmp, ed, i, pr);
EDJE_LOAD_BUILD_TABLE(strrncmp, ed, i, pr);
EDJE_LOAD_BUILD_TABLE(nocmp, ed, i, pr);
}
}
_edje_ref(ed);
@ -1123,34 +1162,47 @@ _edje_file_free(Edje_File *edf)
_edje_file_set(prev);
}
static void
_edje_program_free(Edje_Program *pr, Eina_Bool free_strings)
{
Edje_Program_Target *prt;
Edje_Program_After *pa;
if (free_strings)
{
if (pr->name) eina_stringshare_del(pr->name);
if (pr->signal) eina_stringshare_del(pr->signal);
if (pr->source) eina_stringshare_del(pr->source);
if (pr->filter.part) eina_stringshare_del(pr->filter.part);
if (pr->filter.state) eina_stringshare_del(pr->filter.state);
if (pr->state) eina_stringshare_del(pr->state);
if (pr->state2) eina_stringshare_del(pr->state2);
}
EINA_LIST_FREE(pr->targets, prt)
free(prt);
EINA_LIST_FREE(pr->after, pa)
free(pa);
free(pr);
}
void
_edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec, Edje_Part_Collection_Directory_Entry *ce)
{
Edje_Program *pr;
unsigned int i;
_edje_embryo_script_shutdown(ec);
EINA_LIST_FREE(ec->programs, pr)
{
Edje_Program_Target *prt;
Edje_Program_After *pa;
if (edf->free_strings)
{
if (pr->name) eina_stringshare_del(pr->name);
if (pr->signal) eina_stringshare_del(pr->signal);
if (pr->source) eina_stringshare_del(pr->source);
if (pr->filter.part) eina_stringshare_del(pr->filter.part);
if (pr->filter.state) eina_stringshare_del(pr->filter.state);
if (pr->state) eina_stringshare_del(pr->state);
if (pr->state2) eina_stringshare_del(pr->state2);
}
EINA_LIST_FREE(pr->targets, prt)
free(prt);
EINA_LIST_FREE(pr->after, pa)
free(pa);
free(pr);
}
#define EDJE_LOAD_PROGRAM_FREE(Array, Ec, It, FreeStrings) \
for (It = 0; It < Ec->programs.Array##_count; ++It) \
_edje_program_free(Ec->programs.Array[It], FreeStrings); \
free(Ec->programs.Array);
EDJE_LOAD_PROGRAM_FREE(fnmatch, ec, i, edf->free_strings);
EDJE_LOAD_PROGRAM_FREE(strcmp, ec, i, edf->free_strings);
EDJE_LOAD_PROGRAM_FREE(strncmp, ec, i, edf->free_strings);
EDJE_LOAD_PROGRAM_FREE(strrncmp, ec, i, edf->free_strings);
EDJE_LOAD_PROGRAM_FREE(nocmp, ec, i, edf->free_strings);
for (i = 0; i < ec->parts_count; ++i)
{
Edje_Part *ep;

View File

@ -250,9 +250,9 @@ _edje_match_patterns_exec_init_states(Edje_States *states,
/* Exported function. */
#define EDJE_MATCH_INIT(Func, Type, Source, Show) \
#define EDJE_MATCH_INIT_LIST(Func, Type, Source, Show) \
Edje_Patterns* \
Func(Eina_List *lst) \
Func(const Eina_List *lst) \
{ \
Edje_Patterns *r; \
size_t i; \
@ -312,21 +312,79 @@ _edje_match_patterns_exec_init_states(Edje_States *states,
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);
#define EDJE_MATCH_INIT_ARRAY(Func, Type, Source, Show) \
Edje_Patterns* \
Func(Type * const *lst, unsigned int count) \
{ \
Edje_Patterns *r; \
size_t i; \
\
if (!lst || count == 0) \
return NULL; \
\
r = malloc(sizeof (Edje_Patterns) + \
count \
* sizeof(*r->finals) \
* sizeof(*r->patterns)); \
if (!r) return NULL; \
\
r->ref = 1; \
r->delete_me = 0; \
r->patterns_size = count; \
r->max_length = 0; \
r->patterns = (const char **) r->finals + r->patterns_size + 1; \
\
for (i = 0; i < count; ++i) \
{ \
const char *str; \
size_t j; \
\
if (!lst[i]) \
{ \
free(r); \
return NULL; \
} \
\
str = lst[i]->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; \
\
if (j > r->max_length) \
r->max_length = j; \
} \
\
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);
EDJE_MATCH_INIT_ARRAY(edje_match_programs_signal_init,
Edje_Program,
signal, 0);
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);
static Eina_Bool
_edje_match_collection_dir_exec_finals(const size_t *finals,
@ -345,7 +403,7 @@ 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,
Eina_List *programs,
Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data)
{
@ -360,7 +418,7 @@ edje_match_programs_exec_check_finals(const size_t *signal_finals,
{
Edje_Program *pr;
pr = eina_list_nth(programs, signal_states->states[i].idx);
pr = programs[signal_states->states[i].idx];
if (pr)
{
if (func(pr, data))
@ -487,7 +545,7 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal,
const Edje_Patterns *ppat_source,
const char *signal,
const char *source,
Eina_List *programs,
Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data)
{
@ -609,40 +667,40 @@ _edje_signal_source_key_cmp(const Edje_Signal_Source_Char *node,
Eina_List *
edje_match_program_hash_build(const Eina_List *callbacks,
edje_match_program_hash_build(Edje_Program * const *programs,
unsigned int count,
Eina_Rbtree **tree)
{
Eina_List *result = NULL;
Eina_Rbtree *new = NULL;
Edje_Program *program;
const Eina_List *l;
unsigned int i;
EINA_LIST_FOREACH(callbacks, l, program)
for (i = 0; i < count; ++i)
{
if (program->signal && strpbrk(program->signal, "*?[\\") == NULL
&& program->source && strpbrk(program->source, "*?[\\") == NULL)
if (programs[i]->signal && strpbrk(programs[i]->signal, "*?[\\") == NULL
&& programs[i]->source && strpbrk(programs[i]->source, "*?[\\") == NULL)
{
Edje_Signal_Source_Char *item;
item = (Edje_Signal_Source_Char*) eina_rbtree_inline_lookup(new, program->signal, 0,
EINA_RBTREE_CMP_KEY_CB(_edje_signal_source_key_cmp), program->source);
item = (Edje_Signal_Source_Char*) eina_rbtree_inline_lookup(new, programs[i]->signal, 0,
EINA_RBTREE_CMP_KEY_CB(_edje_signal_source_key_cmp), programs[i]->source);
if (!item)
{
item = malloc(sizeof (Edje_Signal_Source_Char));
if (!item) continue;
item->signal = program->signal;
item->source = program->source;
item->signal = programs[i]->signal;
item->source = programs[i]->source;
item->list = NULL;
new = eina_rbtree_inline_insert(new, EINA_RBTREE_GET(item),
EINA_RBTREE_CMP_NODE_CB(_edje_signal_source_node_cmp), NULL);
}
item->list = eina_list_prepend(item->list, program);
item->list = eina_list_prepend(item->list, programs[i]);
}
else
result = eina_list_prepend(result, program);
result = eina_list_prepend(result, programs[i]);
}
*tree = new;

View File

@ -568,7 +568,22 @@ struct _Edje_Pack_Element
struct _Edje_Part_Collection
{
Eina_List *programs; /* a list of Edje_Program *//* FIXME: use multiple array */
struct { /* list of Edje_Program */
Edje_Program **fnmatch; /* complex match with "*?[\" */
unsigned int fnmatch_count;
Edje_Program **strcmp; /* No special caractere, plain strcmp does the work */
unsigned int strcmp_count;
Edje_Program **strncmp; /* Finish by * or ?, plain strncmp does the work */
unsigned int strncmp_count;
Edje_Program **strrncmp; /* Start with * or ?, reverse strncmp will do the job */
unsigned int strrncmp_count;
Edje_Program **nocmp; /* Empty signal/source that will never match */
unsigned int nocmp_count;
} programs;
Edje_Part **parts; /* an array of Edje_Part */
unsigned int parts_count;
@ -859,12 +874,22 @@ struct _Edje_Signal_Source_Char
};
struct _Edje_Signals_Sources_Patterns
{
Edje_Patterns *signals_patterns;
Edje_Patterns *sources_patterns;
Eina_Rbtree *exact_match;
Eina_List *globing;
union {
struct {
Edje_Program **globing;
unsigned int count;
} programs;
struct {
Eina_List *globing;
} callbacks;
} u;
};
typedef struct _Edje_Signals_Sources_Patterns Edje_Signals_Sources_Patterns;
@ -1284,11 +1309,13 @@ struct _Edje_Patterns
size_t finals[];
};
Edje_Patterns *edje_match_collection_dir_init(Eina_List *lst);
Edje_Patterns *edje_match_programs_signal_init(Eina_List *lst);
Edje_Patterns *edje_match_programs_source_init(Eina_List *lst);
Edje_Patterns *edje_match_callback_signal_init(Eina_List *lst);
Edje_Patterns *edje_match_callback_source_init(Eina_List *lst);
Edje_Patterns *edje_match_collection_dir_init(const Eina_List *lst);
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);
Eina_Bool edje_match_collection_dir_exec(const Edje_Patterns *ppat,
const char *string);
@ -1296,7 +1323,7 @@ Eina_Bool edje_match_programs_exec(const Edje_Patterns *ppat_signal,
const Edje_Patterns *ppat_source,
const char *signal,
const char *source,
Eina_List *programs,
Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data);
int edje_match_callback_exec(Edje_Patterns *ppat_signal,
@ -1308,7 +1335,8 @@ int edje_match_callback_exec(Edje_Patterns *ppat_signal,
void edje_match_patterns_free(Edje_Patterns *ppat);
Eina_List *edje_match_program_hash_build(const Eina_List *callbacks,
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);

View File

@ -1169,7 +1169,7 @@ _edje_callbacks_patterns_clean(Edje *ed)
NULL);
ed->patterns.callbacks.exact_match = NULL;
ed->patterns.callbacks.globing = eina_list_free(ed->patterns.callbacks.globing);
ed->patterns.callbacks.u.callbacks.globing = eina_list_free(ed->patterns.callbacks.u.callbacks.globing);
}
static void
@ -1178,14 +1178,14 @@ _edje_callbacks_patterns_init(Edje *ed)
Edje_Signals_Sources_Patterns *ssp = &ed->patterns.callbacks;
if ((ssp->signals_patterns) || (ssp->sources_patterns) ||
(ssp->globing) || (ssp->exact_match))
(ssp->u.callbacks.globing) || (ssp->exact_match))
return;
ssp->globing = edje_match_callback_hash_build(ed->callbacks,
&ssp->exact_match);
ssp->u.callbacks.globing = edje_match_callback_hash_build(ed->callbacks,
&ssp->exact_match);
ssp->signals_patterns = edje_match_callback_signal_init(ssp->globing);
ssp->sources_patterns = edje_match_callback_source_init(ssp->globing);
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??? */
@ -1258,18 +1258,18 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src)
data.matched = 0;
data.matches = NULL;
#endif
if (ed->collection->programs)
if (ed->table_programs_size > 0)
{
const Eina_List *match;
const Eina_List *l;
Edje_Program *pr;
if (ed->patterns.programs.globing)
if (ed->patterns.programs.u.programs.globing)
if (edje_match_programs_exec(ed->patterns.programs.signals_patterns,
ed->patterns.programs.sources_patterns,
sig,
src,
ed->patterns.programs.globing,
ed->patterns.programs.u.programs.globing,
_edje_glob_callback,
&data) == 0)
goto break_prog;
@ -1334,12 +1334,12 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src)
int r = 1;
_edje_callbacks_patterns_init(ed);
if (ed->patterns.callbacks.globing)
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.globing,
ed->patterns.callbacks.u.callbacks.globing,
ed);
if (!r)