edje: reduce parts walk during load time of Edje file.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 16 Dec 2011 10:17:55 +0000 (10:17 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 16 Dec 2011 10:17:55 +0000 (10:17 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/edje@66281 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
NEWS
src/lib/edje_load.c

index 742fdc9..3fc1cc9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 2011-12-16  Cedric Bail
 
        * Fix wrong call to free() in edje_load.
+       * Reduce parts walk to the strict minimum.
diff --git a/NEWS b/NEWS
index e34a719..e238922 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,10 @@
 Edje 1.1.0
 
+Changes since Edje 1.1.0:
+
+Improvements:
+    * speedup load time of Edje file.
+
 Changes since Edje 1.0.0:
 -------------------------
 
index 21df16f..2031a8b 100644 (file)
@@ -262,6 +262,10 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
 {
    Edje *ed;
    Evas *tev;
+   Edje_Real_Part *rp;
+   Eina_List *textblocks = NULL;
+   Eina_List *sources = NULL;
+   Eina_List *externals = NULL;
    Eina_List *old_swallows;
    unsigned int n;
    Eina_List *parts = NULL;
@@ -323,7 +327,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
        else
          {
             unsigned int i;
-            int errors = 0;
 
             /* colorclass stuff */
             for (i = 0; i < ed->collection->parts_count; ++i)
@@ -333,8 +336,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
 
                  ep = ed->collection->parts[i];
 
-                 if (errors)
-                   break;
                  /* Register any color classes in this parts descriptions. */
                  if ((ep->default_desc) && (ep->default_desc->color_class))
                    _edje_color_class_member_add(ed, ep->default_desc->color_class);
@@ -353,12 +354,12 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
             for (n = 0; n < ed->collection->parts_count; n++)
               {
                  Edje_Part *ep;
-                 Edje_Real_Part *rp;
 
                  ep = ed->collection->parts[n];
                  rp = eina_mempool_malloc(_edje_real_part_mp, sizeof(Edje_Real_Part));
                  if (!rp)
                    {
+                       /* FIXME: destroy all allocated ressource, need to have a common exit point */
                       ed->load_error = EDJE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
                        evas_event_thaw(tev);
                        evas_event_thaw_eval(tev);
@@ -407,9 +408,12 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
                        rp->object = evas_object_text_add(ed->base.evas);
                        evas_object_text_font_source_set(rp->object, ed->path);
                        break;
-                    case EDJE_PART_TYPE_SWALLOW:
                     case EDJE_PART_TYPE_GROUP:
+                        sources = eina_list_append(sources, rp);
+                    case EDJE_PART_TYPE_SWALLOW:
                     case EDJE_PART_TYPE_EXTERNAL:
+                        if (ep->type == EDJE_PART_TYPE_EXTERNAL)
+                          externals = eina_list_append(externals, rp);
                        rp->object = evas_object_rectangle_add(ed->base.evas);
                        evas_object_color_set(rp->object, 0, 0, 0, 0);
                        evas_object_pass_events_set(rp->object, 1);
@@ -417,13 +421,16 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
                        _edje_callbacks_focus_add(rp->object, ed, rp);
                        break;
                     case EDJE_PART_TYPE_TEXTBLOCK:
+                       textblocks = eina_list_append(textblocks, rp);
                        rp->object = evas_object_textblock_add(ed->base.evas);
                        break;
                     case EDJE_PART_TYPE_BOX:
+                        sources = eina_list_append(sources, rp);
                        rp->object = evas_object_box_add(ed->base.evas);
                         rp->anim = _edje_box_layout_anim_new(rp->object);
                        break;
                     case EDJE_PART_TYPE_TABLE:
+                        sources = eina_list_append(sources, rp);
                        rp->object = evas_object_table_add(ed->base.evas);
                        break;
                     case EDJE_PART_TYPE_GRADIENT:
@@ -463,7 +470,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
               }
             if (n > 0)
               {
-                 Edje_Real_Part *rp;
                  Eina_List *l;
 
                  ed->table_parts = malloc(sizeof(Edje_Real_Part *) * n);
@@ -587,8 +593,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
             _edje_var_init(ed);
             for (i = 0; i < ed->table_parts_size; i++)
               {
-                 Edje_Real_Part *rp;
-                 
                  rp = ed->table_parts[i];
                  evas_object_show(rp->object);
                  if (_edje_block_break(ed)) break;
@@ -606,11 +610,28 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
             if ((evas_object_clipees_get(ed->base.clipper)) &&
                 (evas_object_visible_get(obj)))
               evas_object_show(ed->base.clipper);
-            
+
             /* instantiate 'internal swallows' */
-            for (i = 0; i < ed->table_parts_size; i++)
+             EINA_LIST_FREE(externals, rp)
+               {
+                  Edje_Part_Description_External *external;
+                  Evas_Object *child_obj;
+
+                  external = (Edje_Part_Description_External *) rp->part->default_desc;
+                  child_obj = _edje_external_type_add(rp->part->source,
+                                                      evas_object_evas_get(ed->obj), ed->obj,
+                                                      external->external_params, rp->part->name);
+                  if (child_obj)
+                    {
+                       _edje_real_part_swallow(rp, child_obj, EINA_TRUE);
+                       rp->param1.external_params = _edje_external_params_parse(child_obj,
+                                                                                external->external_params);
+                       _edje_external_recalc_apply(ed, rp, NULL, rp->chosen_description);
+                    }
+               }
+
+             EINA_LIST_FREE(sources, rp)
               {
-                 Edje_Real_Part *rp;
                  /* XXX: curr_item and pack_it don't require to be NULL since
                   * XXX: they are just used when source != NULL and type == BOX,
                   * XXX: and they're always set in this case, but GCC fails to
@@ -620,8 +641,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
                  unsigned int item_count = 0;
                  Edje_Pack_Element *pack_it = NULL;
                  const char *source = NULL;
-                 
-                 rp = ed->table_parts[i];
 
                  switch (rp->part->type)
                    {
@@ -643,25 +662,9 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
                               }
                          }
                        break;
-                    case EDJE_PART_TYPE_EXTERNAL:
-                         {
-                            Edje_Part_Description_External *external;
-                            Evas_Object *child_obj;
-
-                            external = (Edje_Part_Description_External *) rp->part->default_desc;
-                            child_obj = _edje_external_type_add(rp->part->source,
-                                                                evas_object_evas_get(ed->obj), ed->obj,
-                                                                external->external_params, rp->part->name);
-                            if (child_obj)
-                              {
-                                 _edje_real_part_swallow(rp, child_obj, EINA_TRUE);
-                                 rp->param1.external_params = _edje_external_params_parse(child_obj,
-                                                                                          external->external_params);
-                                 _edje_external_recalc_apply(ed, rp, NULL, rp->chosen_description);
-                              }
-                         }
-                       continue;
                     default:
+                        /* This list should only be filled by group, box or table, nothing else. */
+                        abort();
                        continue;
                    }
 
@@ -682,6 +685,9 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
                         {
                            if (data == group_path_entry)
                              {
+                                 textblocks = eina_list_free(textblocks);
+                                 externals = eina_list_free(externals);
+                                 sources = eina_list_free(sources);
                                 _edje_thaw(ed);
                                 _edje_unblock(ed);
                                 _edje_unref(ed);
@@ -698,7 +704,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
                                 return 0;
                              }
                         }
-                      
+
                       child_obj = edje_object_add(ed->base.evas);
                       group_path = eina_list_append(group_path, group_path_entry);
                       if (rp->part->type == EDJE_PART_TYPE_GROUP)
@@ -708,11 +714,14 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
 
                       if (!_edje_object_file_set_internal(child_obj, file, source, rp->part->name, group_path))
                         {
+                            textblocks = eina_list_free(textblocks);
+                            externals = eina_list_free(externals);
+                            sources = eina_list_free(sources);
                            _edje_thaw(ed);
                            _edje_unblock(ed);
                            _edje_unref(ed);
                            _edje_file_del(ed);
-                           
+
                            if (group_path_started)
                              {
                                 while (group_path)
@@ -794,56 +803,51 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
                    {
                       const char *name;
                       Evas_Object *swallow;
-                      
+
                       name = eina_list_data_get(old_swallows);
                       old_swallows = eina_list_remove_list(old_swallows, old_swallows);
-                      
+
                       swallow = eina_list_data_get(old_swallows);
                       old_swallows = eina_list_remove_list(old_swallows, old_swallows);
-                      
+
                       edje_object_part_swallow(obj, name, swallow);
                       eina_stringshare_del(name);
                    }
               }
-            
+
             _edje_recalc(ed);
             _edje_thaw(ed);
             _edje_unblock(ed);
             _edje_unref(ed);
             ed->load_error = EDJE_LOAD_ERROR_NONE;
             _edje_emit(ed, "load", NULL);
-            /* instantiate 'internal swallows' */
-            for (i = 0; i < ed->table_parts_size; i++)
-              {
-                 Edje_Real_Part *rp;
-                 
-                 rp = ed->table_parts[i];
-                  if ((rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) &&
-                      (rp->part->default_desc))
-                    {
-                      Edje_Part_Description_Text *text;
-                       Edje_Style *stl  = NULL;
-                       const char *style;
-
-                      text = (Edje_Part_Description_Text *) rp->part->default_desc;
-                       style = edje_string_get(&text->text.style);
-                       if (style)
-                         {
-                           Eina_List *l;
-
-                            EINA_LIST_FOREACH(ed->file->styles, l, stl)
-                              {
-                                 if ((stl->name) && (!strcmp(stl->name, style))) break;
-                                 stl = NULL;
-                              }
-                         }
-                       if (stl)
-                         {
-                            if (evas_object_textblock_style_get(rp->object) != stl->style)
-                              evas_object_textblock_style_set(rp->object, stl->style);
-                         }
-                    }
-               }
+
+            /* instantiate 'internal textblock style' */
+             EINA_LIST_FREE(textblocks, rp)
+               if (rp->part->default_desc)
+                 {
+                    Edje_Part_Description_Text *text;
+                    Edje_Style *stl  = NULL;
+                    const char *style;
+
+                    text = (Edje_Part_Description_Text *) rp->part->default_desc;
+                    style = edje_string_get(&text->text.style);
+                    if (style)
+                      {
+                         Eina_List *l;
+
+                         EINA_LIST_FOREACH(ed->file->styles, l, stl)
+                           {
+                              if ((stl->name) && (!strcmp(stl->name, style))) break;
+                              stl = NULL;
+                           }
+                      }
+                    if (stl)
+                      {
+                         if (evas_object_textblock_style_get(rp->object) != stl->style)
+                           evas_object_textblock_style_set(rp->object, stl->style);
+                      }
+                 }
          }
         _edje_entry_init(ed);
         evas_event_thaw(tev);