summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJee-Yong Um <conr2d@gmail.com>2016-11-01 10:59:09 -0700
committerCedric BAIL <cedric@osg.samsung.com>2016-11-01 11:48:44 -0700
commit0fd144550877ff0a6f413c025685b7e7d63e6535 (patch)
tree600eabc63544ab9e287fcf36f1ef1f3d69ec93a2 /src
parentab9f0ae3ca3f97f550f33947da6e49ac256076ca (diff)
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 <cedric@osg.samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Efl.am3
-rw-r--r--src/lib/edje/edje_load.c8
-rw-r--r--src/lib/edje/edje_main.c45
-rw-r--r--src/lib/edje/edje_object.eo4
-rw-r--r--src/lib/edje/edje_private.h19
-rw-r--r--src/lib/edje/edje_smart.c50
-rw-r--r--src/lib/edje/edje_text.c8
-rw-r--r--src/lib/edje/edje_textblock_styles.c6
-rw-r--r--src/lib/edje/edje_util.c441
-rw-r--r--src/lib/efl/Efl.h3
-rw-r--r--src/lib/efl/interfaces/efl_observable.eo63
-rw-r--r--src/lib/efl/interfaces/efl_observer.c259
-rw-r--r--src/lib/efl/interfaces/efl_observer.eo15
-rw-r--r--src/lib/efl/interfaces/efl_types.eot6
14 files changed, 514 insertions, 416 deletions
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 = \
50 lib/efl/interfaces/efl_io_writer.eo \ 50 lib/efl/interfaces/efl_io_writer.eo \
51 lib/efl/interfaces/efl_io_buffer.eo \ 51 lib/efl/interfaces/efl_io_buffer.eo \
52 lib/efl/interfaces/efl_io_queue.eo \ 52 lib/efl/interfaces/efl_io_queue.eo \
53 lib/efl/interfaces/efl_observer.eo \
54 lib/efl/interfaces/efl_observable.eo \
53 $(efl_eolian_legacy_files) \ 55 $(efl_eolian_legacy_files) \
54 $(NULL) 56 $(NULL)
55 57
@@ -99,6 +101,7 @@ lib/efl/interfaces/efl_io_sizer.c \
99lib/efl/interfaces/efl_io_writer.c \ 101lib/efl/interfaces/efl_io_writer.c \
100lib/efl/interfaces/efl_io_buffer.c \ 102lib/efl/interfaces/efl_io_buffer.c \
101lib/efl/interfaces/efl_io_queue.c \ 103lib/efl/interfaces/efl_io_queue.c \
104lib/efl/interfaces/efl_observer.c \
102$(NULL) 105$(NULL)
103 106
104lib_efl_libefl_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl -I$(top_srcdir)/src/lib/efl @EFL_CFLAGS@ -DEFL_GFX_FILTER_BETA 107lib_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
637 637
638 /* Register any color classes in this parts descriptions. */ 638 /* Register any color classes in this parts descriptions. */
639 if ((ep->default_desc) && (ep->default_desc->color_class)) 639 if ((ep->default_desc) && (ep->default_desc->color_class))
640 _edje_color_class_member_add(ed, ep->default_desc->color_class); 640 efl_observable_observer_add(_edje_color_class_member, ep->default_desc->color_class, obj);
641 641
642 for (k = 0; k < ep->other.desc_count; k++) 642 for (k = 0; k < ep->other.desc_count; k++)
643 { 643 {
@@ -646,7 +646,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
646 desc = ep->other.desc[k]; 646 desc = ep->other.desc[k];
647 647
648 if (desc->color_class) 648 if (desc->color_class)
649 _edje_color_class_member_add(ed, desc->color_class); 649 efl_observable_observer_add(_edje_color_class_member, desc->color_class, obj);
650 } 650 }
651 } 651 }
652 /* sizeclass stuff */ 652 /* sizeclass stuff */
@@ -659,7 +659,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
659 659
660 /* Register any size classes in this parts descriptions. */ 660 /* Register any size classes in this parts descriptions. */
661 if ((ep->default_desc) && (ep->default_desc->size_class)) 661 if ((ep->default_desc) && (ep->default_desc->size_class))
662 _edje_size_class_member_add(ed, ep->default_desc->size_class); 662 efl_observable_observer_add(_edje_size_class_member, ep->default_desc->size_class, obj);
663 663
664 for (k = 0; k < ep->other.desc_count; k++) 664 for (k = 0; k < ep->other.desc_count; k++)
665 { 665 {
@@ -668,7 +668,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
668 desc = ep->other.desc[k]; 668 desc = ep->other.desc[k];
669 669
670 if (desc->size_class) 670 if (desc->size_class)
671 _edje_size_class_member_add(ed, desc->size_class); 671 efl_observable_observer_add(_edje_size_class_member, desc->size_class, obj);
672 } 672 }
673 } 673 }
674 /* build real parts */ 674 /* 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)
90 _edje_message_init(); 90 _edje_message_init();
91 _edje_multisense_init(); 91 _edje_multisense_init();
92 edje_signal_init(); 92 edje_signal_init();
93 _edje_class_init();
93 94
94 _edje_real_part_mp = eina_mempool_add("chained_mempool", 95 _edje_real_part_mp = eina_mempool_add("chained_mempool",
95 "Edje_Real_Part", NULL, 96 "Edje_Real_Part", NULL,
@@ -130,14 +131,13 @@ shutdown_all:
130 eina_mempool_del(_edje_real_part_mp); 131 eina_mempool_del(_edje_real_part_mp);
131 _edje_real_part_state_mp = NULL; 132 _edje_real_part_state_mp = NULL;
132 _edje_real_part_mp = NULL; 133 _edje_real_part_mp = NULL;
134 _edje_class_shutdown();
133 _edje_message_shutdown(); 135 _edje_message_shutdown();
134 _edje_module_shutdown(); 136 _edje_module_shutdown();
135 _edje_external_shutdown(); 137 _edje_external_shutdown();
136 _edje_box_shutdown(); 138 _edje_box_shutdown();
137 _edje_internal_proxy_shutdown(); 139 _edje_internal_proxy_shutdown();
138 _edje_text_class_members_free();
139 _edje_text_class_hash_free(); 140 _edje_text_class_hash_free();
140 _edje_size_class_members_free();
141 _edje_size_class_hash_free(); 141 _edje_size_class_hash_free();
142 _edje_edd_shutdown(); 142 _edje_edd_shutdown();
143 efreet_shutdown(); 143 efreet_shutdown();
@@ -169,7 +169,6 @@ _edje_shutdown_core(void)
169 EINA_LOG_STATE_SHUTDOWN); 169 EINA_LOG_STATE_SHUTDOWN);
170 170
171 _edje_file_cache_shutdown(); 171 _edje_file_cache_shutdown();
172 _edje_color_class_members_free();
173 _edje_color_class_hash_free(); 172 _edje_color_class_hash_free();
174 173
175 eina_stringshare_del(_edje_cache_path); 174 eina_stringshare_del(_edje_cache_path);
@@ -182,15 +181,14 @@ _edje_shutdown_core(void)
182 _edje_real_part_state_mp = NULL; 181 _edje_real_part_state_mp = NULL;
183 _edje_real_part_mp = NULL; 182 _edje_real_part_mp = NULL;
184 183
184 _edje_class_shutdown();
185 edje_signal_shutdown(); 185 edje_signal_shutdown();
186 _edje_multisense_shutdown(); 186 _edje_multisense_shutdown();
187 _edje_message_shutdown(); 187 _edje_message_shutdown();
188 _edje_module_shutdown(); 188 _edje_module_shutdown();
189 _edje_external_shutdown(); 189 _edje_external_shutdown();
190 _edje_box_shutdown(); 190 _edje_box_shutdown();
191 _edje_text_class_members_free();
192 _edje_text_class_hash_free(); 191 _edje_text_class_hash_free();
193 _edje_size_class_members_free();
194 _edje_size_class_hash_free(); 192 _edje_size_class_hash_free();
195 _edje_edd_shutdown(); 193 _edje_edd_shutdown();
196 194
@@ -250,6 +248,37 @@ edje_shutdown(void)
250 248
251/* Private Routines */ 249/* Private Routines */
252void 250void
251_edje_class_init(void)
252{
253 if (!_edje_color_class_member)
254 _edje_color_class_member = efl_add(EFL_OBSERVABLE_CLASS, NULL);
255 if (!_edje_text_class_member)
256 _edje_text_class_member = efl_add(EFL_OBSERVABLE_CLASS, NULL);
257 if (!_edje_size_class_member)
258 _edje_size_class_member = efl_add(EFL_OBSERVABLE_CLASS, NULL);
259}
260
261void
262_edje_class_shutdown(void)
263{
264 if (_edje_color_class_member)
265 {
266 efl_del(_edje_color_class_member);
267 _edje_color_class_member = NULL;
268 }
269 if (_edje_text_class_member)
270 {
271 efl_del(_edje_text_class_member);
272 _edje_text_class_member = NULL;
273 }
274 if (_edje_size_class_member)
275 {
276 efl_del(_edje_size_class_member);
277 _edje_size_class_member = NULL;
278 }
279}
280
281void
253_edje_del(Edje *ed) 282_edje_del(Edje *ed)
254{ 283{
255 Edje_Text_Insert_Filter_Callback *cb; 284 Edje_Text_Insert_Filter_Callback *cb;
@@ -286,9 +315,9 @@ _edje_del(Edje *ed)
286 free(cb); 315 free(cb);
287 } 316 }
288 317
289 _edje_color_class_member_clean(ed); 318 efl_observable_observer_clean(_edje_color_class_member, ed->obj);
290 _edje_text_class_members_clean(ed); 319 efl_observable_observer_clean(_edje_text_class_member, ed->obj);
291 _edje_size_class_members_clean(ed); 320 efl_observable_observer_clean(_edje_size_class_member, ed->obj);
292} 321}
293 322
294void 323void
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 @@
1import edje_types; 1import edje_types;
2 2
3class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part) 3class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part,
4 Efl.Observer)
4{ 5{
5 legacy_prefix: edje_object; 6 legacy_prefix: edje_object;
6 eo_prefix: edje_obj; 7 eo_prefix: edje_obj;
@@ -2084,6 +2085,7 @@ class Edje.Object (Efl.Canvas.Group.Clipped, Efl.File, Efl.Container, Efl.Part)
2084 Efl.Container.content_remove; 2085 Efl.Container.content_remove;
2085 Efl.Container.content_part_name.get; 2086 Efl.Container.content_part_name.get;
2086 Efl.Part.part; 2087 Efl.Part.part;
2088 Efl.Observer.update;
2087 } 2089 }
2088 events { 2090 events {
2089 recalc; [[Edje re-calculated the object.]] 2091 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);
2496Edje_Real_Part *_edje_real_part_recursive_get(Edje **ed, const char *part); 2496Edje_Real_Part *_edje_real_part_recursive_get(Edje **ed, const char *part);
2497Edje_Color_Class *_edje_color_class_find(const Edje *ed, const char *color_class); 2497Edje_Color_Class *_edje_color_class_find(const Edje *ed, const char *color_class);
2498Edje_Color_Class *_edje_color_class_recursive_find(const Edje *ed, const char *color_class); 2498Edje_Color_Class *_edje_color_class_recursive_find(const Edje *ed, const char *color_class);
2499void _edje_color_class_member_add(Edje *ed, const char *color_class);
2500void _edje_color_class_member_del(Edje *ed, const char *color_class);
2501void _edje_color_class_member_clean(Edje *ed);
2502void _edje_color_class_on_del(Edje *ed, Edje_Part *ep); 2499void _edje_color_class_on_del(Edje *ed, Edje_Part *ep);
2503void _edje_color_class_members_free(void);
2504void _edje_color_class_hash_free(void); 2500void _edje_color_class_hash_free(void);
2505 2501
2506const char * _edje_find_alias(Eina_Hash *aliased, char *src, int *length); 2502const char * _edje_find_alias(Eina_Hash *aliased, char *src, int *length);
2507Edje_Text_Class *_edje_text_class_find(Edje *ed, const char *text_class); 2503Edje_Text_Class *_edje_text_class_find(Edje *ed, const char *text_class);
2508void _edje_text_class_member_add(Edje *ed, const char *text_class);
2509void _edje_text_class_member_del(Edje *ed, const char *text_class);
2510void _edje_text_class_members_free(void);
2511void _edje_text_class_hash_free(void); 2504void _edje_text_class_hash_free(void);
2512void _edje_text_class_members_clean(Edje *ed);
2513Edje_Size_Class *_edje_size_class_find(Edje *ed, const char *size_class); 2505Edje_Size_Class *_edje_size_class_find(Edje *ed, const char *size_class);
2514void _edje_size_class_member_add(Edje *ed, const char *size_class);
2515void _edje_size_class_member_del(Edje *ed, const char *size_class);
2516void _edje_size_class_members_free(void);
2517void _edje_size_class_hash_free(void); 2506void _edje_size_class_hash_free(void);
2518void _edje_size_class_members_clean(Edje *ed);
2519Edje *_edje_fetch(const Evas_Object *obj) EINA_PURE; 2507Edje *_edje_fetch(const Evas_Object *obj) EINA_PURE;
2520int _edje_util_freeze(Edje *ed); 2508int _edje_util_freeze(Edje *ed);
2521int _edje_util_thaw(Edje *ed); 2509int _edje_util_thaw(Edje *ed);
@@ -2895,6 +2883,13 @@ void _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params
2895void _edje_user_definition_remove(Edje_User_Defined *eud, Evas_Object *child); 2883void _edje_user_definition_remove(Edje_User_Defined *eud, Evas_Object *child);
2896void _edje_user_definition_free(Edje_User_Defined *eud); 2884void _edje_user_definition_free(Edje_User_Defined *eud);
2897 2885
2886extern Efl_Observable *_edje_color_class_member;
2887extern Efl_Observable *_edje_text_class_member;
2888extern Efl_Observable *_edje_size_class_member;
2889
2890void _edje_class_init(void);
2891void _edje_class_shutdown(void);
2892
2898void _scale_set(Eo *obj, void *_pd, va_list *list); 2893void _scale_set(Eo *obj, void *_pd, va_list *list);
2899void _scale_get(Eo *obj, void *_pd, va_list *list); 2894void _scale_get(Eo *obj, void *_pd, va_list *list);
2900void _base_scale_get(Eo *obj, void *_pd, va_list *list); 2895void _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
490 efl_canvas_group_need_recalculate_set(obj, 1); 490 efl_canvas_group_need_recalculate_set(obj, 1);
491} 491}
492 492
493EOLIAN static void
494_edje_object_efl_observer_update(Eo *obj EINA_UNUSED, Edje *ed, Efl_Object *obs, const char *key, void *data)
495{
496 if (!obs) return;
497
498 ed->dirty = EINA_TRUE;
499 ed->recalc_call = EINA_TRUE;
500
501 if ((obs == _edje_color_class_member) || (obs == _edje_size_class_member))
502 {
503#ifdef EDJE_CALC_CACHE
504 ed->all_part_change = EINA_TRUE;
505#endif
506 }
507 else if (obs == _edje_text_class_member)
508 {
509 _edje_textblock_styles_cache_free(ed, key);
510 _edje_textblock_style_all_update(ed);
511#ifdef EDJE_CALC_CACHE
512 ed->text_part_change = EINA_TRUE;
513#endif
514 }
515
516 _edje_recalc(ed);
517
518 if (obs == _edje_color_class_member)
519 {
520 if (data)
521 _edje_emit(ed, (const char *)data, key);
522
523 if ((ed->file) && (ed->file->color_tree))
524 {
525 Edje_Color_Tree_Node *ctn = NULL;
526 Eina_List *l = NULL;
527 char *name;
528
529 EINA_LIST_FOREACH(ed->file->color_tree, l, ctn)
530 {
531 if (!strcmp(ctn->name, key) && (ctn->color_classes))
532 {
533 EINA_LIST_FOREACH(ctn->color_classes, l, name)
534 efl_observable_observers_update(_edje_color_class_member, name, data);
535
536 break;
537 }
538 }
539 }
540 }
541}
542
493#include "edje_object.eo.c" 543#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)
82 /* if text class exists for this part, add the edje to the tc member list */ 82 /* if text class exists for this part, add the edje to the tc member list */
83 desc = (Edje_Part_Description_Text *)pt->default_desc; 83 desc = (Edje_Part_Description_Text *)pt->default_desc;
84 if ((pt->default_desc) && (desc->text.text_class)) 84 if ((pt->default_desc) && (desc->text.text_class))
85 _edje_text_class_member_add(ed, desc->text.text_class); 85 efl_observable_observer_add(_edje_text_class_member, desc->text.text_class, ed->obj);
86 86
87 /* If any other classes exist add them */ 87 /* If any other classes exist add them */
88 for (i = 0; i < pt->other.desc_count; ++i) 88 for (i = 0; i < pt->other.desc_count; ++i)
89 { 89 {
90 desc = (Edje_Part_Description_Text *)pt->other.desc[i]; 90 desc = (Edje_Part_Description_Text *)pt->other.desc[i];
91 if ((desc) && (desc->text.text_class)) 91 if ((desc) && (desc->text.text_class))
92 _edje_text_class_member_add(ed, desc->text.text_class); 92 efl_observable_observer_add(_edje_text_class_member, desc->text.text_class, ed->obj);
93 } 93 }
94} 94}
95 95
@@ -105,13 +105,13 @@ _edje_text_part_on_del(Edje *ed, Edje_Part *pt)
105 105
106 desc = (Edje_Part_Description_Text *)pt->default_desc; 106 desc = (Edje_Part_Description_Text *)pt->default_desc;
107 if ((pt->default_desc) && (desc->text.text_class)) 107 if ((pt->default_desc) && (desc->text.text_class))
108 _edje_text_class_member_del(ed, desc->text.text_class); 108 efl_observable_observer_del(_edje_text_class_member, desc->text.text_class, ed->obj);
109 109
110 for (i = 0; i < pt->other.desc_count; ++i) 110 for (i = 0; i < pt->other.desc_count; ++i)
111 { 111 {
112 desc = (Edje_Part_Description_Text *)pt->other.desc[i]; 112 desc = (Edje_Part_Description_Text *)pt->other.desc[i];
113 if (desc->text.text_class) 113 if (desc->text.text_class)
114 _edje_text_class_member_del(ed, desc->text.text_class); 114 efl_observable_observer_del(_edje_text_class_member, desc->text.text_class, ed->obj);
115 } 115 }
116} 116}
117 117
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)
310 { 310 {
311 if (tag->text_class) 311 if (tag->text_class)
312 { 312 {
313 _edje_text_class_member_add(ed, tag->text_class); 313 efl_observable_observer_add(_edje_text_class_member, tag->text_class, ed->obj);
314 314
315 /* Newly added text_class member should be updated 315 /* Newly added text_class member should be updated
316 according to the latest text_class's status. */ 316 according to the latest text_class's status. */
@@ -377,7 +377,7 @@ _edje_textblock_styles_del(Edje *ed, Edje_Part *pt)
377 EINA_LIST_FOREACH(stl->tags, l, tag) 377 EINA_LIST_FOREACH(stl->tags, l, tag)
378 { 378 {
379 if (tag->text_class) 379 if (tag->text_class)
380 _edje_text_class_member_del(ed, tag->text_class); 380 efl_observable_observer_del(_edje_text_class_member, tag->text_class, ed->obj);
381 } 381 }
382 } 382 }
383 383
@@ -403,7 +403,7 @@ _edje_textblock_styles_del(Edje *ed, Edje_Part *pt)
403 EINA_LIST_FOREACH(stl->tags, l, tag) 403 EINA_LIST_FOREACH(stl->tags, l, tag)
404 { 404 {
405 if (tag->text_class) 405 if (tag->text_class)
406 _edje_text_class_member_del(ed, tag->text_class); 406 efl_observable_observer_del(_edje_text_class_member, tag->text_class, ed->obj);
407 } 407 }
408 } 408 }
409 } 409 }
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
17}; 17};
18 18
19static Eina_Hash *_edje_color_class_hash = NULL; 19static Eina_Hash *_edje_color_class_hash = NULL;
20static Eina_Hash *_edje_color_class_member_hash = NULL;
21
22static Eina_Hash *_edje_text_class_hash = NULL; 20static Eina_Hash *_edje_text_class_hash = NULL;
23static Eina_Hash *_edje_text_class_member_hash = NULL;
24
25static Eina_Hash *_edje_size_class_hash = NULL; 21static Eina_Hash *_edje_size_class_hash = NULL;
26static Eina_Hash *_edje_size_class_member_hash = NULL; 22
23Efl_Observable *_edje_color_class_member = NULL;
24Efl_Observable *_edje_text_class_member = NULL;
25Efl_Observable *_edje_size_class_member = NULL;
27 26
28static Eina_Rbtree *_edje_box_layout_registry = NULL; 27static Eina_Rbtree *_edje_box_layout_registry = NULL;
29 28
@@ -156,116 +155,6 @@ _edje_user_def_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child EINA_U
156 _edje_user_definition_free(eud); 155 _edje_user_definition_free(eud);
157} 156}
158 157
159static void
160_edje_class_member_add(Edje *ed, Eina_Hash **ghash, const char *class)
161{
162 Eina_Hash *members;
163 Edje_Refcount *er;
164
165 if ((!ed) || (!ghash) || (!class)) return;
166
167 if (!*ghash) *ghash = eina_hash_string_superfast_new(NULL);
168
169 members = eina_hash_find(*ghash, class);
170 if (!members)
171 {
172 members = eina_hash_pointer_new(NULL);
173 eina_hash_add(*ghash, class, members);
174 }
175
176 er = eina_hash_find(members, &ed);
177 if (!er)
178 {
179 er = calloc(1, sizeof (Edje_Refcount));
180 er->ed = ed;
181 EINA_REFCOUNT_INIT(er);
182
183 eina_hash_direct_add(members, &er->ed, er);
184 }
185 else
186 {
187 EINA_REFCOUNT_REF(er);
188 }
189}
190
191static void
192_edje_class_member_del(Edje *ed, Eina_Hash **ghash, const char *class)
193{
194 Edje_Refcount *lookup;
195 Eina_Hash *members;
196
197 if ((!ed) || (!ghash) || (!class)) return;
198 members = eina_hash_find(*ghash, class);
199 if (!members) return;
200
201 lookup = eina_hash_find(members, &ed);
202 if (!lookup) return;
203
204 EINA_REFCOUNT_UNREF(lookup)
205 {
206 eina_hash_del(members, &lookup->ed, lookup);
207 free(lookup);
208
209 if (eina_hash_population(members) == 0)
210 {
211 eina_hash_del(*ghash, class, members);
212 eina_hash_free(members);
213 }
214 }
215}
216
217static void
218_edje_class_members_free(Eina_Hash **ghash)
219{
220 Eina_Iterator *it;
221 Eina_Hash *members;
222
223 if (!ghash || !*ghash) return;
224
225 it = eina_hash_iterator_data_new(*ghash);
226 EINA_ITERATOR_FOREACH(it, members)
227 {
228 Eina_Iterator *it2;
229 Edje_Refcount *er;
230
231 it2 = eina_hash_iterator_data_new(members);
232 EINA_ITERATOR_FOREACH(it2, er)
233 free(er);
234 eina_iterator_free(it2);
235
236 eina_hash_free(members);
237 }
238 eina_iterator_free(it);
239
240 eina_hash_free(*ghash);
241 *ghash = NULL;
242}
243
244static void
245_edje_class_members_clean(Edje *ed, Eina_Hash *ghash)
246{
247 Eina_Iterator *it;
248 Eina_Hash *members;
249
250 if (!ed || !ghash) return;
251
252 it = eina_hash_iterator_data_new(ghash);
253 EINA_ITERATOR_FOREACH(it, members)
254 {
255 Edje_Refcount *lookup;
256
257 lookup = eina_hash_find(members, &ed);
258 if (!lookup) continue;
259
260 EINA_REFCOUNT_UNREF(lookup)
261 {
262 eina_hash_del(members, &lookup->ed, lookup);
263 free(lookup);
264 }
265 }
266 eina_iterator_free(it);
267}
268
269/************************** API Routines **************************/ 158/************************** API Routines **************************/
270 159
271#define FASTFREEZE 1 160#define FASTFREEZE 1
@@ -749,41 +638,6 @@ _edje_color_class_get_internal(Edje_Color_Class *cc, Edje_Color_Class_Mode mode,
749 } 638 }
750} 639}
751 640
752static void
753_edje_color_class_apply(const char *color_class, const char *parent)
754{
755 Eina_Hash *members;
756 Eina_Iterator *it;
757 Edje_Refcount *er;
758 Edje_Color_Tree_Node *ctn;
759 Eina_List *l, *ll;
760 char *name;
761
762 members = eina_hash_find(_edje_color_class_member_hash, color_class);
763 if (!members) return;
764 it = eina_hash_iterator_data_new(members);
765 EINA_ITERATOR_FOREACH(it, er)
766 {
767 er->ed->dirty = EINA_TRUE;
768 er->ed->recalc_call = EINA_TRUE;
769#ifdef EDJE_CALC_CACHE
770 er->ed->all_part_change = EINA_TRUE;
771#endif
772 _edje_recalc(er->ed);
773 _edje_emit(er->ed, "color_class,set", parent);
774
775 if (!er->ed->file) continue;
776
777 EINA_LIST_FOREACH(er->ed->file->color_tree, l, ctn)
778 {
779 if ((!strcmp(ctn->name, color_class)) && (ctn->color_classes))
780 EINA_LIST_FOREACH(ctn->color_classes, ll, name)
781 _edje_color_class_apply(name, parent);
782 }
783 }
784 eina_iterator_free(it);
785}
786
787EAPI Eina_Bool 641EAPI Eina_Bool
788edje_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) 642edje_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)
789{ 643{
@@ -809,7 +663,7 @@ _edje_object_global_color_class_set(Efl_Class *klass EINA_UNUSED, void *pd EINA_
809 int_ret = _edje_color_class_set_internal(_edje_color_class_hash, color_class, mode, r, g, b, a, &need_update); 663 int_ret = _edje_color_class_set_internal(_edje_color_class_hash, color_class, mode, r, g, b, a, &need_update);
810 664
811 if ((int_ret) && (need_update)) 665 if ((int_ret) && (need_update))
812 _edje_color_class_apply(color_class, color_class); 666 efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,set");
813 667
814 return int_ret; 668 return int_ret;
815} 669}
@@ -844,9 +698,6 @@ EAPI void
844edje_color_class_del(const char *color_class) 698edje_color_class_del(const char *color_class)
845{ 699{
846 Edje_Color_Class *cc; 700 Edje_Color_Class *cc;
847 Eina_Hash *members;
848 Eina_Iterator *it;
849 Edje_Refcount *er;
850 701
851 if (!color_class) return; 702 if (!color_class) return;
852 703
@@ -857,20 +708,7 @@ edje_color_class_del(const char *color_class)
857 eina_stringshare_del(cc->name); 708 eina_stringshare_del(cc->name);
858 free(cc); 709 free(cc);
859 710
860 members = eina_hash_find(_edje_color_class_member_hash, color_class); 711 efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,del");
861 if (!members) return;
862 it = eina_hash_iterator_data_new(members);
863 EINA_ITERATOR_FOREACH(it, er)
864 {
865 er->ed->dirty = EINA_TRUE;
866 er->ed->recalc_call = EINA_TRUE;
867#ifdef EDJE_CALC_CACHE
868 er->ed->all_part_change = EINA_TRUE;
869#endif
870 _edje_recalc(er->ed);
871 _edje_emit(er->ed, "color_class,del", color_class);
872 }
873 eina_iterator_free(it);
874} 712}
875 713
876Eina_List * 714Eina_List *
@@ -900,42 +738,40 @@ static Eina_Bool
900_edje_color_class_active_iterator_next(Eina_Iterator *it, void **data) 738_edje_color_class_active_iterator_next(Eina_Iterator *it, void **data)
901{ 739{
902 Edje_Active_Color_Class_Iterator *et = (void *)it; 740 Edje_Active_Color_Class_Iterator *et = (void *)it;
903 Eina_Hash_Tuple *tuple = NULL; 741 Efl_Observable_Tuple *tuple = NULL;
904 Edje_Refcount *er = NULL; 742 Efl_Observer *o;
905 Eina_Iterator *ith; 743 Edje *ed;
906 Edje_Color_Class *cc = NULL; 744 Edje_Color_Class *cc = NULL;
907 Eina_Bool r = EINA_FALSE;
908 745
909 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE; 746 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
910 if (!tuple) return EINA_FALSE; 747 if (!tuple) return EINA_FALSE;
911 748
912 ith = eina_hash_iterator_data_new(tuple->data); 749 if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
913 if (!eina_iterator_next(ith, (void **)&er)) goto on_error; 750
751 ed = efl_data_scope_get(o, EDJE_OBJECT_CLASS);
752 if (!ed) return EINA_FALSE;
914 753
915 /* 754 /*
916 We actually need to ask on an object to get the correct value. 755 We actually need to ask on an object to get the correct value.
917 It is being assumed that the color key are the same for all object here. 756 It is being assumed that the color key are the same for all object here.
918 This can some times not be the case, but for now we should be fine. 757 This can some times not be the case, but for now we should be fine.
919 */ 758 */
920 cc = _edje_color_class_find(er->ed, tuple->key); 759 cc = _edje_color_class_find(ed, tuple->key);
921 if (!cc) goto on_error; 760 if (!cc) return EINA_FALSE;
922 et->cc = *cc; 761 et->cc = *cc;
923 762
924 /* 763 /*
925 Any of the Edje object referenced should have a file with a valid 764 Any of the Edje object referenced should have a file with a valid
926 description for this color class. Let's bet on that for now. 765 description for this color class. Let's bet on that for now.
927 */ 766 */
928 if (er->ed->file) 767 if (ed->file)
929 cc = eina_hash_find(er->ed->file->color_hash, tuple->key); 768 cc = eina_hash_find(ed->file->color_hash, tuple->key);
930 if (!cc) goto on_error; 769 if (!cc) return EINA_FALSE;
931 et->cc.desc = cc->desc; 770 et->cc.desc = cc->desc;
932 771
933 *data = &et->cc; 772 *data = &et->cc;
934 r = EINA_TRUE;
935 773
936 on_error: 774 return EINA_TRUE;
937 eina_iterator_free(ith);
938 return r;
939} 775}
940 776
941static void * 777static void *
@@ -959,12 +795,12 @@ edje_color_class_active_iterator_new(void)
959{ 795{
960 Edje_Active_Color_Class_Iterator *it; 796 Edje_Active_Color_Class_Iterator *it;
961 797
962 if (!_edje_color_class_member_hash) return NULL; 798 if (!_edje_color_class_member) return NULL;
963 it = calloc(1, sizeof (Edje_Active_Color_Class_Iterator)); 799 it = calloc(1, sizeof (Edje_Active_Color_Class_Iterator));
964 if (!it) return NULL; 800 if (!it) return NULL;
965 801
966 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 802 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
967 it->classes = eina_hash_iterator_tuple_new(_edje_color_class_member_hash); 803 it->classes = efl_observable_iterator_tuple_new(_edje_color_class_member);
968 804
969 it->iterator.version = EINA_ITERATOR_VERSION; 805 it->iterator.version = EINA_ITERATOR_VERSION;
970 it->iterator.next = _edje_color_class_active_iterator_next; 806 it->iterator.next = _edje_color_class_active_iterator_next;
@@ -1218,9 +1054,6 @@ on_error:
1218EAPI Eina_Bool 1054EAPI Eina_Bool
1219edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size) 1055edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size)
1220{ 1056{
1221 Eina_Hash *members;
1222 Eina_Iterator *it;
1223 Edje_Refcount *er;
1224 Edje_Text_Class *tc; 1057 Edje_Text_Class *tc;
1225 1058
1226 if (!text_class) return EINA_FALSE; 1059 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
1257 } 1090 }
1258 1091
1259 /* Tell all members of the text class to recalc */ 1092 /* Tell all members of the text class to recalc */
1260 members = eina_hash_find(_edje_text_class_member_hash, text_class); 1093 efl_observable_observers_update(_edje_text_class_member, text_class, NULL);
1261 it = eina_hash_iterator_data_new(members); 1094
1262 EINA_ITERATOR_FOREACH(it, er)
1263 {
1264 er->ed->dirty = EINA_TRUE;
1265 er->ed->recalc_call = EINA_TRUE;
1266 _edje_textblock_styles_cache_free(er->ed, text_class);
1267 _edje_textblock_style_all_update(er->ed);
1268#ifdef EDJE_CALC_CACHE
1269 er->ed->text_part_change = EINA_TRUE;
1270#endif
1271 _edje_recalc(er->ed);
1272 }
1273 eina_iterator_free(it);
1274 return EINA_TRUE; 1095 return EINA_TRUE;
1275} 1096}
1276 1097
@@ -1302,9 +1123,6 @@ EAPI void
1302edje_text_class_del(const char *text_class) 1123edje_text_class_del(const char *text_class)
1303{ 1124{
1304 Edje_Text_Class *tc; 1125 Edje_Text_Class *tc;
1305 Eina_Hash *members;
1306 Eina_Iterator *it;
1307 Edje_Refcount *er;
1308 1126
1309 if (!text_class) return; 1127 if (!text_class) return;
1310 1128
@@ -1316,19 +1134,7 @@ edje_text_class_del(const char *text_class)
1316 eina_stringshare_del(tc->font); 1134 eina_stringshare_del(tc->font);
1317 free(tc); 1135 free(tc);
1318 1136
1319 members = eina_hash_find(_edje_text_class_member_hash, text_class); 1137 efl_observable_observers_update(_edje_text_class_member, text_class, NULL);
1320 it = eina_hash_iterator_data_new(members);
1321 EINA_ITERATOR_FOREACH(it, er)
1322 {
1323 er->ed->dirty = EINA_TRUE;
1324 _edje_textblock_styles_cache_free(er->ed, text_class);
1325 _edje_textblock_style_all_update(er->ed);
1326#ifdef EDJE_CALC_CACHE
1327 er->ed->text_part_change = EINA_TRUE;
1328#endif
1329 _edje_recalc(er->ed);
1330 }
1331 eina_iterator_free(it);
1332} 1138}
1333 1139
1334Eina_List * 1140Eina_List *
@@ -1355,33 +1161,31 @@ static Eina_Bool
1355_edje_text_class_active_iterator_next(Eina_Iterator *it, void **data) 1161_edje_text_class_active_iterator_next(Eina_Iterator *it, void **data)
1356{ 1162{
1357 Edje_Active_Text_Class_Iterator *et = (void *)it; 1163 Edje_Active_Text_Class_Iterator *et = (void *)it;
1358 Eina_Hash_Tuple *tuple = NULL; 1164 Efl_Observable_Tuple *tuple = NULL;
1359 Edje_Refcount *er = NULL; 1165 Efl_Observer *o;
1360 Eina_Iterator *ith; 1166 Edje *ed;
1361 Edje_Text_Class *tc; 1167 Edje_Text_Class *tc;
1362 Eina_Bool r = EINA_FALSE;
1363 1168
1364 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE; 1169 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
1365 if (!tuple) return EINA_FALSE; 1170 if (!tuple) return EINA_FALSE;
1366 1171
1367 ith = eina_hash_iterator_data_new(tuple->data); 1172 if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
1368 if (!eina_iterator_next(ith, (void **)&er)) goto on_error; 1173
1174 ed = efl_data_scope_get(o, EDJE_OBJECT_CLASS);
1175 if (!ed) return EINA_FALSE;
1369 1176
1370 /* 1177 /*
1371 We actually need to ask on an object to get the correct value. 1178 We actually need to ask on an object to get the correct value.
1372 It is being assumed that the size key are the same for all object here. 1179 It is being assumed that the size key are the same for all object here.
1373 This can some times not be the case, but for now we should be fine. 1180 This can some times not be the case, but for now we should be fine.
1374 */ 1181 */
1375 tc = _edje_text_class_find(er->ed, tuple->key); 1182 tc = _edje_text_class_find(ed, tuple->key);
1376 if (!tc) goto on_error; 1183 if (!tc) return EINA_FALSE;
1377 et->tc = *tc; 1184 et->tc = *tc;
1378 1185
1379 *data = &et->tc; 1186 *data = &et->tc;
1380 r = EINA_TRUE;
1381 1187
1382 on_error: 1188 return EINA_TRUE;
1383 eina_iterator_free(ith);
1384 return r;
1385} 1189}
1386 1190
1387static void * 1191static void *
@@ -1405,12 +1209,12 @@ edje_text_class_active_iterator_new(void)
1405{ 1209{
1406 Edje_Active_Text_Class_Iterator *it; 1210 Edje_Active_Text_Class_Iterator *it;
1407 1211
1408 if (!_edje_text_class_member_hash) return NULL; 1212 if (!_edje_text_class_member) return NULL;
1409 it = calloc(1, sizeof (Edje_Active_Text_Class_Iterator)); 1213 it = calloc(1, sizeof (Edje_Active_Text_Class_Iterator));
1410 if (!it) return NULL; 1214 if (!it) return NULL;
1411 1215
1412 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 1216 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
1413 it->classes = eina_hash_iterator_tuple_new(_edje_text_class_member_hash); 1217 it->classes = efl_observable_iterator_tuple_new(_edje_text_class_member);
1414 1218
1415 it->iterator.version = EINA_ITERATOR_VERSION; 1219 it->iterator.version = EINA_ITERATOR_VERSION;
1416 it->iterator.next = _edje_text_class_active_iterator_next; 1220 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
1489 text_class, font, size); 1293 text_class, font, size);
1490 } 1294 }
1491 1295
1492 ed->dirty = EINA_TRUE; 1296 efl_observer_update(obj, _edje_text_class_member, text_class, NULL);
1493 ed->recalc_call = EINA_TRUE;
1494#ifdef EDJE_CALC_CACHE
1495 ed->text_part_change = EINA_TRUE;
1496#endif
1497 _edje_textblock_styles_cache_free(ed, text_class);
1498 _edje_textblock_style_all_update(ed);
1499 _edje_recalc(ed);
1500 1297
1501 return EINA_TRUE; 1298 return EINA_TRUE;
1502} 1299}
@@ -1543,14 +1340,7 @@ _edje_object_text_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *text_clas
1543 edje_object_text_class_del(rp->typedata.swallow->swallowed_object, text_class); 1340 edje_object_text_class_del(rp->typedata.swallow->swallowed_object, text_class);
1544 } 1341 }
1545 1342
1546 ed->dirty = EINA_TRUE; 1343 efl_observer_update(obj, _edje_text_class_member, text_class, NULL);
1547 ed->recalc_call = EINA_TRUE;
1548#ifdef EDJE_CALC_CACHE
1549 ed->text_part_change = EINA_TRUE;
1550#endif
1551 _edje_textblock_styles_cache_free(ed, text_class);
1552 _edje_textblock_style_all_update(ed);
1553 _edje_recalc(ed);
1554} 1344}
1555 1345
1556typedef struct _Edje_File_Text_Class_Iterator Edje_File_Text_Class_Iterator; 1346typedef struct _Edje_File_Text_Class_Iterator Edje_File_Text_Class_Iterator;
@@ -1630,9 +1420,6 @@ on_error:
1630EAPI Eina_Bool 1420EAPI Eina_Bool
1631edje_size_class_set(const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh) 1421edje_size_class_set(const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
1632{ 1422{
1633 Eina_Hash *members;
1634 Eina_Iterator *it;
1635 Edje_Refcount *er;
1636 Edje_Size_Class *sc; 1423 Edje_Size_Class *sc;
1637 1424
1638 if (!size_class) return EINA_FALSE; 1425 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
1672 } 1459 }
1673 1460
1674 /* Tell all members of the size class to recalc */ 1461 /* Tell all members of the size class to recalc */
1675 members = eina_hash_find(_edje_size_class_member_hash, size_class); 1462 efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
1676 it = eina_hash_iterator_data_new(members); 1463
1677 EINA_ITERATOR_FOREACH(it, er)
1678 {
1679 er->ed->dirty = EINA_TRUE;
1680 er->ed->recalc_call = EINA_TRUE;
1681#ifdef EDJE_CALC_CACHE
1682 er->ed->all_part_change = EINA_TRUE;
1683#endif
1684 _edje_recalc(er->ed);
1685 }
1686 eina_iterator_free(it);
1687 return EINA_TRUE; 1464 return EINA_TRUE;
1688} 1465}
1689 1466
@@ -1719,9 +1496,6 @@ EAPI void
1719edje_size_class_del(const char *size_class) 1496edje_size_class_del(const char *size_class)
1720{ 1497{
1721 Edje_Size_Class *sc; 1498 Edje_Size_Class *sc;
1722 Eina_Hash *members;
1723 Eina_Iterator *it;
1724 Edje_Refcount *er;
1725 1499
1726 if (!size_class) return; 1500 if (!size_class) return;
1727 1501
@@ -1732,18 +1506,7 @@ edje_size_class_del(const char *size_class)
1732 eina_stringshare_del(sc->name); 1506 eina_stringshare_del(sc->name);
1733 free(sc); 1507 free(sc);
1734 1508
1735 members = eina_hash_find(_edje_size_class_member_hash, size_class); 1509 efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
1736 it = eina_hash_iterator_data_new(members);
1737 EINA_ITERATOR_FOREACH(it, er)
1738 {
1739 er->ed->dirty = EINA_TRUE;
1740 er->ed->recalc_call = EINA_TRUE;
1741#ifdef EDJE_CALC_CACHE
1742 er->ed->all_part_change = EINA_TRUE;
1743#endif
1744 _edje_recalc(er->ed);
1745 }
1746 eina_iterator_free(it);
1747} 1510}
1748 1511
1749Eina_List * 1512Eina_List *
@@ -1770,33 +1533,31 @@ static Eina_Bool
1770_edje_size_class_active_iterator_next(Eina_Iterator *it, void **data) 1533_edje_size_class_active_iterator_next(Eina_Iterator *it, void **data)
1771{ 1534{
1772 Edje_Active_Size_Class_Iterator *et = (void *)it; 1535 Edje_Active_Size_Class_Iterator *et = (void *)it;
1773 Eina_Hash_Tuple *tuple = NULL; 1536 Efl_Observable_Tuple *tuple = NULL;
1774 Edje_Refcount *er = NULL; 1537 Efl_Observer *o;
1775 Eina_Iterator *ith; 1538 Edje *ed;
1776 Edje_Size_Class *sc; 1539 Edje_Size_Class *sc;
1777 Eina_Bool r = EINA_FALSE;
1778 1540
1779 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE; 1541 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
1780 if (!tuple) return EINA_FALSE; 1542 if (!tuple) return EINA_FALSE;
1781 1543
1782 ith = eina_hash_iterator_data_new(tuple->data); 1544 if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
1783 if (!eina_iterator_next(ith, (void **)&er)) goto on_error; 1545
1546 ed = efl_data_scope_get(o, EDJE_OBJECT_CLASS);
1547 if (!ed) return EINA_FALSE;
1784 1548
1785 /* 1549 /*
1786 We actually need to ask on an object to get the correct value. 1550 We actually need to ask on an object to get the correct value.
1787 It is being assumed that the size key are the same for all object here. 1551 It is being assumed that the size key are the same for all object here.
1788 This can some times not be the case, but for now we should be fine. 1552 This can some times not be the case, but for now we should be fine.
1789 */ 1553 */
1790 sc = _edje_size_class_find(er->ed, tuple->key); 1554 sc = _edje_size_class_find(ed, tuple->key);
1791 if (!sc) goto on_error; 1555 if (!sc) return EINA_FALSE;
1792 et->sc = *sc; 1556 et->sc = *sc;
1793 1557
1794 *data = &et->sc; 1558 *data = &et->sc;
1795 r = EINA_TRUE;
1796 1559
1797 on_error: 1560 return EINA_TRUE;
1798 eina_iterator_free(ith);
1799 return r;
1800} 1561}
1801 1562
1802static void * 1563static void *
@@ -1820,12 +1581,12 @@ edje_size_class_active_iterator_new(void)
1820{ 1581{
1821 Edje_Active_Size_Class_Iterator *it; 1582 Edje_Active_Size_Class_Iterator *it;
1822 1583
1823 if (!_edje_size_class_member_hash) return NULL; 1584 if (!_edje_size_class_member) return NULL;
1824 it = calloc(1, sizeof (Edje_Active_Size_Class_Iterator)); 1585 it = calloc(1, sizeof (Edje_Active_Size_Class_Iterator));
1825 if (!it) return NULL; 1586 if (!it) return NULL;
1826 1587
1827 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 1588 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
1828 it->classes = eina_hash_iterator_tuple_new(_edje_size_class_member_hash); 1589 it->classes = efl_observable_iterator_tuple_new(_edje_size_class_member);
1829 1590
1830 it->iterator.version = EINA_ITERATOR_VERSION; 1591 it->iterator.version = EINA_ITERATOR_VERSION;
1831 it->iterator.next = _edje_size_class_active_iterator_next; 1592 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
1902 size_class, minw, minh, maxw, maxh); 1663 size_class, minw, minh, maxw, maxh);
1903 } 1664 }
1904 1665
1905 ed->dirty = EINA_TRUE; 1666 efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
1906 ed->recalc_call = EINA_TRUE;
1907#ifdef EDJE_CALC_CACHE
1908 ed->all_part_change = EINA_TRUE;
1909#endif
1910 _edje_recalc(ed);
1911 1667
1912 return EINA_TRUE; 1668 return EINA_TRUE;
1913} 1669}
@@ -1958,12 +1714,7 @@ _edje_object_size_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *size_clas
1958 edje_object_size_class_del(rp->typedata.swallow->swallowed_object, size_class); 1714 edje_object_size_class_del(rp->typedata.swallow->swallowed_object, size_class);
1959 } 1715 }
1960 1716
1961 ed->dirty = EINA_TRUE; 1717 efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
1962 ed->recalc_call = EINA_TRUE;
1963#ifdef EDJE_CALC_CACHE
1964 ed->all_part_change = EINA_TRUE;
1965#endif
1966 _edje_recalc(ed);
1967} 1718}
1968 1719
1969typedef struct _Edje_File_Size_Class_Iterator Edje_File_Size_Class_Iterator; 1720typedef 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)
6138 return NULL; 5889 return NULL;
6139} 5890}
6140 5891
6141void
6142_edje_color_class_member_add(Edje *ed, const char *color_class)
6143{
6144 _edje_class_member_add(ed, &_edje_color_class_member_hash, color_class);
6145}
6146
6147void
6148_edje_color_class_member_del(Edje *ed, const char *color_class)
6149{
6150 if ((!ed) || (!color_class)) return;
6151
6152 _edje_class_member_del(ed, &_edje_color_class_member_hash, color_class);
6153}
6154
6155void
6156_edje_color_class_members_free(void)
6157{
6158 _edje_class_members_free(&_edje_color_class_member_hash);
6159}
6160
6161void
6162_edje_color_class_member_clean(Edje *ed)
6163{
6164 _edje_class_members_clean(ed, _edje_color_class_member_hash);
6165}
6166
6167static Eina_Bool 5892static Eina_Bool
6168color_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) 5893color_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
6169{ 5894{
@@ -6190,11 +5915,11 @@ _edje_color_class_on_del(Edje *ed, Edje_Part *ep)
6190 unsigned int i; 5915 unsigned int i;
6191 5916
6192 if ((ep->default_desc) && (ep->default_desc->color_class)) 5917 if ((ep->default_desc) && (ep->default_desc->color_class))
6193 _edje_color_class_member_del(ed, ep->default_desc->color_class); 5918 efl_observable_observer_del(_edje_color_class_member, ep->default_desc->color_class, ed->obj);
6194 5919
6195 for (i = 0; i < ep->other.desc_count; ++i) 5920 for (i = 0; i < ep->other.desc_count; ++i)
6196 if (ep->other.desc[i]->color_class) 5921 if (ep->other.desc[i]->color_class)
6197 _edje_color_class_member_del(ed, ep->other.desc[i]->color_class); 5922 efl_observable_observer_del(_edje_color_class_member, ep->other.desc[i]->color_class, ed->obj);
6198} 5923}
6199 5924
6200Edje_Text_Class * 5925Edje_Text_Class *
@@ -6220,32 +5945,6 @@ _edje_text_class_find(Edje *ed, const char *text_class)
6220 return NULL; 5945 return NULL;
6221} 5946}
6222 5947
6223void
6224_edje_text_class_member_add(Edje *ed, const char *text_class)
6225{
6226 _edje_class_member_add(ed, &_edje_text_class_member_hash, text_class);
6227}
6228
6229void
6230_edje_text_class_member_del(Edje *ed, const char *text_class)
6231{
6232 if ((!ed) || (!text_class)) return;
6233
6234 _edje_class_member_del(ed, &_edje_text_class_member_hash, text_class);
6235}
6236
6237void
6238_edje_text_class_members_free(void)
6239{
6240 _edje_class_members_free(&_edje_text_class_member_hash);
6241}
6242
6243void
6244_edje_text_class_members_clean(Edje *ed)
6245{
6246 _edje_class_members_clean(ed, _edje_text_class_member_hash);
6247}
6248
6249static Eina_Bool 5948static Eina_Bool
6250text_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) 5949text_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
6251{ 5950{
@@ -6290,32 +5989,6 @@ _edje_size_class_find(Edje *ed, const char *size_class)
6290 return NULL; 5989 return NULL;
6291} 5990}
6292 5991
6293void
6294_edje_size_class_member_add(Edje *ed, const char *size_class)
6295{
6296 _edje_class_member_add(ed, &_edje_size_class_member_hash, size_class);
6297}
6298
6299void
6300_edje_size_class_member_del(Edje *ed, const char *size_class)
6301{
6302 if ((!ed) || (!size_class)) return;
6303
6304 _edje_class_member_del(ed, &_edje_size_class_member_hash, size_class);
6305}
6306
6307void
6308_edje_size_class_members_free(void)
6309{
6310 _edje_class_members_free(&_edje_size_class_member_hash);
6311}
6312
6313void
6314_edje_size_class_members_clean(Edje *ed)
6315{
6316 _edje_class_members_clean(ed, _edje_size_class_member_hash);
6317}
6318
6319static Eina_Bool 5992static Eina_Bool
6320size_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) 5993size_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
6321{ 5994{
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;
53 53
54#ifdef EFL_BETA_API_SUPPORT 54#ifdef EFL_BETA_API_SUPPORT
55 55
56#include "interfaces/efl_observer.eo.h"
57#include "interfaces/efl_observable.eo.h"
58
56#include "interfaces/efl_types.eot.h" 59#include "interfaces/efl_types.eot.h"
57 60
58#include <Efl_Model_Common.h> 61#include <Efl_Model_Common.h>
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 @@
1class Efl.Observable (Efl.Object) {
2 methods {
3 observer_add {
4 [[Add an observer to a group of observers.
5
6 Note: Observers that observe this observable are grouped by the $key
7 and an observer can belong to multiple groups at the same time.
8
9 @since 1.19]]
10 params {
11 @in key: string; [[A key to classify observer groups]]
12 @in obs: Efl.Observer; [[An observer object]]
13 }
14 }
15 observer_del {
16 [[Delete an observer from a group of observers.
17
18 See also @.observer_add().
19
20 @since 1.19]]
21 params {
22 @in key: string; [[A key to classify observer groups]]
23 @in obs: Efl.Observer; [[An observer object]]
24 }
25 }
26 observer_clean {
27 [[Clear an observer from all groups of observers.
28
29 @since 1.19]]
30 params {
31 @in obs: Efl.Observer; [[An observer object]]
32 }
33 }
34 observers_iterator_new {
35 [[Return a new iterator associated with a group of observers.
36
37 @since 1.19]]
38 return: free(own(iterator<Efl.Observer>), eina_iterator_free);
39 params {
40 @in key: string; [[A key to classify observer groups]]
41 }
42 }
43 observers_update {
44 [[Update all observers in a group by calling their update() method.
45
46 @since 1.19]]
47 params {
48 @in key: string; [[A key to classify observer groups]]
49 @in data: void_ptr; [[Required data to update observer]]
50 }
51 }
52 iterator_tuple_new {
53 [[Return a new iterator associated to this observable.
54
55 @since 1.19]]
56 return: free(own(iterator<Efl.Observable.Tuple>), eina_iterator_free);
57 }
58 }
59 implements {
60 Efl.Object.constructor;
61 Efl.Object.destructor;
62 }
63}
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 @@
1#include "config.h"
2#include "Efl.h"
3
4typedef struct
5{
6 Eina_Hash *observers;
7} Efl_Observable_Data;
8
9typedef struct
10{
11 EINA_REFCOUNT;
12
13 Efl_Observer *o;
14} Efl_Observer_Refcount;
15
16EOLIAN static Eo *
17_efl_observable_efl_object_constructor(Efl_Object *obj, Efl_Observable_Data *pd)
18{
19 pd->observers = eina_hash_string_superfast_new((Eina_Free_Cb)eina_hash_free);
20
21 obj = efl_constructor(efl_super(obj, EFL_OBSERVABLE_CLASS));
22
23 return obj;
24}
25
26EOLIAN static void
27_efl_observable_efl_object_destructor(Eo *obj, Efl_Observable_Data *pd)
28{
29 eina_hash_free(pd->observers);
30
31 efl_destructor(efl_super(obj, EFL_OBSERVABLE_CLASS));
32}
33
34EOLIAN static void
35_efl_observable_observer_add(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, const char *key, Efl_Observer *obs)
36{
37 Eina_Hash *observers;
38 Efl_Observer_Refcount *or;
39
40 if (!key) return;
41
42 observers = eina_hash_find(pd->observers, key);
43 if (!observers)
44 {
45 observers = eina_hash_pointer_new(free);
46 eina_hash_add(pd->observers, key, observers);
47 }
48
49 or = eina_hash_find(observers, &obs);
50 if (!or)
51 {
52 or = calloc(1, sizeof(Efl_Observer_Refcount));
53 or->o = obs;
54 EINA_REFCOUNT_INIT(or);
55
56 eina_hash_direct_add(observers, &or->o, or);
57 }
58 else
59 {
60 EINA_REFCOUNT_REF(or);
61 }
62}
63
64EOLIAN static void
65_efl_observable_observer_del(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, const char *key, Efl_Observer *obs)
66{
67 Eina_Hash *observers;
68 Efl_Observer_Refcount *or;
69
70 if (!key) return;
71
72 observers = eina_hash_find(pd->observers, key);
73 if (!observers) return;
74
75 or = eina_hash_find(observers, &obs);
76 if (!or) return;
77
78 EINA_REFCOUNT_UNREF(or)
79 {
80 eina_hash_del(observers, &or->o, or);
81
82 if (eina_hash_population(observers) == 0)
83 {
84 eina_hash_del(pd->observers, key, observers);
85 }
86 }
87}
88
89EOLIAN static void
90_efl_observable_observer_clean(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, Efl_Observer *obs)
91{
92 Eina_Iterator *it;
93 Eina_Hash *observers;
94
95 it = eina_hash_iterator_data_new(pd->observers);
96 EINA_ITERATOR_FOREACH(it, observers)
97 {
98 Efl_Observer_Refcount *or;
99
100 or = eina_hash_find(observers, &obs);
101 if (!or) continue;
102
103 EINA_REFCOUNT_UNREF(or)
104 {
105 eina_hash_del(observers, &obs, or);
106 }
107 }
108 eina_iterator_free(it);
109}
110
111typedef struct
112{
113 Eina_Iterator iterator;
114 Eina_Iterator *classes;
115} Efl_Observer_Iterator;
116
117static Eina_Bool
118_efl_observable_observers_iterator_next(Eina_Iterator *it, void **data)
119{
120 Efl_Observer_Iterator *et = (void *)it;
121 Efl_Observer_Refcount *or = NULL;
122
123 if (!eina_iterator_next(et->classes, (void **)&or)) return EINA_FALSE;
124 if (!or) return EINA_FALSE;
125
126 *data = or->o;
127
128 return EINA_TRUE;
129}
130
131static void *
132_efl_observable_observers_iterator_container(Eina_Iterator *it EINA_UNUSED)
133{
134 return NULL;
135}
136
137static void
138_efl_observable_observers_iterator_free(Eina_Iterator *it)
139{
140 Efl_Observer_Iterator *et = (void *)it;
141
142 eina_iterator_free(et->classes);
143 EINA_MAGIC_SET(&et->iterator, 0);
144 free(et);
145}
146
147EOLIAN static Eina_Iterator *
148_efl_observable_observers_iterator_new(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, const char *key)
149{
150 Eina_Hash *observers;
151 Efl_Observer_Iterator *it;
152
153 observers = eina_hash_find(pd->observers, key);
154 if (!observers) return NULL;
155
156 it = calloc(1, sizeof(Efl_Observer_Iterator));
157 if (!it) return NULL;
158
159 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
160 it->classes = eina_hash_iterator_data_new(observers);
161
162 it->iterator.version = EINA_ITERATOR_VERSION;
163 it->iterator.next = _efl_observable_observers_iterator_next;
164 it->iterator.get_container = _efl_observable_observers_iterator_container;
165 it->iterator.free = _efl_observable_observers_iterator_free;
166
167 return &it->iterator;
168}
169
170EOLIAN static void
171_efl_observable_observers_update(Eo *obj, Efl_Observable_Data *pd EINA_UNUSED, const char *key, void *data)
172{
173 Eina_Iterator *it;
174 Efl_Observer *o;
175
176 it = efl_observable_observers_iterator_new(obj, key);
177 if (!it) return;
178
179 EINA_ITERATOR_FOREACH(it, o)
180 {
181 efl_observer_update(o, obj, key, data);
182 }
183}
184
185typedef struct
186{
187 Eina_Iterator iterator;
188 Eina_Iterator *classes;
189 Efl_Observable *obs;
190 Eina_List *tuples;
191} Efl_Observable_Iterator;
192
193static Eina_Bool
194_efl_observable_iterator_tuple_next(Eina_Iterator *it, void **data)
195{
196 Efl_Observable_Iterator *et = (void *)it;
197 Efl_Observable_Tuple *tuple;
198 const char *key;
199
200 if (!eina_iterator_next(et->classes, (void **)&key)) return EINA_FALSE;
201 if (!key) return EINA_FALSE;
202
203 tuple = calloc(1, sizeof(Efl_Observable_Tuple));
204 if (!tuple) return EINA_FALSE;
205
206 tuple->key = key;
207 tuple->data = efl_observable_observers_iterator_new(et->obs, key);
208
209 et->tuples = eina_list_append(et->tuples, tuple);
210 *data = tuple;
211
212 return EINA_TRUE;
213}
214
215static void *
216_efl_observable_iterator_tuple_container(Eina_Iterator *it EINA_UNUSED)
217{
218 return NULL;
219}
220
221static void
222_efl_observable_iterator_tuple_free(Eina_Iterator *it)
223{
224 Efl_Observable_Iterator *et = (void *)it;
225 Efl_Observable_Tuple *tuple;
226
227 eina_iterator_free(et->classes);
228 EINA_LIST_FREE(et->tuples, tuple)
229 {
230 if (tuple->data)
231 eina_iterator_free(tuple->data);
232 free(tuple);
233 }
234 EINA_MAGIC_SET(&et->iterator, 0);
235 free(et);
236}
237
238EOLIAN static Eina_Iterator *
239_efl_observable_iterator_tuple_new(Eo *obj, Efl_Observable_Data *pd)
240{
241 Efl_Observable_Iterator *it;
242
243 it = calloc(1, sizeof(Efl_Observable_Iterator));
244 if (!it) return NULL;
245
246 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
247 it->classes = eina_hash_iterator_key_new(pd->observers);
248 it->obs = obj;
249
250 it->iterator.version = EINA_ITERATOR_VERSION;
251 it->iterator.next = _efl_observable_iterator_tuple_next;
252 it->iterator.get_container = _efl_observable_iterator_tuple_container;
253 it->iterator.free = _efl_observable_iterator_tuple_free;
254
255 return &it->iterator;
256}
257
258#include "efl_observable.eo.c"
259#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 @@
1interface Efl.Observer {
2 methods {
3 update @virtual_pure {
4 [[Update observer according to the changes of observable object.
5
6 @since 1.19]]
7 params {
8 /* FIXME: obs should be Efl.Observable, but cyclic dependency error occurs. */
9 @in obs: Efl.Object; [[An observable object]]
10 @in key: string; [[A key to classify observer groups]]
11 @in data: void_ptr; [[Required data to update the observer, usually passed by observable object]]
12 }
13 }
14 }
15}
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
38 vanilla (upstream) EFL. Contains $EFL_VERSION_FLAVOR.]] 38 vanilla (upstream) EFL. Contains $EFL_VERSION_FLAVOR.]]
39 build_id: string; [[Contains $EFL_BUILD_ID.]] 39 build_id: string; [[Contains $EFL_BUILD_ID.]]
40} 40}
41
42struct Efl.Observable.Tuple
43{
44 key: string;
45 data: free(own(iterator<Efl.Observer>), eina_iterator_free);
46}