* edje: split programs type in different stack for later speed improvements.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 4 Aug 2010 14:25:40 +0000 (14:25 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 4 Aug 2010 14:25:40 +0000 (14:25 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/edje@50810 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/edje_convert.c
src/lib/edje_convert.h
src/lib/edje_edit.c
src/lib/edje_load.c
src/lib/edje_match.c
src/lib/edje_private.h
src/lib/edje_program.c

index 0e35c56..af8551c 100644 (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)
index fcc2781..f954f68 100644 (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
index 8fbafeb..97a816a 100644 (file)
@@ -475,6 +475,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)
 {
    /* This function change the id of a given real_part.
@@ -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;
-
-       if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
-         continue;
+#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);
 
-       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)
@@ -573,6 +583,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)
 {
    /* This function switch the id of two parts.
@@ -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;
-
-       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;
-         }
-     }
+#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);
+
+   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");
index 30eedf4..757094f 100644 (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);
-
-   ssp->signals_patterns = edje_match_programs_signal_init(ssp->globing);
-   ssp->sources_patterns = edje_match_programs_source_init(ssp->globing);
+   edje_match_program_hash_build(ed->collection->programs.strcmp,
+                                ed->collection->programs.strcmp_count,
+                                &ssp->exact_match);
+
+   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;
index b7752dd..e71a21f 100644 (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;
index 3f0ed8b..47546c3 100644 (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);
index 72e451e..2cdabac 100644 (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)