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>
This commit is contained in:
Jee-Yong Um 2016-11-01 10:59:09 -07:00 committed by Cedric BAIL
parent ab9f0ae3ca
commit 0fd1445508
14 changed files with 514 additions and 416 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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.]]

View File

@ -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);

View File

@ -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"

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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)
{

View File

@ -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 <Efl_Model_Common.h>

View File

@ -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<Efl.Observer>), 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<Efl.Observable.Tuple>), eina_iterator_free);
}
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
}
}

View File

@ -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"

View File

@ -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]]
}
}
}
}

View File

@ -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<Efl.Observer>), eina_iterator_free);
}