From 5665e9573740aba30d3e568e2a9d3a8907d2b175 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 28 Jun 2019 12:25:07 -0400 Subject: [PATCH 1/6] edje: remove _edje_user_definition_fetch() this is an internal function which is never used Differential Revision: https://phab.enlightenment.org/D9205 --- src/lib/edje/edje_private.h | 1 - src/lib/edje/edje_util.c | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 69e36776eb..874a99f622 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -3046,7 +3046,6 @@ Eina_Bool _edje_multisense_internal_vibration_sample_play(Edje *ed, const char * void _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *state); -Edje_User_Defined * _edje_user_definition_fetch(Edje *ed, const char *part, Edje_User_Defined_Type type); Edje_User_Defined * _edje_user_text_style_definition_fetch(Edje *ed, const char *part); Edje_User_Defined * _edje_user_text_expand_definition_fetch(Edje *ed, const char *part); void _edje_user_definition_remove(Edje_User_Defined *eud, Evas_Object *child); diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index 29ebf04482..6dcf287d3b 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -2003,24 +2003,6 @@ _edje_object_part_text_raw_set(Edje *ed, Evas_Object *obj, Edje_Real_Part *rp, c EINA_FALSE, EINA_TRUE); } -Edje_User_Defined * -_edje_user_definition_fetch(Edje *ed, - const char *part, Edje_User_Defined_Type type) -{ - Edje_User_Defined *eud; - Eina_List *l; - - EINA_LIST_FOREACH(ed->user_defined, l, eud) - { - if (eud->type == type && !strcmp(eud->part, part)) - { - return eud; - } - } - eud = _edje_user_definition_new(type, part, ed); - return eud; -} - Edje_User_Defined * _edje_user_text_style_definition_fetch(Edje *ed, const char *part) { From d317488278f5c375adc6eaa00aa45904f3728ab6 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 28 Jun 2019 12:40:40 -0400 Subject: [PATCH 2/6] eina/hash: add direct variants of list append/prepend functions this simplifies the process of manipulating lists inside hashes with a non-copied key @feature Differential Revision: https://phab.enlightenment.org/D9206 --- src/lib/eina/eina_hash.c | 66 ++++++++++++++++++++++++++++++++++++++++ src/lib/eina/eina_hash.h | 30 ++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/lib/eina/eina_hash.c b/src/lib/eina/eina_hash.c index b6465c7df8..92c37e1968 100644 --- a/src/lib/eina/eina_hash.c +++ b/src/lib/eina/eina_hash.c @@ -1407,6 +1407,39 @@ eina_hash_list_append(Eina_Hash *hash, const void *key, const void *data) eina_list_append(NULL, data)); } +EAPI void +eina_hash_list_direct_append(Eina_Hash *hash, const void *key, const void *data) +{ + Eina_Hash_Tuple tuple; + Eina_Hash_Head *hash_head; + Eina_Hash_Element *hash_element; + int key_length; + int key_hash; + + EINA_SAFETY_ON_NULL_RETURN(hash); + EINA_SAFETY_ON_NULL_RETURN(hash->key_hash_cb); + EINA_SAFETY_ON_NULL_RETURN(key); + EINA_SAFETY_ON_NULL_RETURN(data); + EINA_MAGIC_CHECK_HASH(hash); + + _eina_hash_compute(hash, key, &key_length, &key_hash); + + tuple.key = key; + tuple.key_length = key_length; + tuple.data = NULL; + + hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); + if (hash_element) + hash_element->tuple.data = eina_list_append(hash_element->tuple.data, data); + else + eina_hash_add_alloc_by_hash(hash, + key, + key_length, + 0, + key_hash, + eina_list_append(NULL, data)); +} + EAPI void eina_hash_list_prepend(Eina_Hash *hash, const void *key, const void *data) { @@ -1440,6 +1473,39 @@ eina_hash_list_prepend(Eina_Hash *hash, const void *key, const void *data) eina_list_append(NULL, data)); } +EAPI void +eina_hash_list_direct_prepend(Eina_Hash *hash, const void *key, const void *data) +{ + Eina_Hash_Tuple tuple; + Eina_Hash_Head *hash_head; + Eina_Hash_Element *hash_element; + int key_length; + int key_hash; + + EINA_SAFETY_ON_NULL_RETURN(hash); + EINA_SAFETY_ON_NULL_RETURN(hash->key_hash_cb); + EINA_SAFETY_ON_NULL_RETURN(key); + EINA_SAFETY_ON_NULL_RETURN(data); + EINA_MAGIC_CHECK_HASH(hash); + + _eina_hash_compute(hash, key, &key_length, &key_hash); + + tuple.key = key; + tuple.key_length = key_length; + tuple.data = NULL; + + hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); + if (hash_element) + hash_element->tuple.data = eina_list_prepend(hash_element->tuple.data, data); + else + eina_hash_add_alloc_by_hash(hash, + key, + key_length, + 0, + key_hash, + eina_list_append(NULL, data)); +} + EAPI void eina_hash_list_remove(Eina_Hash *hash, const void *key, const void *data) { diff --git a/src/lib/eina/eina_hash.h b/src/lib/eina/eina_hash.h index 16344cfed4..cda625b362 100644 --- a/src/lib/eina/eina_hash.h +++ b/src/lib/eina/eina_hash.h @@ -1035,6 +1035,21 @@ EAPI void eina_hash_foreach(const Eina_Hash *hash, */ EAPI void eina_hash_list_append(Eina_Hash *hash, const void *key, const void *data) EINA_ARG_NONNULL(1, 2, 3); +/** + * @brief Appends data to an #Eina_List inside a hash using eina_hash_direct_add(). + * + * This function is identical to the sequence of calling + * eina_hash_find(), eina_list_append(), eina_hash_set(), + * but with one fewer required hash lookup. + * + * @param[in,out] hash The hash table. + * @param[in] key The key associated with the data. + * @param[in] data The data to append to the list. + * + * @since 1.23 + */ +EAPI void eina_hash_list_direct_append(Eina_Hash *hash, const void *key, const void *data) EINA_ARG_NONNULL(1, 2, 3); + /** * @brief Prepends data to an #Eina_List inside a hash. * @@ -1050,6 +1065,21 @@ EAPI void eina_hash_list_append(Eina_Hash *hash, const void *key, const void *da */ EAPI void eina_hash_list_prepend(Eina_Hash *hash, const void *key, const void *data) EINA_ARG_NONNULL(1, 2, 3); +/** + * @brief Prepends data to an #Eina_List inside a hash using eina_hash_direct_add(). + * + * This function is identical to the sequence of calling + * eina_hash_find(), eina_list_prepend(), eina_hash_set(), + * but with one fewer required hash lookup. + * + * @param[in,out] hash The hash table. + * @param[in] key The key associated with the data. + * @param[in] data The data to prepend to the list. + * + * @since 1.23 + */ +EAPI void eina_hash_list_direct_prepend(Eina_Hash *hash, const void *key, const void *data) EINA_ARG_NONNULL(1, 2, 3); + /** * @brief Removes data from an #Eina_List inside a hash. * From 17be25bfd3c0a48472202984cc81f4183ac20ea5 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 28 Jun 2019 14:27:56 -0400 Subject: [PATCH 3/6] edje: change 'user_defined' member of Edje struct to be a hash 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 Differential Revision: https://phab.enlightenment.org/D9208 --- src/lib/edje/edje_load.c | 348 ++++++++++++++++++------------------ src/lib/edje/edje_private.h | 2 +- src/lib/edje/edje_util.c | 247 +++++++++++++------------ 3 files changed, 311 insertions(+), 286 deletions(-) diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index fa2f4f7d58..786dae00d9 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -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,132 +1592,138 @@ _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) { - Evas_Object *child = NULL; - - if (!eina_hash_find(part_match, eud->part)) + EINA_LIST_FOREACH(l, ll, eud) { - /* part no longer exists */ - 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; - case EDJE_USER_STRING: - case EDJE_USER_DRAG_STEP: - case EDJE_USER_DRAG_PAGE: - case EDJE_USER_DRAG_VALUE: - case EDJE_USER_DRAG_SIZE: - case EDJE_USER_TEXT_STYLE: - case EDJE_USER_TEXT_EXPAND: - default: - break; - } - if (child) + Evas_Object *child = NULL; + + if (!eina_hash_find(part_match, eud->part)) { - WRN("Container part '%s' no longer exists, hiding previously-contained child object", eud->part); - evas_object_hide(child); + /* part no longer exists */ + 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; + case EDJE_USER_STRING: + case EDJE_USER_DRAG_STEP: + case EDJE_USER_DRAG_PAGE: + case EDJE_USER_DRAG_VALUE: + case EDJE_USER_DRAG_SIZE: + case EDJE_USER_TEXT_STYLE: + case EDJE_USER_TEXT_EXPAND: + default: + break; + } + if (child) + { + WRN("Container part '%s' no longer exists, hiding previously-contained child object", eud->part); + evas_object_hide(child); + } } - } - else - { - switch (eud->type) + else { - case EDJE_USER_SWALLOW: - edje_object_part_swallow(obj, eud->part, eud->u.swallow.child); - child = eud->u.swallow.child; - break; - - case EDJE_USER_BOX_PACK: - boxes = eina_list_append(boxes, eud); - eud = NULL; - break; - - case EDJE_USER_TABLE_PACK: - edje_object_part_table_pack(obj, eud->part, eud->u.table.child, - eud->u.table.col, eud->u.table.row, - eud->u.table.colspan, eud->u.table.rowspan); - child = eud->u.table.child; - break; - - case EDJE_USER_DRAG_STEP: - edje_object_part_drag_step_set(obj, eud->part, - eud->u.drag_position.x, - eud->u.drag_position.y); - break; - - case EDJE_USER_DRAG_PAGE: - edje_object_part_drag_page_set(obj, eud->part, - eud->u.drag_position.x, - eud->u.drag_position.y); - break; - - case EDJE_USER_DRAG_VALUE: - edje_object_part_drag_value_set(obj, eud->part, - eud->u.drag_position.x, - eud->u.drag_position.y); - break; - - case EDJE_USER_DRAG_SIZE: - edje_object_part_drag_size_set(obj, eud->part, - eud->u.drag_size.w, - eud->u.drag_size.h); - break; - - case EDJE_USER_STRING: - switch (eud->u.string.type) + switch (eud->type) { - case EDJE_TEXT_TYPE_NORMAL: - edje_object_part_text_set(obj, eud->part, eud->u.string.text); + case EDJE_USER_SWALLOW: + edje_object_part_swallow(obj, eud->part, eud->u.swallow.child); + child = eud->u.swallow.child; break; - case EDJE_TEXT_TYPE_ESCAPED: - edje_object_part_text_escaped_set(obj, eud->part, eud->u.string.text); + + case EDJE_USER_BOX_PACK: + boxes = eina_list_append(boxes, eud); + eud = NULL; break; - case EDJE_TEXT_TYPE_UNESCAPED: - edje_object_part_text_unescaped_set(obj, eud->part, eud->u.string.text); + + case EDJE_USER_TABLE_PACK: + edje_object_part_table_pack(obj, eud->part, eud->u.table.child, + eud->u.table.col, eud->u.table.row, + eud->u.table.colspan, eud->u.table.rowspan); + child = eud->u.table.child; break; - } - eina_stringshare_del(eud->u.string.text); - break; - case EDJE_USER_TEXT_STYLE: - { - Edje_Part_Text_Prop *prop; - EINA_LIST_FREE(eud->u.text_style.props, prop) + case EDJE_USER_DRAG_STEP: + edje_object_part_drag_step_set(obj, eud->part, + eud->u.drag_position.x, + eud->u.drag_position.y); + break; + + case EDJE_USER_DRAG_PAGE: + edje_object_part_drag_page_set(obj, eud->part, + eud->u.drag_position.x, + eud->u.drag_position.y); + break; + + case EDJE_USER_DRAG_VALUE: + edje_object_part_drag_value_set(obj, eud->part, + eud->u.drag_position.x, + eud->u.drag_position.y); + break; + + case EDJE_USER_DRAG_SIZE: + edje_object_part_drag_size_set(obj, eud->part, + eud->u.drag_size.w, + eud->u.drag_size.h); + break; + + case EDJE_USER_STRING: + switch (eud->u.string.type) { - _canvas_layout_user_text_apply(eud, obj, - prop); - free(prop); + case EDJE_TEXT_TYPE_NORMAL: + edje_object_part_text_set(obj, eud->part, eud->u.string.text); + break; + case EDJE_TEXT_TYPE_ESCAPED: + edje_object_part_text_escaped_set(obj, eud->part, eud->u.string.text); + break; + case EDJE_TEXT_TYPE_UNESCAPED: + edje_object_part_text_unescaped_set(obj, eud->part, eud->u.string.text); + break; } + eina_stringshare_del(eud->u.string.text); + break; + + case EDJE_USER_TEXT_STYLE: + { + Edje_Part_Text_Prop *prop; + EINA_LIST_FREE(eud->u.text_style.props, prop) + { + _canvas_layout_user_text_apply(eud, obj, + prop); + free(prop); + } + } + break; + case EDJE_USER_TEXT_EXPAND: + { + efl_canvas_layout_part_text_expand_set( + efl_part(obj, eud->part), + eud->u.text_expand.expand); + } + break; } - break; - case EDJE_USER_TEXT_EXPAND: - { - efl_canvas_layout_part_text_expand_set( - efl_part(obj, eud->part), - eud->u.text_expand.expand); - } - 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); - } + edje_object_part_box_append(obj, eud->part, 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,88 +1839,94 @@ _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) { - switch (eud->type) + EINA_LIST_FOREACH(l, ll, eud) { - case EDJE_USER_STRING: - eud->u.string.text = eina_stringshare_ref(eud->u.string.text); - break; - - case EDJE_USER_BOX_PACK: - if (eud->u.box.index == -1) + switch (eud->type) { - Edje_User_Defined *search; - Edje_Real_Part *rp; - Eina_List *children; - Eina_List *ls; - Evas_Object *child; - int idx = 0; - - rp = _edje_real_part_recursive_get(&ed, eud->part); - if (rp) + case EDJE_USER_STRING: + eud->u.string.text = eina_stringshare_ref(eud->u.string.text); + break; + + case EDJE_USER_BOX_PACK: + if (eud->u.box.index == -1) { - if (rp->part->type != EDJE_PART_TYPE_BOX) continue; + Edje_User_Defined *search; + Edje_Real_Part *rp; + Eina_List *children; + Eina_List *ls; + Evas_Object *child; + int idx = 0; + + rp = _edje_real_part_recursive_get(&ed, eud->part); + if (rp) + { + if (rp->part->type != EDJE_PART_TYPE_BOX) continue; - children = evas_object_box_children_get(rp->object); - EINA_LIST_FREE(children, child) - if (!evas_object_data_get(child, "\377 edje.box_item")) - { - EINA_LIST_FOREACH(l, ls, search) + children = evas_object_box_children_get(rp->object); + EINA_LIST_FREE(children, child) + if (!evas_object_data_get(child, "\377 edje.box_item")) { - if (search->type == EDJE_USER_BOX_PACK && - search->u.box.child == child && - search->part == eud->part /* beauty of stringshare ! */) + EINA_LIST_FOREACH(l, ls, search) { - search->u.box.index = idx++; - break; + if (search->type == EDJE_USER_BOX_PACK && + search->u.box.child == child && + search->part == eud->part /* beauty of stringshare ! */) + { + search->u.box.index = idx++; + break; + } } + _edje_real_part_box_remove(eud->ed, rp, child); } - _edje_real_part_box_remove(eud->ed, rp, child); - } + } } - } - break; - - case EDJE_USER_TABLE_PACK: - { - Edje_Real_Part *rp; + break; - rp = _edje_real_part_recursive_get(&ed, eud->part); - if (rp) + case EDJE_USER_TABLE_PACK: { - if (rp->part->type != EDJE_PART_TYPE_TABLE) continue; - _edje_real_part_table_unpack(eud->ed, rp, eud->u.table.child); + Edje_Real_Part *rp; + + rp = _edje_real_part_recursive_get(&ed, eud->part); + if (rp) + { + if (rp->part->type != EDJE_PART_TYPE_TABLE) continue; + _edje_real_part_table_unpack(eud->ed, rp, eud->u.table.child); + } + break; } - break; - } - case EDJE_USER_SWALLOW: - edje_object_part_unswallow(NULL, eud->u.swallow.child); - break; + case EDJE_USER_SWALLOW: + edje_object_part_unswallow(NULL, eud->u.swallow.child); + break; - case EDJE_USER_TEXT_STYLE: - _canvas_layout_user_text_collect(ed, eud); - break; + case EDJE_USER_TEXT_STYLE: + _canvas_layout_user_text_collect(ed, eud); + break; - case EDJE_USER_DRAG_STEP: - case EDJE_USER_DRAG_PAGE: - case EDJE_USER_DRAG_VALUE: - case EDJE_USER_DRAG_SIZE: - case EDJE_USER_TEXT_EXPAND: - break; + case EDJE_USER_DRAG_STEP: + case EDJE_USER_DRAG_PAGE: + case EDJE_USER_DRAG_VALUE: + case EDJE_USER_DRAG_SIZE: + case EDJE_USER_TEXT_EXPAND: + 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) { diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 874a99f622..cedc4d6fa6 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -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; diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index 6dcf287d3b..e73da61d54 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -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) - if ((eud->type == EDJE_USER_SWALLOW) && (eud->u.swallow.child == obj_swallow)) - { - _edje_user_definition_free(eud); - return EINA_TRUE; - } - + 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) - if (eud->type == EDJE_USER_SWALLOW && eud->u.swallow.child == obj) - { - _edje_user_definition_free(eud); - break; - } + 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); + 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); From 5beeeb3a0130be872f45ddca5c2df61ec8874688 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 28 Jun 2019 14:38:55 -0400 Subject: [PATCH 4/6] edje: fix reapplying markup text on file/group change this was being stored as regular text when it was actually markup @fix Differential Revision: https://phab.enlightenment.org/D9209 --- src/lib/edje/edje_load.c | 5 ++++- src/lib/edje/edje_private.h | 1 + src/lib/edje/edje_util.c | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 786dae00d9..0e257a902d 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -1683,7 +1683,10 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch switch (eud->u.string.type) { case EDJE_TEXT_TYPE_NORMAL: - edje_object_part_text_set(obj, eud->part, eud->u.string.text); + efl_text_set(efl_part(obj, eud->part), eud->u.string.text); + break; + case EDJE_TEXT_TYPE_MARKUP: + efl_text_markup_set(efl_part(obj, eud->part), eud->u.string.text); break; case EDJE_TEXT_TYPE_ESCAPED: edje_object_part_text_escaped_set(obj, eud->part, eud->u.string.text); diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index cedc4d6fa6..c8362dbb56 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -2085,6 +2085,7 @@ struct _Edje_Signal_Callback typedef enum { EDJE_TEXT_TYPE_NORMAL, + EDJE_TEXT_TYPE_MARKUP, EDJE_TEXT_TYPE_ESCAPED, EDJE_TEXT_TYPE_UNESCAPED } Edje_Text_Type; diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index e73da61d54..827c95c0d1 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -2114,7 +2114,8 @@ _edje_efl_text_text_set(Eo *obj, Edje *ed, const char *part, const char *text, } int_ret = _edje_object_part_text_raw_generic_set(ed, obj, rp, part, text, set_markup, legacy); - _edje_user_define_string(ed, part, rp->typedata.text->text, EDJE_TEXT_TYPE_NORMAL); + _edje_user_define_string(ed, part, rp->typedata.text->text, + set_markup ? EDJE_TEXT_TYPE_MARKUP : EDJE_TEXT_TYPE_NORMAL); return int_ret; } From eebbbda686fd3d7074569fe1849361de725bd701 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 28 Jun 2019 15:23:33 -0400 Subject: [PATCH 5/6] edje: improve user-defined data caching to handle data before file is set this adds explicit handling for things like: efl_add(SOMECLASS, parent, efl_text_set(efl_added, "my text") ); on edje-inheriting objects. note that it's still impossible to do something like efl_add(SOMECLASS, parent, efl_text_set(efl_part(efl_added, "somepart"), "my text") ); also add a unit test to verify common behaviors @feature Differential Revision: https://phab.enlightenment.org/D9210 --- src/lib/edje/edje_load.c | 5 + src/lib/edje/edje_util.c | 162 +++++++++++++++------- src/tests/elementary/efl_ui_test_layout.c | 17 +++ 3 files changed, 132 insertions(+), 52 deletions(-) diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 0e257a902d..5170411700 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -779,6 +779,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch int group_path_started = 0; Evas_Object *nested_smart = NULL; char lang[PATH_MAX]; + Eina_Bool had_file; Eina_Hash *part_match = NULL; /* Get data pointer of top-of-stack */ @@ -793,6 +794,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch { return 0; } + had_file = !!ed->file; tev = evas_object_evas_get(obj); evas_event_freeze(tev); @@ -1696,6 +1698,9 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch break; } eina_stringshare_del(eud->u.string.text); + /* string has extra ref in this case */ + if (!had_file) + eina_stringshare_del(eud->u.string.text); break; case EDJE_USER_TEXT_STYLE: diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index 827c95c0d1..5b5692beb3 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -2103,6 +2103,12 @@ _edje_efl_text_text_set(Eo *obj, Edje *ed, const char *part, const char *text, Eina_Bool int_ret; if ((!ed) || (!part)) return EINA_FALSE; + if ((!ed->file) && (!legacy)) + { + _edje_user_define_string(ed, part, eina_stringshare_add(text), + set_markup ? EDJE_TEXT_TYPE_MARKUP : EDJE_TEXT_TYPE_NORMAL); + return EINA_TRUE; + } rp = _edje_real_part_recursive_get(&ed, part); if (!rp) return EINA_FALSE; if ((rp->part->type != EDJE_PART_TYPE_TEXT) && @@ -3035,6 +3041,16 @@ _edje_efl_content_content_set(Edje *ed, const char *part, Efl_Gfx_Entity *obj_sw } } + if (!ed->file) + { + eud = _edje_user_definition_new(EDJE_USER_SWALLOW, part, ed); + if (eud) + { + evas_object_event_callback_add(obj_swallow, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud); + eud->u.swallow.child = obj_swallow; + } + return EINA_TRUE; + } if (!rp) { DBG("cannot swallow part %s: part not exist!", part); @@ -3919,14 +3935,17 @@ _edje_object_part_drag_dir_get(Edje *ed, const char *part) Eina_Bool _edje_object_part_drag_value_set(Edje *ed, const char *part, double dx, double dy) { - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; Edje_User_Defined *eud; 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; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return EINA_FALSE; + if (!rp->drag) return EINA_FALSE; + } l = eina_hash_find(ed->user_defined, part); EINA_LIST_FOREACH(l, ll, eud) @@ -3945,6 +3964,7 @@ _edje_object_part_drag_value_set(Edje *ed, const char *part, double dx, double d eud->u.drag_position.y = dy; } } + if (!ed->file) return EINA_TRUE; if (rp->part->dragable.confine_id != -1) { @@ -4005,14 +4025,17 @@ _edje_object_part_drag_value_get(Edje *ed, const char *part, double *dx, double Eina_Bool _edje_object_part_drag_size_set(Edje *ed, const char *part, double dw, double dh) { - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; Edje_User_Defined *eud; 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; + if (ed->file) + { + if (!rp) return EINA_FALSE; + if (!rp->drag) return EINA_FALSE; + } l = eina_hash_find(ed->user_defined, part); EINA_LIST_FOREACH(l, ll, eud) @@ -4031,6 +4054,7 @@ _edje_object_part_drag_size_set(Edje *ed, const char *part, double dw, double dh eud->u.drag_size.h = dh; } } + if (!ed->file) return EINA_TRUE; if (dw < 0.0) dw = 0.0; else if (dw > 1.0) @@ -4085,14 +4109,17 @@ _edje_object_part_drag_size_get(Edje *ed, const char *part, double *dw, double * Eina_Bool _edje_object_part_drag_step_set(Edje *ed, const char *part, double dx, double dy) { - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; Edje_User_Defined *eud; 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; + if (ed->file) + { + if (!rp) return EINA_FALSE; + if (!rp->drag) return EINA_FALSE; + } l = eina_hash_find(ed->user_defined, part); EINA_LIST_FOREACH(l, ll, eud) @@ -4111,6 +4138,7 @@ _edje_object_part_drag_step_set(Edje *ed, const char *part, double dx, double dy eud->u.drag_position.y = dy; } } + if (!ed->file) return EINA_TRUE; if (dx < 0.0) dx = 0.0; else if (dx > 1.0) @@ -4158,14 +4186,17 @@ _edje_object_part_drag_step_get(Edje *ed, const char *part, double *dx, double * Eina_Bool _edje_object_part_drag_page_set(Edje *ed, const char *part, double dx, double dy) { - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; Edje_User_Defined *eud; 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; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return EINA_FALSE; + if (!rp->drag) return EINA_FALSE; + } l = eina_hash_find(ed->user_defined, part); EINA_LIST_FOREACH(l, ll, eud) @@ -4184,6 +4215,7 @@ _edje_object_part_drag_page_set(Edje *ed, const char *part, double dx, double dy eud->u.drag_position.y = dy; } } + if (!ed->file) return EINA_TRUE; if (dx < 0.0) dx = 0.0; else if (dx > 1.0) @@ -4231,15 +4263,18 @@ _edje_object_part_drag_page_get(Edje *ed, const char *part, double *dx, double * Eina_Bool _edje_object_part_drag_step(Edje *ed, const char *part, double dx, double dy) { - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; FLOAT_T px, py; Edje_User_Defined *eud; 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; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return EINA_FALSE; + if (!rp->drag) return EINA_FALSE; + } l = eina_hash_find(ed->user_defined, part); EINA_LIST_FOREACH(l, ll, eud) @@ -4258,6 +4293,7 @@ _edje_object_part_drag_step(Edje *ed, const char *part, double dx, double dy) eud->u.drag_position.y = dy; } } + if (!ed->file) return EINA_TRUE; px = rp->drag->val.x; py = rp->drag->val.y; @@ -4283,15 +4319,18 @@ _edje_object_part_drag_step(Edje *ed, const char *part, double dx, double dy) Eina_Bool _edje_object_part_drag_page(Edje *ed, const char *part, double dx, double dy) { - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; FLOAT_T px, py; Edje_User_Defined *eud; 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; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return EINA_FALSE; + if (!rp->drag) return EINA_FALSE; + } l = eina_hash_find(ed->user_defined, part); EINA_LIST_FOREACH(l, ll, eud) @@ -4310,6 +4349,7 @@ _edje_object_part_drag_page(Edje *ed, const char *part, double dx, double dy) eud->u.drag_position.y = dy; } } + if (!ed->file) return EINA_TRUE; px = rp->drag->val.x; py = rp->drag->val.y; @@ -4350,16 +4390,19 @@ Eina_Bool _edje_part_box_append(Edje *ed, const char *part, Evas_Object *child) { Eina_Bool ret; - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; ret = EINA_FALSE; if ((!ed) || (!part) || (!child)) return ret; - rp = _edje_real_part_recursive_get(&ed, part); - if (!rp) return ret; - if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return ret; + if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + } - if (_edje_real_part_box_append(ed, rp, child)) + if ((!ed->file) || _edje_real_part_box_append(ed, rp, child)) { Edje_User_Defined *eud; @@ -4379,16 +4422,19 @@ Eina_Bool _edje_part_box_prepend(Edje *ed, const char *part, Evas_Object *child) { Eina_Bool ret; - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; ret = EINA_FALSE; if ((!ed) || (!part)) return ret; - rp = _edje_real_part_recursive_get(&ed, part); - if (!rp) return ret; - if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return ret; + if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + } - if (_edje_real_part_box_prepend(ed, rp, child)) + if ((!ed->file) || _edje_real_part_box_prepend(ed, rp, child)) { Edje_User_Defined *eud; @@ -4407,16 +4453,19 @@ Eina_Bool _edje_part_box_insert_before(Edje *ed, const char *part, Evas_Object *child, const Evas_Object *reference) { Eina_Bool ret; - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; ret = EINA_FALSE; if ((!ed) || (!part)) return ret; - rp = _edje_real_part_recursive_get(&ed, part); - if (!rp) return ret; - if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return ret; + if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + } - if (_edje_real_part_box_insert_before(ed, rp, child, reference)) + if ((!ed->file) || _edje_real_part_box_insert_before(ed, rp, child, reference)) { Edje_User_Defined *eud; @@ -4435,16 +4484,19 @@ Eina_Bool _edje_part_box_insert_after(Edje *ed, const char *part, Evas_Object *child, const Evas_Object *reference) { Eina_Bool ret; - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; ret = EINA_FALSE; if ((!ed) || (!part)) return ret; - rp = _edje_real_part_recursive_get(&ed, part); - if (!rp) return ret; - if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return ret; + if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + } - if (_edje_real_part_box_insert_after(ed, rp, child, reference)) + if ((!ed->file) || _edje_real_part_box_insert_after(ed, rp, child, reference)) { Edje_User_Defined *eud; @@ -4463,16 +4515,19 @@ Eina_Bool _edje_part_box_insert_at(Edje *ed, const char *part, Evas_Object *child, unsigned int pos) { Eina_Bool ret; - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; ret = EINA_FALSE; if ((!ed) || (!part)) return ret; - rp = _edje_real_part_recursive_get(&ed, part); - if (!rp) return ret; - if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return ret; + if (rp->part->type != EDJE_PART_TYPE_BOX) return ret; + } - if (_edje_real_part_box_insert_at(ed, rp, child, pos)) + if ((!ed->file) || _edje_real_part_box_insert_at(ed, rp, child, pos)) { Edje_User_Defined *eud; @@ -4919,17 +4974,20 @@ Eina_Bool _edje_part_table_pack(Edje *ed, const char *part, Evas_Object *child_obj, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan) { Eina_Bool ret; - Edje_Real_Part *rp; + Edje_Real_Part *rp = NULL; Edje_User_Defined *eud; ret = EINA_FALSE; if ((!ed) || (!part)) return ret; - rp = _edje_real_part_recursive_get(&ed, part); - if (!rp) return ret; - if (rp->part->type != EDJE_PART_TYPE_TABLE) return ret; + if (ed->file) + { + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return ret; + if (rp->part->type != EDJE_PART_TYPE_TABLE) return ret; + } - if (_edje_real_part_table_pack(ed, rp, child_obj, col, row, colspan, rowspan)) + if ((!ed->file) || _edje_real_part_table_pack(ed, rp, child_obj, col, row, colspan, rowspan)) { ret = EINA_TRUE; eud = _edje_user_definition_new(EDJE_USER_TABLE_PACK, part, ed); diff --git a/src/tests/elementary/efl_ui_test_layout.c b/src/tests/elementary/efl_ui_test_layout.c index 8f52408cc4..20581d4ae6 100644 --- a/src/tests/elementary/efl_ui_test_layout.c +++ b/src/tests/elementary/efl_ui_test_layout.c @@ -106,6 +106,22 @@ EFL_START_TEST(efl_ui_layout_test_layout_theme) } EFL_END_TEST +EFL_START_TEST(efl_ui_layout_test_api_ordering) +{ + Evas_Object *win, *box; + const char text_text[] = "test text"; + + win = win_add(NULL, "layout", EFL_UI_WIN_TYPE_BASIC); + box = efl_add(EFL_UI_BOX_CLASS, win); + Eo *layout = efl_add(EFL_UI_BUTTON_CLASS, win, + efl_content_set(efl_added, box), + efl_text_set(efl_added, text_text) + ); + ck_assert_ptr_eq(efl_content_get(layout), box); + ck_assert_str_eq(efl_text_get(layout), text_text); +} +EFL_END_TEST + void efl_ui_test_layout(TCase *tc) { tcase_add_test(tc, efl_ui_layout_test_property_bind); @@ -113,4 +129,5 @@ void efl_ui_test_layout(TCase *tc) tcase_add_test(tc, efl_ui_layout_test_layout_api_update_hints); tcase_add_test(tc, efl_ui_layout_test_layout_force); tcase_add_test(tc, efl_ui_layout_test_layout_theme); + tcase_add_test(tc, efl_ui_layout_test_api_ordering); } From 046eac5d302f52c5bf6f2a57040b79f6ab7af7ee Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 28 Jun 2019 15:25:38 -0400 Subject: [PATCH 6/6] edje: fix some small leaks when failing to reapply user-defined data this only occurs when the same text parts don't exist in the new layout, which is an extremely unlikely scenario Differential Revision: https://phab.enlightenment.org/D9211 --- src/lib/edje/edje_load.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 5170411700..40109c0c1b 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -1621,11 +1621,23 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch child = eud->u.table.child; break; case EDJE_USER_STRING: + eina_stringshare_del(eud->u.string.text); + /* string has extra ref in this case */ + if (!had_file) + eina_stringshare_del(eud->u.string.text); + break; case EDJE_USER_DRAG_STEP: case EDJE_USER_DRAG_PAGE: case EDJE_USER_DRAG_VALUE: case EDJE_USER_DRAG_SIZE: + break; case EDJE_USER_TEXT_STYLE: + { + Edje_Part_Text_Prop *prop; + EINA_LIST_FREE(eud->u.text_style.props, prop) + free(prop); + } + break; case EDJE_USER_TEXT_EXPAND: default: break;