From 0fd144550877ff0a6f413c025685b7e7d63e6535 Mon Sep 17 00:00:00 2001 From: Jee-Yong Um Date: Tue, 1 Nov 2016 10:59:09 -0700 Subject: [PATCH] edje.object: implement Efl.Observer interface Summary: To remove duplicated lines to handle edje class (color, text, size), observer interface is implemented to Edje.Object. Reviewers: jpeg, cedric Reviewed By: cedric Subscribers: bu5hm4n, cedric Differential Revision: https://phab.enlightenment.org/D4359 Signed-off-by: Cedric BAIL --- src/Makefile_Efl.am | 3 + src/lib/edje/edje_load.c | 8 +- src/lib/edje/edje_main.c | 45 ++- src/lib/edje/edje_object.eo | 4 +- src/lib/edje/edje_private.h | 19 +- src/lib/edje/edje_smart.c | 50 +++ src/lib/edje/edje_text.c | 8 +- src/lib/edje/edje_textblock_styles.c | 6 +- src/lib/edje/edje_util.c | 441 +++-------------------- src/lib/efl/Efl.h | 3 + src/lib/efl/interfaces/efl_observable.eo | 63 ++++ src/lib/efl/interfaces/efl_observer.c | 259 +++++++++++++ src/lib/efl/interfaces/efl_observer.eo | 15 + src/lib/efl/interfaces/efl_types.eot | 6 + 14 files changed, 514 insertions(+), 416 deletions(-) create mode 100644 src/lib/efl/interfaces/efl_observable.eo create mode 100644 src/lib/efl/interfaces/efl_observer.c create mode 100644 src/lib/efl/interfaces/efl_observer.eo diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am index f1ef8f684e..e64a588373 100644 --- a/src/Makefile_Efl.am +++ b/src/Makefile_Efl.am @@ -50,6 +50,8 @@ efl_eolian_files = \ lib/efl/interfaces/efl_io_writer.eo \ lib/efl/interfaces/efl_io_buffer.eo \ lib/efl/interfaces/efl_io_queue.eo \ + lib/efl/interfaces/efl_observer.eo \ + lib/efl/interfaces/efl_observable.eo \ $(efl_eolian_legacy_files) \ $(NULL) @@ -99,6 +101,7 @@ lib/efl/interfaces/efl_io_sizer.c \ lib/efl/interfaces/efl_io_writer.c \ lib/efl/interfaces/efl_io_buffer.c \ lib/efl/interfaces/efl_io_queue.c \ +lib/efl/interfaces/efl_observer.c \ $(NULL) lib_efl_libefl_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_srcdir)/src/lib/efl @EFL_CFLAGS@ -DEFL_GFX_FILTER_BETA diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 9df43141a6..3751fae34a 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -637,7 +637,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch /* 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); + efl_observable_observer_add(_edje_color_class_member, ep->default_desc->color_class, obj); for (k = 0; k < ep->other.desc_count; k++) { @@ -646,7 +646,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch desc = ep->other.desc[k]; if (desc->color_class) - _edje_color_class_member_add(ed, desc->color_class); + efl_observable_observer_add(_edje_color_class_member, desc->color_class, obj); } } /* sizeclass stuff */ @@ -659,7 +659,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch /* Register any size classes in this parts descriptions. */ if ((ep->default_desc) && (ep->default_desc->size_class)) - _edje_size_class_member_add(ed, ep->default_desc->size_class); + efl_observable_observer_add(_edje_size_class_member, ep->default_desc->size_class, obj); for (k = 0; k < ep->other.desc_count; k++) { @@ -668,7 +668,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch desc = ep->other.desc[k]; if (desc->size_class) - _edje_size_class_member_add(ed, desc->size_class); + efl_observable_observer_add(_edje_size_class_member, desc->size_class, obj); } } /* build real parts */ diff --git a/src/lib/edje/edje_main.c b/src/lib/edje/edje_main.c index 7bb4774b71..f6d8462e35 100644 --- a/src/lib/edje/edje_main.c +++ b/src/lib/edje/edje_main.c @@ -90,6 +90,7 @@ edje_init(void) _edje_message_init(); _edje_multisense_init(); edje_signal_init(); + _edje_class_init(); _edje_real_part_mp = eina_mempool_add("chained_mempool", "Edje_Real_Part", NULL, @@ -130,14 +131,13 @@ shutdown_all: eina_mempool_del(_edje_real_part_mp); _edje_real_part_state_mp = NULL; _edje_real_part_mp = NULL; + _edje_class_shutdown(); _edje_message_shutdown(); _edje_module_shutdown(); _edje_external_shutdown(); _edje_box_shutdown(); _edje_internal_proxy_shutdown(); - _edje_text_class_members_free(); _edje_text_class_hash_free(); - _edje_size_class_members_free(); _edje_size_class_hash_free(); _edje_edd_shutdown(); efreet_shutdown(); @@ -169,7 +169,6 @@ _edje_shutdown_core(void) EINA_LOG_STATE_SHUTDOWN); _edje_file_cache_shutdown(); - _edje_color_class_members_free(); _edje_color_class_hash_free(); eina_stringshare_del(_edje_cache_path); @@ -182,15 +181,14 @@ _edje_shutdown_core(void) _edje_real_part_state_mp = NULL; _edje_real_part_mp = NULL; + _edje_class_shutdown(); edje_signal_shutdown(); _edje_multisense_shutdown(); _edje_message_shutdown(); _edje_module_shutdown(); _edje_external_shutdown(); _edje_box_shutdown(); - _edje_text_class_members_free(); _edje_text_class_hash_free(); - _edje_size_class_members_free(); _edje_size_class_hash_free(); _edje_edd_shutdown(); @@ -249,6 +247,37 @@ edje_shutdown(void) } /* Private Routines */ +void +_edje_class_init(void) +{ + if (!_edje_color_class_member) + _edje_color_class_member = efl_add(EFL_OBSERVABLE_CLASS, NULL); + if (!_edje_text_class_member) + _edje_text_class_member = efl_add(EFL_OBSERVABLE_CLASS, NULL); + if (!_edje_size_class_member) + _edje_size_class_member = efl_add(EFL_OBSERVABLE_CLASS, NULL); +} + +void +_edje_class_shutdown(void) +{ + if (_edje_color_class_member) + { + efl_del(_edje_color_class_member); + _edje_color_class_member = NULL; + } + if (_edje_text_class_member) + { + efl_del(_edje_text_class_member); + _edje_text_class_member = NULL; + } + if (_edje_size_class_member) + { + efl_del(_edje_size_class_member); + _edje_size_class_member = NULL; + } +} + void _edje_del(Edje *ed) { @@ -286,9 +315,9 @@ _edje_del(Edje *ed) free(cb); } - _edje_color_class_member_clean(ed); - _edje_text_class_members_clean(ed); - _edje_size_class_members_clean(ed); + efl_observable_observer_clean(_edje_color_class_member, ed->obj); + efl_observable_observer_clean(_edje_text_class_member, ed->obj); + efl_observable_observer_clean(_edje_size_class_member, ed->obj); } void diff --git a/src/lib/edje/edje_object.eo b/src/lib/edje/edje_object.eo index 21602755ef..c05cd0efe1 100644 --- a/src/lib/edje/edje_object.eo +++ b/src/lib/edje/edje_object.eo @@ -1,6 +1,7 @@ import edje_types; -class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part) +class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part, + Efl.Observer) { legacy_prefix: edje_object; eo_prefix: edje_obj; @@ -2084,6 +2085,7 @@ class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part) Efl.Container.content_remove; Efl.Container.content_part_name.get; Efl.Part.part; + Efl.Observer.update; } events { recalc; [[Edje re-calculated the object.]] diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 4b4b46abea..3e610d2639 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -2496,26 +2496,14 @@ Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part); Edje_Real_Part *_edje_real_part_recursive_get(Edje **ed, const char *part); Edje_Color_Class *_edje_color_class_find(const Edje *ed, const char *color_class); Edje_Color_Class *_edje_color_class_recursive_find(const Edje *ed, const char *color_class); -void _edje_color_class_member_add(Edje *ed, const char *color_class); -void _edje_color_class_member_del(Edje *ed, const char *color_class); -void _edje_color_class_member_clean(Edje *ed); void _edje_color_class_on_del(Edje *ed, Edje_Part *ep); -void _edje_color_class_members_free(void); void _edje_color_class_hash_free(void); const char * _edje_find_alias(Eina_Hash *aliased, char *src, int *length); Edje_Text_Class *_edje_text_class_find(Edje *ed, const char *text_class); -void _edje_text_class_member_add(Edje *ed, const char *text_class); -void _edje_text_class_member_del(Edje *ed, const char *text_class); -void _edje_text_class_members_free(void); void _edje_text_class_hash_free(void); -void _edje_text_class_members_clean(Edje *ed); Edje_Size_Class *_edje_size_class_find(Edje *ed, const char *size_class); -void _edje_size_class_member_add(Edje *ed, const char *size_class); -void _edje_size_class_member_del(Edje *ed, const char *size_class); -void _edje_size_class_members_free(void); void _edje_size_class_hash_free(void); -void _edje_size_class_members_clean(Edje *ed); Edje *_edje_fetch(const Evas_Object *obj) EINA_PURE; int _edje_util_freeze(Edje *ed); int _edje_util_thaw(Edje *ed); @@ -2895,6 +2883,13 @@ void _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params void _edje_user_definition_remove(Edje_User_Defined *eud, Evas_Object *child); void _edje_user_definition_free(Edje_User_Defined *eud); +extern Efl_Observable *_edje_color_class_member; +extern Efl_Observable *_edje_text_class_member; +extern Efl_Observable *_edje_size_class_member; + +void _edje_class_init(void); +void _edje_class_shutdown(void); + void _scale_set(Eo *obj, void *_pd, va_list *list); void _scale_get(Eo *obj, void *_pd, va_list *list); void _base_scale_get(Eo *obj, void *_pd, va_list *list); diff --git a/src/lib/edje/edje_smart.c b/src/lib/edje/edje_smart.c index 7e8105aa30..b769f59dd8 100644 --- a/src/lib/edje/edje_smart.c +++ b/src/lib/edje/edje_smart.c @@ -490,4 +490,54 @@ _edje_object_efl_canvas_object_paragraph_direction_set(Eo *obj, Edje *ed, Evas_B efl_canvas_group_need_recalculate_set(obj, 1); } +EOLIAN static void +_edje_object_efl_observer_update(Eo *obj EINA_UNUSED, Edje *ed, Efl_Object *obs, const char *key, void *data) +{ + if (!obs) return; + + ed->dirty = EINA_TRUE; + ed->recalc_call = EINA_TRUE; + + if ((obs == _edje_color_class_member) || (obs == _edje_size_class_member)) + { +#ifdef EDJE_CALC_CACHE + ed->all_part_change = EINA_TRUE; +#endif + } + else if (obs == _edje_text_class_member) + { + _edje_textblock_styles_cache_free(ed, key); + _edje_textblock_style_all_update(ed); +#ifdef EDJE_CALC_CACHE + ed->text_part_change = EINA_TRUE; +#endif + } + + _edje_recalc(ed); + + if (obs == _edje_color_class_member) + { + if (data) + _edje_emit(ed, (const char *)data, key); + + if ((ed->file) && (ed->file->color_tree)) + { + Edje_Color_Tree_Node *ctn = NULL; + Eina_List *l = NULL; + char *name; + + EINA_LIST_FOREACH(ed->file->color_tree, l, ctn) + { + if (!strcmp(ctn->name, key) && (ctn->color_classes)) + { + EINA_LIST_FOREACH(ctn->color_classes, l, name) + efl_observable_observers_update(_edje_color_class_member, name, data); + + break; + } + } + } + } +} + #include "edje_object.eo.c" diff --git a/src/lib/edje/edje_text.c b/src/lib/edje/edje_text.c index f622714274..517cdabbd6 100644 --- a/src/lib/edje/edje_text.c +++ b/src/lib/edje/edje_text.c @@ -82,14 +82,14 @@ _edje_text_part_on_add(Edje *ed, Edje_Real_Part *ep) /* if text class exists for this part, add the edje to the tc member list */ desc = (Edje_Part_Description_Text *)pt->default_desc; if ((pt->default_desc) && (desc->text.text_class)) - _edje_text_class_member_add(ed, desc->text.text_class); + efl_observable_observer_add(_edje_text_class_member, desc->text.text_class, ed->obj); /* If any other classes exist add them */ for (i = 0; i < pt->other.desc_count; ++i) { desc = (Edje_Part_Description_Text *)pt->other.desc[i]; if ((desc) && (desc->text.text_class)) - _edje_text_class_member_add(ed, desc->text.text_class); + efl_observable_observer_add(_edje_text_class_member, desc->text.text_class, ed->obj); } } @@ -105,13 +105,13 @@ _edje_text_part_on_del(Edje *ed, Edje_Part *pt) desc = (Edje_Part_Description_Text *)pt->default_desc; if ((pt->default_desc) && (desc->text.text_class)) - _edje_text_class_member_del(ed, desc->text.text_class); + efl_observable_observer_del(_edje_text_class_member, desc->text.text_class, ed->obj); for (i = 0; i < pt->other.desc_count; ++i) { desc = (Edje_Part_Description_Text *)pt->other.desc[i]; if (desc->text.text_class) - _edje_text_class_member_del(ed, desc->text.text_class); + efl_observable_observer_del(_edje_text_class_member, desc->text.text_class, ed->obj); } } diff --git a/src/lib/edje/edje_textblock_styles.c b/src/lib/edje/edje_textblock_styles.c index 9b9d921164..e4d18510fb 100644 --- a/src/lib/edje/edje_textblock_styles.c +++ b/src/lib/edje/edje_textblock_styles.c @@ -310,7 +310,7 @@ _edje_textblock_style_member_add(Edje *ed, Edje_Style *stl) { if (tag->text_class) { - _edje_text_class_member_add(ed, tag->text_class); + efl_observable_observer_add(_edje_text_class_member, tag->text_class, ed->obj); /* Newly added text_class member should be updated according to the latest text_class's status. */ @@ -377,7 +377,7 @@ _edje_textblock_styles_del(Edje *ed, Edje_Part *pt) EINA_LIST_FOREACH(stl->tags, l, tag) { if (tag->text_class) - _edje_text_class_member_del(ed, tag->text_class); + efl_observable_observer_del(_edje_text_class_member, tag->text_class, ed->obj); } } @@ -403,7 +403,7 @@ _edje_textblock_styles_del(Edje *ed, Edje_Part *pt) EINA_LIST_FOREACH(stl->tags, l, tag) { if (tag->text_class) - _edje_text_class_member_del(ed, tag->text_class); + efl_observable_observer_del(_edje_text_class_member, tag->text_class, ed->obj); } } } diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index 4432821d14..83c37d5859 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -17,13 +17,12 @@ struct _Edje_Box_Layout }; static Eina_Hash *_edje_color_class_hash = NULL; -static Eina_Hash *_edje_color_class_member_hash = NULL; - static Eina_Hash *_edje_text_class_hash = NULL; -static Eina_Hash *_edje_text_class_member_hash = NULL; - static Eina_Hash *_edje_size_class_hash = NULL; -static Eina_Hash *_edje_size_class_member_hash = NULL; + +Efl_Observable *_edje_color_class_member = NULL; +Efl_Observable *_edje_text_class_member = NULL; +Efl_Observable *_edje_size_class_member = NULL; static Eina_Rbtree *_edje_box_layout_registry = NULL; @@ -156,116 +155,6 @@ _edje_user_def_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child EINA_U _edje_user_definition_free(eud); } -static void -_edje_class_member_add(Edje *ed, Eina_Hash **ghash, const char *class) -{ - Eina_Hash *members; - Edje_Refcount *er; - - if ((!ed) || (!ghash) || (!class)) return; - - if (!*ghash) *ghash = eina_hash_string_superfast_new(NULL); - - members = eina_hash_find(*ghash, class); - if (!members) - { - members = eina_hash_pointer_new(NULL); - eina_hash_add(*ghash, class, members); - } - - er = eina_hash_find(members, &ed); - if (!er) - { - er = calloc(1, sizeof (Edje_Refcount)); - er->ed = ed; - EINA_REFCOUNT_INIT(er); - - eina_hash_direct_add(members, &er->ed, er); - } - else - { - EINA_REFCOUNT_REF(er); - } -} - -static void -_edje_class_member_del(Edje *ed, Eina_Hash **ghash, const char *class) -{ - Edje_Refcount *lookup; - Eina_Hash *members; - - if ((!ed) || (!ghash) || (!class)) return; - members = eina_hash_find(*ghash, class); - if (!members) return; - - lookup = eina_hash_find(members, &ed); - if (!lookup) return; - - EINA_REFCOUNT_UNREF(lookup) - { - eina_hash_del(members, &lookup->ed, lookup); - free(lookup); - - if (eina_hash_population(members) == 0) - { - eina_hash_del(*ghash, class, members); - eina_hash_free(members); - } - } -} - -static void -_edje_class_members_free(Eina_Hash **ghash) -{ - Eina_Iterator *it; - Eina_Hash *members; - - if (!ghash || !*ghash) return; - - it = eina_hash_iterator_data_new(*ghash); - EINA_ITERATOR_FOREACH(it, members) - { - Eina_Iterator *it2; - Edje_Refcount *er; - - it2 = eina_hash_iterator_data_new(members); - EINA_ITERATOR_FOREACH(it2, er) - free(er); - eina_iterator_free(it2); - - eina_hash_free(members); - } - eina_iterator_free(it); - - eina_hash_free(*ghash); - *ghash = NULL; -} - -static void -_edje_class_members_clean(Edje *ed, Eina_Hash *ghash) -{ - Eina_Iterator *it; - Eina_Hash *members; - - if (!ed || !ghash) return; - - it = eina_hash_iterator_data_new(ghash); - EINA_ITERATOR_FOREACH(it, members) - { - Edje_Refcount *lookup; - - lookup = eina_hash_find(members, &ed); - if (!lookup) continue; - - EINA_REFCOUNT_UNREF(lookup) - { - eina_hash_del(members, &lookup->ed, lookup); - free(lookup); - } - } - eina_iterator_free(it); -} - /************************** API Routines **************************/ #define FASTFREEZE 1 @@ -749,41 +638,6 @@ _edje_color_class_get_internal(Edje_Color_Class *cc, Edje_Color_Class_Mode mode, } } -static void -_edje_color_class_apply(const char *color_class, const char *parent) -{ - Eina_Hash *members; - Eina_Iterator *it; - Edje_Refcount *er; - Edje_Color_Tree_Node *ctn; - Eina_List *l, *ll; - char *name; - - members = eina_hash_find(_edje_color_class_member_hash, color_class); - if (!members) return; - it = eina_hash_iterator_data_new(members); - EINA_ITERATOR_FOREACH(it, er) - { - er->ed->dirty = EINA_TRUE; - er->ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - er->ed->all_part_change = EINA_TRUE; -#endif - _edje_recalc(er->ed); - _edje_emit(er->ed, "color_class,set", parent); - - if (!er->ed->file) continue; - - EINA_LIST_FOREACH(er->ed->file->color_tree, l, ctn) - { - if ((!strcmp(ctn->name, color_class)) && (ctn->color_classes)) - EINA_LIST_FOREACH(ctn->color_classes, ll, name) - _edje_color_class_apply(name, parent); - } - } - eina_iterator_free(it); -} - EAPI Eina_Bool edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3) { @@ -809,7 +663,7 @@ _edje_object_global_color_class_set(Efl_Class *klass EINA_UNUSED, void *pd EINA_ int_ret = _edje_color_class_set_internal(_edje_color_class_hash, color_class, mode, r, g, b, a, &need_update); if ((int_ret) && (need_update)) - _edje_color_class_apply(color_class, color_class); + efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,set"); return int_ret; } @@ -844,9 +698,6 @@ EAPI void edje_color_class_del(const char *color_class) { Edje_Color_Class *cc; - Eina_Hash *members; - Eina_Iterator *it; - Edje_Refcount *er; if (!color_class) return; @@ -857,20 +708,7 @@ edje_color_class_del(const char *color_class) eina_stringshare_del(cc->name); free(cc); - members = eina_hash_find(_edje_color_class_member_hash, color_class); - if (!members) return; - it = eina_hash_iterator_data_new(members); - EINA_ITERATOR_FOREACH(it, er) - { - er->ed->dirty = EINA_TRUE; - er->ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - er->ed->all_part_change = EINA_TRUE; -#endif - _edje_recalc(er->ed); - _edje_emit(er->ed, "color_class,del", color_class); - } - eina_iterator_free(it); + efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,del"); } Eina_List * @@ -900,42 +738,40 @@ static Eina_Bool _edje_color_class_active_iterator_next(Eina_Iterator *it, void **data) { Edje_Active_Color_Class_Iterator *et = (void *)it; - Eina_Hash_Tuple *tuple = NULL; - Edje_Refcount *er = NULL; - Eina_Iterator *ith; + Efl_Observable_Tuple *tuple = NULL; + Efl_Observer *o; + Edje *ed; Edje_Color_Class *cc = NULL; - Eina_Bool r = EINA_FALSE; if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE; if (!tuple) return EINA_FALSE; - ith = eina_hash_iterator_data_new(tuple->data); - if (!eina_iterator_next(ith, (void **)&er)) goto on_error; + if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE; + + ed = efl_data_scope_get(o, EDJE_OBJECT_CLASS); + if (!ed) return EINA_FALSE; /* We actually need to ask on an object to get the correct value. It is being assumed that the color key are the same for all object here. This can some times not be the case, but for now we should be fine. */ - cc = _edje_color_class_find(er->ed, tuple->key); - if (!cc) goto on_error; + cc = _edje_color_class_find(ed, tuple->key); + if (!cc) return EINA_FALSE; et->cc = *cc; /* Any of the Edje object referenced should have a file with a valid description for this color class. Let's bet on that for now. */ - if (er->ed->file) - cc = eina_hash_find(er->ed->file->color_hash, tuple->key); - if (!cc) goto on_error; + if (ed->file) + cc = eina_hash_find(ed->file->color_hash, tuple->key); + if (!cc) return EINA_FALSE; et->cc.desc = cc->desc; *data = &et->cc; - r = EINA_TRUE; - on_error: - eina_iterator_free(ith); - return r; + return EINA_TRUE; } static void * @@ -959,12 +795,12 @@ edje_color_class_active_iterator_new(void) { Edje_Active_Color_Class_Iterator *it; - if (!_edje_color_class_member_hash) return NULL; + if (!_edje_color_class_member) return NULL; it = calloc(1, sizeof (Edje_Active_Color_Class_Iterator)); if (!it) return NULL; EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - it->classes = eina_hash_iterator_tuple_new(_edje_color_class_member_hash); + it->classes = efl_observable_iterator_tuple_new(_edje_color_class_member); it->iterator.version = EINA_ITERATOR_VERSION; it->iterator.next = _edje_color_class_active_iterator_next; @@ -1218,9 +1054,6 @@ on_error: EAPI Eina_Bool edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size) { - Eina_Hash *members; - Eina_Iterator *it; - Edje_Refcount *er; Edje_Text_Class *tc; if (!text_class) return EINA_FALSE; @@ -1257,20 +1090,8 @@ edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size siz } /* Tell all members of the text class to recalc */ - members = eina_hash_find(_edje_text_class_member_hash, text_class); - it = eina_hash_iterator_data_new(members); - EINA_ITERATOR_FOREACH(it, er) - { - er->ed->dirty = EINA_TRUE; - er->ed->recalc_call = EINA_TRUE; - _edje_textblock_styles_cache_free(er->ed, text_class); - _edje_textblock_style_all_update(er->ed); -#ifdef EDJE_CALC_CACHE - er->ed->text_part_change = EINA_TRUE; -#endif - _edje_recalc(er->ed); - } - eina_iterator_free(it); + efl_observable_observers_update(_edje_text_class_member, text_class, NULL); + return EINA_TRUE; } @@ -1302,9 +1123,6 @@ EAPI void edje_text_class_del(const char *text_class) { Edje_Text_Class *tc; - Eina_Hash *members; - Eina_Iterator *it; - Edje_Refcount *er; if (!text_class) return; @@ -1316,19 +1134,7 @@ edje_text_class_del(const char *text_class) eina_stringshare_del(tc->font); free(tc); - members = eina_hash_find(_edje_text_class_member_hash, text_class); - it = eina_hash_iterator_data_new(members); - EINA_ITERATOR_FOREACH(it, er) - { - er->ed->dirty = EINA_TRUE; - _edje_textblock_styles_cache_free(er->ed, text_class); - _edje_textblock_style_all_update(er->ed); -#ifdef EDJE_CALC_CACHE - er->ed->text_part_change = EINA_TRUE; -#endif - _edje_recalc(er->ed); - } - eina_iterator_free(it); + efl_observable_observers_update(_edje_text_class_member, text_class, NULL); } Eina_List * @@ -1355,33 +1161,31 @@ static Eina_Bool _edje_text_class_active_iterator_next(Eina_Iterator *it, void **data) { Edje_Active_Text_Class_Iterator *et = (void *)it; - Eina_Hash_Tuple *tuple = NULL; - Edje_Refcount *er = NULL; - Eina_Iterator *ith; + Efl_Observable_Tuple *tuple = NULL; + Efl_Observer *o; + Edje *ed; Edje_Text_Class *tc; - Eina_Bool r = EINA_FALSE; if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE; if (!tuple) return EINA_FALSE; - ith = eina_hash_iterator_data_new(tuple->data); - if (!eina_iterator_next(ith, (void **)&er)) goto on_error; + if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE; + + ed = efl_data_scope_get(o, EDJE_OBJECT_CLASS); + if (!ed) return EINA_FALSE; /* We actually need to ask on an object to get the correct value. It is being assumed that the size key are the same for all object here. This can some times not be the case, but for now we should be fine. */ - tc = _edje_text_class_find(er->ed, tuple->key); - if (!tc) goto on_error; + tc = _edje_text_class_find(ed, tuple->key); + if (!tc) return EINA_FALSE; et->tc = *tc; *data = &et->tc; - r = EINA_TRUE; - on_error: - eina_iterator_free(ith); - return r; + return EINA_TRUE; } static void * @@ -1405,12 +1209,12 @@ edje_text_class_active_iterator_new(void) { Edje_Active_Text_Class_Iterator *it; - if (!_edje_text_class_member_hash) return NULL; + if (!_edje_text_class_member) return NULL; it = calloc(1, sizeof (Edje_Active_Text_Class_Iterator)); if (!it) return NULL; EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - it->classes = eina_hash_iterator_tuple_new(_edje_text_class_member_hash); + it->classes = efl_observable_iterator_tuple_new(_edje_text_class_member); it->iterator.version = EINA_ITERATOR_VERSION; it->iterator.next = _edje_text_class_active_iterator_next; @@ -1489,14 +1293,7 @@ _edje_object_text_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *text_clas text_class, font, size); } - ed->dirty = EINA_TRUE; - ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - ed->text_part_change = EINA_TRUE; -#endif - _edje_textblock_styles_cache_free(ed, text_class); - _edje_textblock_style_all_update(ed); - _edje_recalc(ed); + efl_observer_update(obj, _edje_text_class_member, text_class, NULL); return EINA_TRUE; } @@ -1543,14 +1340,7 @@ _edje_object_text_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *text_clas edje_object_text_class_del(rp->typedata.swallow->swallowed_object, text_class); } - ed->dirty = EINA_TRUE; - ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - ed->text_part_change = EINA_TRUE; -#endif - _edje_textblock_styles_cache_free(ed, text_class); - _edje_textblock_style_all_update(ed); - _edje_recalc(ed); + efl_observer_update(obj, _edje_text_class_member, text_class, NULL); } typedef struct _Edje_File_Text_Class_Iterator Edje_File_Text_Class_Iterator; @@ -1630,9 +1420,6 @@ on_error: EAPI Eina_Bool edje_size_class_set(const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh) { - Eina_Hash *members; - Eina_Iterator *it; - Edje_Refcount *er; Edje_Size_Class *sc; if (!size_class) return EINA_FALSE; @@ -1672,18 +1459,8 @@ edje_size_class_set(const char *size_class, Evas_Coord minw, Evas_Coord minh, Ev } /* Tell all members of the size class to recalc */ - members = eina_hash_find(_edje_size_class_member_hash, size_class); - it = eina_hash_iterator_data_new(members); - EINA_ITERATOR_FOREACH(it, er) - { - er->ed->dirty = EINA_TRUE; - er->ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - er->ed->all_part_change = EINA_TRUE; -#endif - _edje_recalc(er->ed); - } - eina_iterator_free(it); + efl_observable_observers_update(_edje_size_class_member, size_class, NULL); + return EINA_TRUE; } @@ -1719,9 +1496,6 @@ EAPI void edje_size_class_del(const char *size_class) { Edje_Size_Class *sc; - Eina_Hash *members; - Eina_Iterator *it; - Edje_Refcount *er; if (!size_class) return; @@ -1732,18 +1506,7 @@ edje_size_class_del(const char *size_class) eina_stringshare_del(sc->name); free(sc); - members = eina_hash_find(_edje_size_class_member_hash, size_class); - it = eina_hash_iterator_data_new(members); - EINA_ITERATOR_FOREACH(it, er) - { - er->ed->dirty = EINA_TRUE; - er->ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - er->ed->all_part_change = EINA_TRUE; -#endif - _edje_recalc(er->ed); - } - eina_iterator_free(it); + efl_observable_observers_update(_edje_size_class_member, size_class, NULL); } Eina_List * @@ -1770,33 +1533,31 @@ static Eina_Bool _edje_size_class_active_iterator_next(Eina_Iterator *it, void **data) { Edje_Active_Size_Class_Iterator *et = (void *)it; - Eina_Hash_Tuple *tuple = NULL; - Edje_Refcount *er = NULL; - Eina_Iterator *ith; + Efl_Observable_Tuple *tuple = NULL; + Efl_Observer *o; + Edje *ed; Edje_Size_Class *sc; - Eina_Bool r = EINA_FALSE; if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE; if (!tuple) return EINA_FALSE; - ith = eina_hash_iterator_data_new(tuple->data); - if (!eina_iterator_next(ith, (void **)&er)) goto on_error; + if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE; + + ed = efl_data_scope_get(o, EDJE_OBJECT_CLASS); + if (!ed) return EINA_FALSE; /* We actually need to ask on an object to get the correct value. It is being assumed that the size key are the same for all object here. This can some times not be the case, but for now we should be fine. */ - sc = _edje_size_class_find(er->ed, tuple->key); - if (!sc) goto on_error; + sc = _edje_size_class_find(ed, tuple->key); + if (!sc) return EINA_FALSE; et->sc = *sc; *data = &et->sc; - r = EINA_TRUE; - on_error: - eina_iterator_free(ith); - return r; + return EINA_TRUE; } static void * @@ -1820,12 +1581,12 @@ edje_size_class_active_iterator_new(void) { Edje_Active_Size_Class_Iterator *it; - if (!_edje_size_class_member_hash) return NULL; + if (!_edje_size_class_member) return NULL; it = calloc(1, sizeof (Edje_Active_Size_Class_Iterator)); if (!it) return NULL; EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - it->classes = eina_hash_iterator_tuple_new(_edje_size_class_member_hash); + it->classes = efl_observable_iterator_tuple_new(_edje_size_class_member); it->iterator.version = EINA_ITERATOR_VERSION; it->iterator.next = _edje_size_class_active_iterator_next; @@ -1902,12 +1663,7 @@ _edje_object_size_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *size_clas size_class, minw, minh, maxw, maxh); } - ed->dirty = EINA_TRUE; - ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - ed->all_part_change = EINA_TRUE; -#endif - _edje_recalc(ed); + efl_observable_observers_update(_edje_size_class_member, size_class, NULL); return EINA_TRUE; } @@ -1958,12 +1714,7 @@ _edje_object_size_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *size_clas edje_object_size_class_del(rp->typedata.swallow->swallowed_object, size_class); } - ed->dirty = EINA_TRUE; - ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - ed->all_part_change = EINA_TRUE; -#endif - _edje_recalc(ed); + efl_observable_observers_update(_edje_size_class_member, size_class, NULL); } typedef struct _Edje_File_Size_Class_Iterator Edje_File_Size_Class_Iterator; @@ -6138,32 +5889,6 @@ _edje_color_class_recursive_find(const Edje *ed, const char *color_class) return NULL; } -void -_edje_color_class_member_add(Edje *ed, const char *color_class) -{ - _edje_class_member_add(ed, &_edje_color_class_member_hash, color_class); -} - -void -_edje_color_class_member_del(Edje *ed, const char *color_class) -{ - if ((!ed) || (!color_class)) return; - - _edje_class_member_del(ed, &_edje_color_class_member_hash, color_class); -} - -void -_edje_color_class_members_free(void) -{ - _edje_class_members_free(&_edje_color_class_member_hash); -} - -void -_edje_color_class_member_clean(Edje *ed) -{ - _edje_class_members_clean(ed, _edje_color_class_member_hash); -} - static Eina_Bool color_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) { @@ -6190,11 +5915,11 @@ _edje_color_class_on_del(Edje *ed, Edje_Part *ep) unsigned int i; if ((ep->default_desc) && (ep->default_desc->color_class)) - _edje_color_class_member_del(ed, ep->default_desc->color_class); + efl_observable_observer_del(_edje_color_class_member, ep->default_desc->color_class, ed->obj); for (i = 0; i < ep->other.desc_count; ++i) if (ep->other.desc[i]->color_class) - _edje_color_class_member_del(ed, ep->other.desc[i]->color_class); + efl_observable_observer_del(_edje_color_class_member, ep->other.desc[i]->color_class, ed->obj); } Edje_Text_Class * @@ -6220,32 +5945,6 @@ _edje_text_class_find(Edje *ed, const char *text_class) return NULL; } -void -_edje_text_class_member_add(Edje *ed, const char *text_class) -{ - _edje_class_member_add(ed, &_edje_text_class_member_hash, text_class); -} - -void -_edje_text_class_member_del(Edje *ed, const char *text_class) -{ - if ((!ed) || (!text_class)) return; - - _edje_class_member_del(ed, &_edje_text_class_member_hash, text_class); -} - -void -_edje_text_class_members_free(void) -{ - _edje_class_members_free(&_edje_text_class_member_hash); -} - -void -_edje_text_class_members_clean(Edje *ed) -{ - _edje_class_members_clean(ed, _edje_text_class_member_hash); -} - static Eina_Bool text_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) { @@ -6290,32 +5989,6 @@ _edje_size_class_find(Edje *ed, const char *size_class) return NULL; } -void -_edje_size_class_member_add(Edje *ed, const char *size_class) -{ - _edje_class_member_add(ed, &_edje_size_class_member_hash, size_class); -} - -void -_edje_size_class_member_del(Edje *ed, const char *size_class) -{ - if ((!ed) || (!size_class)) return; - - _edje_class_member_del(ed, &_edje_size_class_member_hash, size_class); -} - -void -_edje_size_class_members_free(void) -{ - _edje_class_members_free(&_edje_size_class_member_hash); -} - -void -_edje_size_class_members_clean(Edje *ed) -{ - _edje_class_members_clean(ed, _edje_size_class_member_hash); -} - static Eina_Bool size_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) { diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h index 142950aed6..afcb314863 100644 --- a/src/lib/efl/Efl.h +++ b/src/lib/efl/Efl.h @@ -53,6 +53,9 @@ typedef struct tm Efl_Time; #ifdef EFL_BETA_API_SUPPORT +#include "interfaces/efl_observer.eo.h" +#include "interfaces/efl_observable.eo.h" + #include "interfaces/efl_types.eot.h" #include diff --git a/src/lib/efl/interfaces/efl_observable.eo b/src/lib/efl/interfaces/efl_observable.eo new file mode 100644 index 0000000000..7accb4c9f4 --- /dev/null +++ b/src/lib/efl/interfaces/efl_observable.eo @@ -0,0 +1,63 @@ +class Efl.Observable (Efl.Object) { + methods { + observer_add { + [[Add an observer to a group of observers. + + Note: Observers that observe this observable are grouped by the $key + and an observer can belong to multiple groups at the same time. + + @since 1.19]] + params { + @in key: string; [[A key to classify observer groups]] + @in obs: Efl.Observer; [[An observer object]] + } + } + observer_del { + [[Delete an observer from a group of observers. + + See also @.observer_add(). + + @since 1.19]] + params { + @in key: string; [[A key to classify observer groups]] + @in obs: Efl.Observer; [[An observer object]] + } + } + observer_clean { + [[Clear an observer from all groups of observers. + + @since 1.19]] + params { + @in obs: Efl.Observer; [[An observer object]] + } + } + observers_iterator_new { + [[Return a new iterator associated with a group of observers. + + @since 1.19]] + return: free(own(iterator), eina_iterator_free); + params { + @in key: string; [[A key to classify observer groups]] + } + } + observers_update { + [[Update all observers in a group by calling their update() method. + + @since 1.19]] + params { + @in key: string; [[A key to classify observer groups]] + @in data: void_ptr; [[Required data to update observer]] + } + } + iterator_tuple_new { + [[Return a new iterator associated to this observable. + + @since 1.19]] + return: free(own(iterator), eina_iterator_free); + } + } + implements { + Efl.Object.constructor; + Efl.Object.destructor; + } +} diff --git a/src/lib/efl/interfaces/efl_observer.c b/src/lib/efl/interfaces/efl_observer.c new file mode 100644 index 0000000000..eb2ca92f9f --- /dev/null +++ b/src/lib/efl/interfaces/efl_observer.c @@ -0,0 +1,259 @@ +#include "config.h" +#include "Efl.h" + +typedef struct +{ + Eina_Hash *observers; +} Efl_Observable_Data; + +typedef struct +{ + EINA_REFCOUNT; + + Efl_Observer *o; +} Efl_Observer_Refcount; + +EOLIAN static Eo * +_efl_observable_efl_object_constructor(Efl_Object *obj, Efl_Observable_Data *pd) +{ + pd->observers = eina_hash_string_superfast_new((Eina_Free_Cb)eina_hash_free); + + obj = efl_constructor(efl_super(obj, EFL_OBSERVABLE_CLASS)); + + return obj; +} + +EOLIAN static void +_efl_observable_efl_object_destructor(Eo *obj, Efl_Observable_Data *pd) +{ + eina_hash_free(pd->observers); + + efl_destructor(efl_super(obj, EFL_OBSERVABLE_CLASS)); +} + +EOLIAN static void +_efl_observable_observer_add(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, const char *key, Efl_Observer *obs) +{ + Eina_Hash *observers; + Efl_Observer_Refcount *or; + + if (!key) return; + + observers = eina_hash_find(pd->observers, key); + if (!observers) + { + observers = eina_hash_pointer_new(free); + eina_hash_add(pd->observers, key, observers); + } + + or = eina_hash_find(observers, &obs); + if (!or) + { + or = calloc(1, sizeof(Efl_Observer_Refcount)); + or->o = obs; + EINA_REFCOUNT_INIT(or); + + eina_hash_direct_add(observers, &or->o, or); + } + else + { + EINA_REFCOUNT_REF(or); + } +} + +EOLIAN static void +_efl_observable_observer_del(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, const char *key, Efl_Observer *obs) +{ + Eina_Hash *observers; + Efl_Observer_Refcount *or; + + if (!key) return; + + observers = eina_hash_find(pd->observers, key); + if (!observers) return; + + or = eina_hash_find(observers, &obs); + if (!or) return; + + EINA_REFCOUNT_UNREF(or) + { + eina_hash_del(observers, &or->o, or); + + if (eina_hash_population(observers) == 0) + { + eina_hash_del(pd->observers, key, observers); + } + } +} + +EOLIAN static void +_efl_observable_observer_clean(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, Efl_Observer *obs) +{ + Eina_Iterator *it; + Eina_Hash *observers; + + it = eina_hash_iterator_data_new(pd->observers); + EINA_ITERATOR_FOREACH(it, observers) + { + Efl_Observer_Refcount *or; + + or = eina_hash_find(observers, &obs); + if (!or) continue; + + EINA_REFCOUNT_UNREF(or) + { + eina_hash_del(observers, &obs, or); + } + } + eina_iterator_free(it); +} + +typedef struct +{ + Eina_Iterator iterator; + Eina_Iterator *classes; +} Efl_Observer_Iterator; + +static Eina_Bool +_efl_observable_observers_iterator_next(Eina_Iterator *it, void **data) +{ + Efl_Observer_Iterator *et = (void *)it; + Efl_Observer_Refcount *or = NULL; + + if (!eina_iterator_next(et->classes, (void **)&or)) return EINA_FALSE; + if (!or) return EINA_FALSE; + + *data = or->o; + + return EINA_TRUE; +} + +static void * +_efl_observable_observers_iterator_container(Eina_Iterator *it EINA_UNUSED) +{ + return NULL; +} + +static void +_efl_observable_observers_iterator_free(Eina_Iterator *it) +{ + Efl_Observer_Iterator *et = (void *)it; + + eina_iterator_free(et->classes); + EINA_MAGIC_SET(&et->iterator, 0); + free(et); +} + +EOLIAN static Eina_Iterator * +_efl_observable_observers_iterator_new(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, const char *key) +{ + Eina_Hash *observers; + Efl_Observer_Iterator *it; + + observers = eina_hash_find(pd->observers, key); + if (!observers) return NULL; + + it = calloc(1, sizeof(Efl_Observer_Iterator)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + it->classes = eina_hash_iterator_data_new(observers); + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = _efl_observable_observers_iterator_next; + it->iterator.get_container = _efl_observable_observers_iterator_container; + it->iterator.free = _efl_observable_observers_iterator_free; + + return &it->iterator; +} + +EOLIAN static void +_efl_observable_observers_update(Eo *obj, Efl_Observable_Data *pd EINA_UNUSED, const char *key, void *data) +{ + Eina_Iterator *it; + Efl_Observer *o; + + it = efl_observable_observers_iterator_new(obj, key); + if (!it) return; + + EINA_ITERATOR_FOREACH(it, o) + { + efl_observer_update(o, obj, key, data); + } +} + +typedef struct +{ + Eina_Iterator iterator; + Eina_Iterator *classes; + Efl_Observable *obs; + Eina_List *tuples; +} Efl_Observable_Iterator; + +static Eina_Bool +_efl_observable_iterator_tuple_next(Eina_Iterator *it, void **data) +{ + Efl_Observable_Iterator *et = (void *)it; + Efl_Observable_Tuple *tuple; + const char *key; + + if (!eina_iterator_next(et->classes, (void **)&key)) return EINA_FALSE; + if (!key) return EINA_FALSE; + + tuple = calloc(1, sizeof(Efl_Observable_Tuple)); + if (!tuple) return EINA_FALSE; + + tuple->key = key; + tuple->data = efl_observable_observers_iterator_new(et->obs, key); + + et->tuples = eina_list_append(et->tuples, tuple); + *data = tuple; + + return EINA_TRUE; +} + +static void * +_efl_observable_iterator_tuple_container(Eina_Iterator *it EINA_UNUSED) +{ + return NULL; +} + +static void +_efl_observable_iterator_tuple_free(Eina_Iterator *it) +{ + Efl_Observable_Iterator *et = (void *)it; + Efl_Observable_Tuple *tuple; + + eina_iterator_free(et->classes); + EINA_LIST_FREE(et->tuples, tuple) + { + if (tuple->data) + eina_iterator_free(tuple->data); + free(tuple); + } + EINA_MAGIC_SET(&et->iterator, 0); + free(et); +} + +EOLIAN static Eina_Iterator * +_efl_observable_iterator_tuple_new(Eo *obj, Efl_Observable_Data *pd) +{ + Efl_Observable_Iterator *it; + + it = calloc(1, sizeof(Efl_Observable_Iterator)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + it->classes = eina_hash_iterator_key_new(pd->observers); + it->obs = obj; + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = _efl_observable_iterator_tuple_next; + it->iterator.get_container = _efl_observable_iterator_tuple_container; + it->iterator.free = _efl_observable_iterator_tuple_free; + + return &it->iterator; +} + +#include "efl_observable.eo.c" +#include "efl_observer.eo.c" diff --git a/src/lib/efl/interfaces/efl_observer.eo b/src/lib/efl/interfaces/efl_observer.eo new file mode 100644 index 0000000000..a0d4ffe665 --- /dev/null +++ b/src/lib/efl/interfaces/efl_observer.eo @@ -0,0 +1,15 @@ +interface Efl.Observer { + methods { + update @virtual_pure { + [[Update observer according to the changes of observable object. + + @since 1.19]] + params { + /* FIXME: obs should be Efl.Observable, but cyclic dependency error occurs. */ + @in obs: Efl.Object; [[An observable object]] + @in key: string; [[A key to classify observer groups]] + @in data: void_ptr; [[Required data to update the observer, usually passed by observable object]] + } + } + } +} diff --git a/src/lib/efl/interfaces/efl_types.eot b/src/lib/efl/interfaces/efl_types.eot index 0625dc3c65..988f7abb68 100644 --- a/src/lib/efl/interfaces/efl_types.eot +++ b/src/lib/efl/interfaces/efl_types.eot @@ -38,3 +38,9 @@ struct Efl.Version vanilla (upstream) EFL. Contains $EFL_VERSION_FLAVOR.]] build_id: string; [[Contains $EFL_BUILD_ID.]] } + +struct Efl.Observable.Tuple +{ + key: string; + data: free(own(iterator), eina_iterator_free); +}