eo: replace loop_get with object_find

Summary:
object_find is more generic, so other mechanisms can also reuse the
code.
The object itself has to support the function, so there is no need for
eo_isa which would have a negative performance impact.
The base class implementation calls interface_get on the parent, so a
override of the function can just call the super function to continue in
the recursion.

Test Plan: just run the eo test suite

Reviewers: raster, tasn, jpeg

Reviewed By: tasn, jpeg

Subscribers: felipealmeida, netstar, cedric, jpeg

Differential Revision: https://phab.enlightenment.org/D3909
This commit is contained in:
Marcel Hollerbach 2016-05-04 10:08:00 +02:00
parent 1ee72bbf04
commit c66695bedb
7 changed files with 56 additions and 29 deletions

View File

@ -2749,9 +2749,11 @@ _efl_loop_quit(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
}
EOLIAN static Eo_Base *
_efl_loop_eo_base_loop_get(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
_efl_loop_eo_base_provider_find(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, const Eo_Base *klass)
{
return obj;
if (klass == EFL_LOOP_CLASS) return obj;
return eo_provider_find(eo_super(obj, EFL_LOOP_CLASS), klass);
}
static Eina_Bool

View File

@ -47,6 +47,6 @@ class Efl.Loop (Eo.Base)
}
implements {
Eo.Base.constructor;
Eo.Base.loop.get;
Eo.Base.provider_find;
}
}

View File

@ -146,23 +146,20 @@ abstract Eo.Base ()
finalized: bool;
}
}
@property loop {
[[The owning loop object.
provider_find {
[[Searches up in the object tree for a provider which knows the given class/interface.
Objects that have anything to do with I/O, time based events
or anything async should have an owining loop. They will ask
their parent for the owning loop and iterate until the
toplevel/root object. The root object should be a loop object
which will return itself. Some objects may shortcut this
and be fixed to live in only a single loop. Either way all
you need to do is get the loop for an object and use that
for I/O, timing etc. needs.
]]
get {
}
values {
obj: Eo.Base *; [[ XXX: this should be Efl.Loop *; ]]
}
The object from the provider will then be returned.
The base implementation calls the provider_find function on the object parent,
and returnes its result. If no parent is present NULL is returned.
Each implementation has to support this function by overriding
it and returning itself if the interface matches the parameter.
If this is not done the class cannot be found up in the object tree.
]]
params {
klass : const(Eo.Base)*; [[The class identifier to search for]]
}
return : Eo.Base*;
}
constructor {
[[Call the object's constructor.

View File

@ -546,14 +546,14 @@ _eo_base_finalized_get(Eo *obj_id, Eo_Base_Data *pd EINA_UNUSED)
return obj->finalized;
}
// XXX: this should be Efl_Loop *;
EOLIAN static Eo_Base *
_eo_base_loop_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd)
_eo_base_provider_find(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const Eo_Base *klass)
{
if (!pd->parent) return eo_loop_get(pd->parent);
if (pd->parent) return eo_provider_find(pd->parent, klass);
return NULL;
}
/* Children accessor */
typedef struct _Eo_Children_Iterator Eo_Children_Iterator;
struct _Eo_Children_Iterator

View File

@ -137,3 +137,28 @@ static const Eo_Class_Description class_desc2 = {
};
EO_DEFINE_CLASS(simple2_class_get, &class_desc2, EO_CLASS, NULL)
static Eo_Base*
_interface_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const Eo_Base *klass)
{
if (klass == SEARCHABLE_CLASS) return obj;
return eo_provider_find(eo_super(obj, SEARCHABLE_CLASS), klass);
}
static Eo_Op_Description op_descs_searchable[] = {
EO_OP_FUNC_OVERRIDE(eo_provider_find, _interface_get)
};
static const Eo_Class_Description class_desc_searchable = {
EO_VERSION,
"Searchable",
EO_CLASS_TYPE_REGULAR,
EO_CLASS_DESCRIPTION_OPS(op_descs_searchable),
NULL,
0,
NULL,
NULL
};
EO_DEFINE_CLASS(searchable_class_get, &class_desc_searchable, EO_CLASS, NULL)

View File

@ -29,4 +29,7 @@ EAPI int simple2_class_beef_get(const Eo_Class *obj);
#define SIMPLE2_CLASS simple2_class_get()
const Eo_Class *simple2_class_get(void);
#define SEARCHABLE_CLASS searchable_class_get()
const Eo_Class *searchable_class_get(void);
#endif

View File

@ -1140,16 +1140,16 @@ START_TEST(eo_comment)
}
END_TEST
START_TEST(eo_loop)
START_TEST(eo_rec_interface)
{
eo_init();
Eo *obj = eo_add(SIMPLE_CLASS, NULL);
Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
Eo *s = eo_add(SEARCHABLE_CLASS, NULL);
Eo *obj = eo_add(SIMPLE_CLASS, s);
Eo *obj2 = eo_add(SIMPLE_CLASS, obj);
Eo *objtmp;
eo_parent_set(obj2, obj);
objtmp = eo_loop_get(obj2);
fail_if(NULL != objtmp);
objtmp = eo_provider_find(obj2, SEARCHABLE_CLASS);
fail_if(objtmp != s);
eo_del(obj);
@ -1177,5 +1177,5 @@ void eo_test_general(TCase *tc)
tcase_add_test(tc, eo_del_intercept);
tcase_add_test(tc, eo_name);
tcase_add_test(tc, eo_comment);
tcase_add_test(tc, eo_loop);
tcase_add_test(tc, eo_rec_interface);
}