From 664e6939fbbfb3cbb646d1db3fe91c6e0f97eae3 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 25 Jan 2012 16:47:38 +0000 Subject: [PATCH] edje: fix use of inherit, overridding and alias. SVN revision: 67537 --- legacy/edje/src/bin/edje_cc.h | 1 + legacy/edje/src/bin/edje_cc_handlers.c | 169 ++++++++++++++++--------- legacy/edje/src/bin/edje_cc_out.c | 49 ++++++- 3 files changed, 161 insertions(+), 58 deletions(-) diff --git a/legacy/edje/src/bin/edje_cc.h b/legacy/edje/src/bin/edje_cc.h index 94fe90e248..0291f29ea3 100644 --- a/legacy/edje/src/bin/edje_cc.h +++ b/legacy/edje/src/bin/edje_cc.h @@ -156,6 +156,7 @@ void data_process_lookups(void); void data_process_scripts(void); void data_process_script_lookups(void); +void part_description_image_cleanup(Edje_Part *ep); int is_verbatim(void); void track_verbatim(int on); diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index 0dd9a7635e..a3c6992a0c 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -847,6 +847,25 @@ _edje_part_description_image_remove(Edje_Part_Description_Image *ed) &(ed->image.tweens[j]->set)); } +void +part_description_image_cleanup(Edje_Part *ep) +{ + Edje_Part_Description_Image *ed; + unsigned int j; + + if (ep->type != EDJE_PART_TYPE_IMAGE) + return ; + + ed = (Edje_Part_Description_Image*) ep->default_desc; + _edje_part_description_image_remove(ed); + + for (j = 0; j < ep->other.desc_count; j++) + { + ed = (Edje_Part_Description_Image*) ep->other.desc[j]; + _edje_part_description_image_remove(ed); + } +} + static Edje_Part_Description_Common * _edje_part_description_alloc(unsigned char type, const char *collection, const char *part) { @@ -2153,8 +2172,10 @@ ob_collections_group(void) static void st_collections_group_name(void) { + Edje_Part_Collection_Directory_Entry *alias; Edje_Part_Collection_Directory_Entry *older; Edje_Part_Collection *current_pc; + Eina_List *l = NULL; check_arg_count(1); @@ -2164,51 +2185,23 @@ st_collections_group_name(void) current_pc->part = current_de->entry; older = eina_hash_find(edje_file->collection, current_de->entry); - - if (older) - { - Edje_Part_Collection *pc; - Eina_List *l; - Code *cd; - unsigned int id = 0; - unsigned int i; - - pc = eina_list_nth(edje_collections, older->id); - cd = eina_list_nth(codes, older->id); - - eina_hash_del(edje_file->collection, current_de->entry, older); - edje_collections = eina_list_remove(edje_collections, pc); - codes = eina_list_remove(codes, cd); - - for (i = 0; i < pc->parts_count; ++i) - { - Edje_Part_Description_Image *ed; - unsigned int j; - - if (pc->parts[i]->type != EDJE_PART_TYPE_IMAGE) - continue ; - - ed = (Edje_Part_Description_Image*) pc->parts[i]->default_desc; - _edje_part_description_image_remove(ed); - - for (j = 0; j < pc->parts[i]->other.desc_count; j++) - { - ed = (Edje_Part_Description_Image*) pc->parts[i]->other.desc[j]; - _edje_part_description_image_remove(ed); - } - } - - EINA_LIST_FOREACH(edje_collections, l, pc) - { - older = eina_hash_find(edje_file->collection, pc->part); - - pc->id = id++; - if (older) older->id = pc->id; - else if (pc->part == current_pc->part) current_de->id = pc->id; - } - } - + if (older) eina_hash_del(edje_file->collection, current_de->entry, older); eina_hash_direct_add(edje_file->collection, current_de->entry, current_de); + + EINA_LIST_FOREACH(aliases, l, alias) + if (strcmp(alias->entry, current_de->entry) == 0) + { + Edje_Part_Collection *pc; + + pc = eina_list_nth(edje_collections, older->id); + INF("overriding alias ('%s' => '%s') by group '%s'", + alias->entry, pc->part, + current_de->entry); + aliases = eina_list_remove_list(aliases, l); + free(alias); + break; + } + } typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data; @@ -2505,6 +2498,8 @@ static void st_collections_group_alias(void) { Edje_Part_Collection_Directory_Entry *alias; + Edje_Part_Collection_Directory_Entry *tmp; + Eina_List *l; check_arg_count(1); @@ -2512,6 +2507,20 @@ st_collections_group_alias(void) alias->id = current_de->id; alias->entry = parse_str(0); + EINA_LIST_FOREACH(aliases, l, tmp) + if (strcmp(alias->entry, tmp->entry) == 0) + { + Edje_Part_Collection *pc; + + pc = eina_list_nth(edje_collections, tmp->id); + INF("overriding alias ('%s' => '%s') to ('%s' => '%s')", + tmp->entry, pc->part, + alias->entry, current_de->entry); + aliases = eina_list_remove_list(aliases, l); + free(tmp); + break; + } + aliases = eina_list_append(aliases, alias); } @@ -2989,21 +2998,57 @@ st_collections_group_parts_part_name(void) static void st_collections_group_parts_part_type(void) { + unsigned int type; + check_arg_count(1); - current_part->type = parse_enum(0, - "NONE", EDJE_PART_TYPE_NONE, - "RECT", EDJE_PART_TYPE_RECTANGLE, - "TEXT", EDJE_PART_TYPE_TEXT, - "IMAGE", EDJE_PART_TYPE_IMAGE, - "SWALLOW", EDJE_PART_TYPE_SWALLOW, - "TEXTBLOCK", EDJE_PART_TYPE_TEXTBLOCK, - "GROUP", EDJE_PART_TYPE_GROUP, - "BOX", EDJE_PART_TYPE_BOX, - "TABLE", EDJE_PART_TYPE_TABLE, - "EXTERNAL", EDJE_PART_TYPE_EXTERNAL, - "PROXY", EDJE_PART_TYPE_PROXY, - NULL); + type = parse_enum(0, + "NONE", EDJE_PART_TYPE_NONE, + "RECT", EDJE_PART_TYPE_RECTANGLE, + "TEXT", EDJE_PART_TYPE_TEXT, + "IMAGE", EDJE_PART_TYPE_IMAGE, + "SWALLOW", EDJE_PART_TYPE_SWALLOW, + "TEXTBLOCK", EDJE_PART_TYPE_TEXTBLOCK, + "GROUP", EDJE_PART_TYPE_GROUP, + "BOX", EDJE_PART_TYPE_BOX, + "TABLE", EDJE_PART_TYPE_TABLE, + "EXTERNAL", EDJE_PART_TYPE_EXTERNAL, + "PROXY", EDJE_PART_TYPE_PROXY, + NULL); + + /* handle type change of inherited part */ + if (type != current_part->type) + { + Edje_Part_Description_Common *new, *previous; + Edje_Part_Collection *pc; + Edje_Part *ep; + unsigned int i; + + /* we don't free old part as we don't remove all reference to them */ + part_description_image_cleanup(current_part); + + pc = eina_list_data_get(eina_list_last(edje_collections)); + ep = current_part; + + previous = ep->default_desc; + if (previous) + { + new = _edje_part_description_alloc(type, pc->part, ep->name); + memcpy(new, previous, sizeof (Edje_Part_Description_Common)); + + ep->default_desc = new; + } + + for (i = 0; i < ep->other.desc_count; i++) + { + previous = ep->other.desc[i]; + new = _edje_part_description_alloc(type, pc->part, ep->name); + memcpy(new, previous, sizeof (Edje_Part_Description_Common)); + ep->other.desc[i] = new; + } + } + + current_part->type = type; } /** @@ -4334,6 +4379,7 @@ st_collections_group_parts_part_description_inherit(void) ied->image = iparent->image; + data_queue_image_remove(&ied->image.id, &ied->image.set); data_queue_copied_image_lookup(&iparent->image.id, &ied->image.id, &ied->image.set); ied->image.tweens = calloc(iparent->image.tweens_count, @@ -4345,6 +4391,7 @@ st_collections_group_parts_part_description_inherit(void) iid = iparent->image.tweens[i]; iid_new = mem_alloc(SZ(Edje_Part_Image_Id)); + data_queue_image_remove(&ied->image.id, &ied->image.set); data_queue_copied_image_lookup(&(iid->id), &(iid_new->id), &(iid_new->set)); ied->image.tweens[i] = iid_new; } @@ -4487,6 +4534,9 @@ st_collections_group_parts_part_description_state(void) if ((ep->default_desc->state.name && !strcmp(s, ep->default_desc->state.name) && ed->state.value == ep->default_desc->state.value) || (!ep->default_desc->state.name && !strcmp(s, "default") && ed->state.value == ep->default_desc->state.value)) { + if (ep->type == EDJE_PART_TYPE_IMAGE) + _edje_part_description_image_remove((Edje_Part_Description_Image*) ed); + free(ed); ep->other.desc_count--; ep->other.desc = realloc(ep->other.desc, @@ -4500,6 +4550,9 @@ st_collections_group_parts_part_description_state(void) { if (!strcmp(s, ep->other.desc[i]->state.name) && ed->state.value == ep->other.desc[i]->state.value) { + if (ep->type == EDJE_PART_TYPE_IMAGE) + _edje_part_description_image_remove((Edje_Part_Description_Image*) ed); + free(ed); ep->other.desc_count--; ep->other.desc = realloc(ep->other.desc, @@ -5081,6 +5134,7 @@ st_collections_group_parts_part_description_image_normal(void) char *name; name = parse_str(0); + data_queue_image_remove(&(ed->image.id), &(ed->image.set)); data_queue_image_lookup(name, &(ed->image.id), &(ed->image.set)); free(name); } @@ -5125,6 +5179,7 @@ st_collections_group_parts_part_description_image_tween(void) sizeof (Edje_Part_Image_Id*) * ed->image.tweens_count); ed->image.tweens[ed->image.tweens_count - 1] = iid; name = parse_str(0); + data_queue_image_remove(&(iid->id), &(iid->set)); data_queue_image_lookup(name, &(iid->id), &(iid->set)); free(name); } diff --git a/legacy/edje/src/bin/edje_cc_out.c b/legacy/edje/src/bin/edje_cc_out.c index f994af3453..76498361c1 100644 --- a/legacy/edje/src/bin/edje_cc_out.c +++ b/legacy/edje/src/bin/edje_cc_out.c @@ -1561,10 +1561,11 @@ data_queue_image_remove(int *dest, Eina_Bool *set) if (il->dest == dest && il->set == set) { image_lookups = eina_list_remove_list(image_lookups, l); + free(il); return ; } } -} + } void data_queue_copied_image_lookup(int *src, int *dest, Eina_Bool *set) @@ -1619,10 +1620,56 @@ data_process_lookups(void) Program_Lookup *program; Group_Lookup *group; Image_Lookup *image; + Eina_List *l2; Eina_List *l; Eina_Hash *images_in_use; void *data; + /* remove all unreferenced Edje_Part_Collection */ + EINA_LIST_FOREACH_SAFE(edje_collections, l, l2, pc) + { + Edje_Part_Collection_Directory_Entry *alias; + Edje_Part_Collection_Directory_Entry *find; + Eina_List *l3; + unsigned int id = 0; + unsigned int i; + + find = eina_hash_find(edje_file->collection, pc->part); + if (find && find->id == pc->id) + continue ; + + EINA_LIST_FOREACH(aliases, l3, alias) + if (alias->id == pc->id) + continue ; + + /* This Edje_Part_Collection is not used at all */ + edje_collections = eina_list_remove_list(edje_collections, l); + l3 = eina_list_nth_list(codes, pc->id); + codes = eina_list_remove_list(codes, l3); + + /* Unref all image used by that group */ + for (i = 0; i < pc->parts_count; ++i) + part_description_image_cleanup(pc->parts[i]); + + /* Correct all id */ + EINA_LIST_FOREACH(edje_collections, l3, pc) + { + Eina_List *l4; + + /* Some group could be removed from the collection, but still be referenced by alias */ + find = eina_hash_find(edje_file->collection, pc->part); + if (pc->id != find->id) find = NULL; + + /* Update all matching alias */ + EINA_LIST_FOREACH(aliases, l4, alias) + if (pc->id == alias->id) + alias->id = id; + + pc->id = id++; + if (find) find->id = pc->id; + } + } + EINA_LIST_FOREACH(edje_collections, l, pc) { unsigned int count = 0;