edje: change 'user_defined' member of Edje struct to be a hash

Summary:
this is where all user-added data (e.g., swallowed objects, table/box packs,
text strings) are stored. with this patch, it is now a hash by part name,
storing a list of user-defined data for that part

this simplifies a bit of code by deconstructing some list walks, and
should end up being slightly faster for large edje objects with lots of
user-defined data

ideally no functional changes

Depends on D9206

Reviewers: cedric

Reviewed By: cedric

Subscribers: #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D9208
This commit is contained in:
Mike Blumenkrantz 2019-07-10 14:24:48 -04:00
parent 662572ecfe
commit aa921c553b
3 changed files with 311 additions and 286 deletions

View File

@ -153,7 +153,7 @@ static Eina_Bool _edje_collection_free_prog_cache_matches_free_cb(const Eina_Ha
static void _edje_object_pack_item_hints_set(Evas_Object *obj, Edje_Pack_Element *it);
static void _cb_signal_repeat(void *data, Evas_Object *obj, const char *signal, const char *source);
static Eina_List *_edje_object_collect(Edje *ed);
static Eina_Hash *_edje_object_collect(Edje *ed);
static int _sort_defined_boxes(const void *a, const void *b);
@ -773,7 +773,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
Eina_List *textblocks = NULL;
Eina_List *sources = NULL;
Eina_List *externals = NULL;
Eina_List *collect = NULL;
Eina_Hash *collect = NULL;
unsigned int n;
Eina_Array parts;
int group_path_started = 0;
@ -1592,8 +1592,15 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
{
Edje_User_Defined *eud;
Eina_List *boxes = NULL;
Eina_Iterator *it;
Eina_List *l, *ll;
EINA_LIST_FREE(collect, eud)
it = eina_hash_iterator_data_new(collect);
/* the eud structs get manually freed below */
eina_hash_free_cb_set(collect, (void*)eina_list_free);
EINA_ITERATOR_FOREACH(it, l)
{
EINA_LIST_FOREACH(l, ll, eud)
{
Evas_Object *child = NULL;
@ -1708,16 +1715,15 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
break;
}
}
if (eud) _edje_user_definition_remove(eud, child);
}
}
eina_iterator_free(it);
boxes = eina_list_sort(boxes, -1, _sort_defined_boxes);
EINA_LIST_FREE(boxes, eud)
{
edje_object_part_box_append(obj, eud->part, eud->u.box.child);
_edje_user_definition_remove(eud, eud->u.box.child);
}
eina_hash_free(part_match);
eina_hash_free(collect);
}
if (_edje_language)
snprintf(lang, sizeof(lang), "edje,language,%s", _edje_language);
@ -1833,17 +1839,21 @@ _sort_defined_boxes(const void *a, const void *b)
return euda->u.box.index - eudb->u.box.index;
}
static Eina_List *
static Eina_Hash *
_edje_object_collect(Edje *ed)
{
Edje_User_Defined *eud;
Eina_List *collect;
Eina_List *l;
Eina_Hash *collect;
Eina_List *l, *ll;
Eina_Iterator *it;
collect = ed->user_defined;
ed->user_defined = NULL;
EINA_LIST_FOREACH(collect, l, eud)
it = eina_hash_iterator_data_new(collect);
EINA_ITERATOR_FOREACH(it, l)
{
EINA_LIST_FOREACH(l, ll, eud)
{
switch (eud->type)
{
@ -1915,6 +1925,8 @@ _edje_object_collect(Edje *ed)
break;
}
}
}
eina_iterator_free(it);
return collect;
}
@ -1938,7 +1950,6 @@ _edje_file_callbacks_del(Edje *ed, Evas *e)
void
_edje_file_del(Edje *ed)
{
Edje_User_Defined *eud;
Evas *tev = NULL;
if (ed->obj && (!efl_invalidated_get(ed->obj)))
@ -1972,11 +1983,8 @@ _edje_file_del(Edje *ed)
return;
}
while (ed->user_defined)
{
eud = eina_list_data_get(ed->user_defined);
_edje_user_definition_free(eud);
}
eina_hash_free(ed->user_defined);
ed->user_defined = NULL;
if (ed->table_parts)
{

View File

@ -1738,7 +1738,7 @@ struct _Edje
#endif
double duration_scale;
double paused_at;
Eina_List *user_defined;
Eina_Hash *user_defined;
lua_State *L;
Eina_Inlist *lua_objs;

View File

@ -61,44 +61,67 @@ static void _edje_child_remove(Edje *ed, Edje_Real_Part *rp, Evas_Object *c
Edje_Real_Part *_edje_real_part_recursive_get_helper(Edje **ed, char **path);
static void
_edje_user_definition_free_internal(Edje_User_Defined *eud)
{
Evas_Object *child = NULL;
switch (eud->type)
{
case EDJE_USER_SWALLOW:
child = eud->u.swallow.child;
break;
case EDJE_USER_BOX_PACK:
child = eud->u.box.child;
break;
case EDJE_USER_TABLE_PACK:
child = eud->u.table.child;
break;
default: break;
}
if (child) evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
eina_stringshare_del(eud->part);
free(eud);
}
static void
_edje_user_definition_list_free_internal(Eina_List *l)
{
Edje_User_Defined *eud;
EINA_LIST_FREE(l, eud)
_edje_user_definition_free_internal(eud);
}
static Edje_User_Defined *
_edje_user_definition_new(Edje_User_Defined_Type type, const char *part, Edje *ed)
{
Edje_User_Defined *eud;
if (!ed->user_defined)
ed->user_defined = eina_hash_string_superfast_new((Eina_Free_Cb)_edje_user_definition_list_free_internal);
EINA_SAFETY_ON_NULL_RETURN_VAL(ed->user_defined, NULL);
eud = malloc(sizeof (Edje_User_Defined));
if (!eud) return NULL;
eud->type = type;
eud->part = eina_stringshare_add(part);
eud->ed = ed;
ed->user_defined = eina_list_append(ed->user_defined, eud);
eina_hash_list_direct_append(ed->user_defined, eud->part, eud);
return eud;
}
void
_edje_user_definition_remove(Edje_User_Defined *eud, Evas_Object *child)
{
eud->ed->user_defined = eina_list_remove(eud->ed->user_defined, eud);
if (child) evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
eina_stringshare_del(eud->part);
free(eud);
}
void
_edje_user_definition_free(Edje_User_Defined *eud)
{
Evas_Object *child = NULL;
Edje_Real_Part *rp;
eud->ed->user_defined = eina_list_remove(eud->ed->user_defined, eud);
switch (eud->type)
{
case EDJE_USER_SWALLOW:
child = eud->u.swallow.child;
rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
if (rp)
{
@ -125,15 +148,13 @@ _edje_user_definition_free(Edje_User_Defined *eud)
break;
case EDJE_USER_BOX_PACK:
child = eud->u.box.child;
rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
if (rp) _edje_child_remove(eud->ed, rp, child);
if (rp) _edje_child_remove(eud->ed, rp, eud->u.box.child);
break;
case EDJE_USER_TABLE_PACK:
child = eud->u.table.child;
rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
if (rp) _edje_child_remove(eud->ed, rp, child);
if (rp) _edje_child_remove(eud->ed, rp, eud->u.table.child);
break;
case EDJE_USER_TEXT_STYLE:
@ -155,7 +176,8 @@ _edje_user_definition_free(Edje_User_Defined *eud)
break;
}
_edje_user_definition_remove(eud, child);
eina_hash_list_remove(eud->ed->user_defined, eud->part, eud);
_edje_user_definition_free_internal(eud);
}
static void
@ -2007,15 +2029,11 @@ Edje_User_Defined *
_edje_user_text_style_definition_fetch(Edje *ed, const char *part)
{
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
{
if (eud->type == EDJE_USER_TEXT_STYLE && !strcmp(eud->part, part))
{
break;
}
}
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_TEXT_STYLE) break;
if (!eud)
{
@ -2032,15 +2050,11 @@ Edje_User_Defined *
_edje_user_text_expand_definition_fetch(Edje *ed, const char *part)
{
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
{
if (eud->type == EDJE_USER_TEXT_EXPAND && !strcmp(eud->part, part))
{
break;
}
}
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_TEXT_EXPAND) break;
if (!eud)
{
@ -2059,10 +2073,11 @@ _edje_user_define_string(Edje *ed, const char *part, const char *raw_text, Edje_
rp. So on edje_object_file_set, we should first ref it, before destroying the old
layout. */
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_STRING && !strcmp(eud->part, part))
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_STRING)
{
if (!raw_text)
{
@ -3349,18 +3364,24 @@ _efl_canvas_layout_content_remove(Eo *obj EINA_UNUSED, Edje *ed, Evas_Object *ob
{
Edje_Real_Part *rp;
Edje_User_Defined *eud;
Eina_List *l;
Eina_Iterator *it;
Eina_List *l, *ll;
rp = _swallow_real_part_get(obj_swallow);
if (!rp) return EINA_FALSE;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
it = eina_hash_iterator_data_new(ed->user_defined);
EINA_ITERATOR_FOREACH(it, l)
{
EINA_LIST_FOREACH(l, ll, eud)
if ((eud->type == EDJE_USER_SWALLOW) && (eud->u.swallow.child == obj_swallow))
{
_edje_user_definition_free(eud);
eina_iterator_free(it);
return EINA_TRUE;
}
}
eina_iterator_free(it);
_edje_real_part_swallow_clear(ed, rp);
rp->typedata.swallow->swallowed_object = NULL;
rp->typedata.swallow->swallow_params.min.w = 0;
@ -3899,15 +3920,16 @@ _edje_object_part_drag_value_set(Edje *ed, const char *part, double dx, double d
{
Edje_Real_Part *rp;
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
if ((!ed) || (!part)) return EINA_FALSE;
rp = _edje_real_part_recursive_get(&ed, part);
if (!rp) return EINA_FALSE;
if (!rp->drag) return EINA_FALSE;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_DRAG_VALUE && !strcmp(part, eud->part))
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_DRAG_VALUE)
{
eud->u.drag_position.x = dx;
eud->u.drag_position.y = dy;
@ -3984,15 +4006,16 @@ _edje_object_part_drag_size_set(Edje *ed, const char *part, double dw, double dh
{
Edje_Real_Part *rp;
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
if ((!ed) || (!part)) return EINA_FALSE;
rp = _edje_real_part_recursive_get(&ed, part);
if (!rp) return EINA_FALSE;
if (!rp->drag) return EINA_FALSE;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_DRAG_SIZE && !strcmp(part, eud->part))
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_DRAG_SIZE)
{
eud->u.drag_size.w = dw;
eud->u.drag_size.h = dh;
@ -4063,15 +4086,16 @@ _edje_object_part_drag_step_set(Edje *ed, const char *part, double dx, double dy
{
Edje_Real_Part *rp;
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
if ((!ed) || (!part)) return EINA_FALSE;
rp = _edje_real_part_recursive_get(&ed, part);
if (!rp) return EINA_FALSE;
if (!rp->drag) return EINA_FALSE;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_DRAG_STEP && !strcmp(part, eud->part))
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_DRAG_STEP)
{
eud->u.drag_position.x = dx;
eud->u.drag_position.y = dy;
@ -4135,15 +4159,16 @@ _edje_object_part_drag_page_set(Edje *ed, const char *part, double dx, double dy
{
Edje_Real_Part *rp;
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
if ((!ed) || (!part)) return EINA_FALSE;
rp = _edje_real_part_recursive_get(&ed, part);
if (!rp) return EINA_FALSE;
if (!rp->drag) return EINA_FALSE;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_DRAG_PAGE && !strcmp(part, eud->part))
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_DRAG_PAGE)
{
eud->u.drag_position.x = dx;
eud->u.drag_position.y = dy;
@ -4208,15 +4233,16 @@ _edje_object_part_drag_step(Edje *ed, const char *part, double dx, double dy)
Edje_Real_Part *rp;
FLOAT_T px, py;
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
if ((!ed) || (!part)) return EINA_FALSE;
rp = _edje_real_part_recursive_get(&ed, part);
if (!rp) return EINA_FALSE;
if (!rp->drag) return EINA_FALSE;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_DRAG_STEP && !strcmp(part, eud->part))
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_DRAG_STEP)
{
eud->u.drag_position.x = dx;
eud->u.drag_position.y = dy;
@ -4259,15 +4285,16 @@ _edje_object_part_drag_page(Edje *ed, const char *part, double dx, double dy)
Edje_Real_Part *rp;
FLOAT_T px, py;
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
if ((!ed) || (!part)) return EINA_FALSE;
rp = _edje_real_part_recursive_get(&ed, part);
if (!rp) return EINA_FALSE;
if (!rp->drag) return EINA_FALSE;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_DRAG_PAGE && !strcmp(part, eud->part))
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_DRAG_PAGE)
{
eud->u.drag_position.x = dx;
eud->u.drag_position.y = dy;
@ -4459,6 +4486,21 @@ _edje_part_box_insert_at(Edje *ed, const char *part, Evas_Object *child, unsigne
return ret;
}
static void
_edje_part_box_remove_user_definition(Edje *ed, Eina_Stringshare *part, Evas_Object *child)
{
Edje_User_Defined *eud;
Eina_List *l, *ll;
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_BOX_PACK && eud->u.box.child == child)
{
_edje_user_definition_free(eud);
return;
}
}
Evas_Object *
_edje_part_box_remove(Edje *ed, const char *part, Evas_Object *child)
{
@ -4473,18 +4515,7 @@ _edje_part_box_remove(Edje *ed, const char *part, Evas_Object *child)
r = _edje_real_part_box_remove(ed, rp, child);
if (r)
{
Edje_User_Defined *eud;
Eina_List *l;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_BOX_PACK && eud->u.box.child == child && !strcmp(eud->part, part))
{
_edje_user_definition_free(eud);
return r;
}
}
if (r) _edje_part_box_remove_user_definition(ed, part, r);
return r;
}
@ -4502,18 +4533,7 @@ _edje_part_box_remove_at(Edje *ed, const char *part, unsigned int pos)
r = _edje_real_part_box_remove_at(ed, rp, pos);
if (r)
{
Edje_User_Defined *eud;
Eina_List *l;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
if (eud->type == EDJE_USER_BOX_PACK && eud->u.box.child == r && !strcmp(eud->part, part))
{
_edje_user_definition_free(eud);
return r;
}
}
if (r) _edje_part_box_remove_user_definition(ed, part, r);
return r;
}
@ -4549,15 +4569,7 @@ _edje_part_box_remove_all(Edje *ed, const char *part, Eina_Bool clear)
if (_edje_real_part_box_remove_all(ed, rp, clear))
{
ret = EINA_TRUE;
Edje_User_Defined *eud;
Eina_List *ll, *l;
EINA_LIST_FOREACH_SAFE(ed->user_defined, l, ll, eud)
if (eud->type == EDJE_USER_BOX_PACK && !strcmp(eud->part, part))
{
_edje_user_definition_free(eud);
return ret;
}
eina_hash_del_by_key(ed->user_defined, part);
}
return ret;
@ -4642,16 +4654,16 @@ _edje_child_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child, void *ei
{
Edje_Real_Part *rp = data;
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
Edje *ed = evas_object_data_get(child, ".edje");
if (!ed) return;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
l = eina_hash_find(ed->user_defined, rp->part->name);
EINA_LIST_FOREACH(l, ll, eud)
if (rp->part->type == EDJE_PART_TYPE_BOX)
{
if (eud->type == EDJE_USER_BOX_PACK &&
eud->u.box.child == child &&
!strcmp(rp->part->name, eud->part))
eud->u.box.child == child)
{
_edje_user_definition_free(eud);
break;
@ -4660,8 +4672,7 @@ _edje_child_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child, void *ei
else if (rp->part->type == EDJE_PART_TYPE_TABLE)
{
if (eud->type == EDJE_USER_TABLE_PACK &&
eud->u.table.child == child &&
!strcmp(rp->part->name, eud->part))
eud->u.table.child == child)
{
_edje_user_definition_free(eud);
break;
@ -4952,12 +4963,12 @@ _edje_part_table_unpack(Edje *ed, const char *part, Evas_Object *child_obj)
{
ret = EINA_TRUE;
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
l = eina_hash_find(ed->user_defined, part);
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_TABLE_PACK &&
eud->u.table.child == child_obj &&
!strcmp(part, eud->part))
eud->u.table.child == child_obj)
{
_edje_user_definition_free(eud);
break;
@ -5881,18 +5892,24 @@ void
_edje_object_part_swallow_free_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Edje_User_Defined *eud;
Eina_List *l;
Eina_List *l, *ll;
Eina_Iterator *it;
Edje *ed;
Edje_Real_Part *rp;
ed = evas_object_data_get(obj, ".edje");
if (!ed) return;
EINA_LIST_FOREACH(ed->user_defined, l, eud)
it = eina_hash_iterator_data_new(ed->user_defined);
EINA_ITERATOR_FOREACH(it, l)
{
EINA_LIST_FOREACH(l, ll, eud)
if (eud->type == EDJE_USER_SWALLOW && eud->u.swallow.child == obj)
{
_edje_user_definition_free(eud);
break;
goto out;
}
}
out:
rp = evas_object_data_get(obj, "\377 edje.swallowing_part");
if (rp && (rp->part->type == EDJE_PART_TYPE_SWALLOW))
edje_object_part_unswallow(ed->obj, obj);