diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 21a4bf25d2..de71a698b3 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -910,9 +910,12 @@ EAPI Eina_Bool efl_object_override(Eo *obj, const Efl_Object_Ops *ops); * @brief Check if an object "is a" klass. * @param obj The object to check * @param klass The klass to check against. - * @return @c EINA_TRUE if obj implements klass, @c EINA_FALSE otherwise. + * @return @c EINA_TRUE if obj implements klass or is an Efl_Class which inherits + * from/implements klass, @c EINA_FALSE otherwise. * * Notice: This function does not support composite objects. + * Note: that an Efl_Class is also an Efl_Object, so if you pass an Efl_Class + * as obj, it will check if that class contain klass. */ EAPI Eina_Bool efl_isa(const Eo *obj, const Efl_Class *klass); diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index 5d95ff04db..44a17ae8a9 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1756,6 +1756,30 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id) Eina_Bool isa = EINA_FALSE; if (EINA_UNLIKELY(!eo_id)) return EINA_FALSE; + + // Case where we are looking if eo_id is a class that contain klass_id + if (EINA_UNLIKELY(_eo_is_a_class(eo_id))) + { + const _Efl_Class **kls_itr; + + EO_CLASS_POINTER_GOTO(klass_id, klass, err_class); + EO_CLASS_POINTER_GOTO(eo_id, lookinto, err_class0); + + if (lookinto == klass) return EINA_TRUE; + + kls_itr = lookinto->mro; + if (!kls_itr) return EINA_FALSE; + + while (*kls_itr) + { + if ((*kls_itr) == klass) + return EINA_TRUE; + kls_itr++; + } + + return EINA_FALSE; + } + domain = ((Eo_Id)eo_id >> SHIFT_DOMAIN) & MASK_DOMAIN; data = _eo_table_data_get(); tdata = _eo_table_data_table_get(data, domain); @@ -1821,6 +1845,10 @@ err_shared_obj: EINA_COLD eina_lock_release(&(_eo_table_data_shared_data->obj_lock)); return EINA_FALSE; +err_class0: + _EO_POINTER_ERR(eo_id, "Class (%p) is an invalid ref.", eo_id); + return EINA_FALSE; + err_class: EINA_COLD _EO_POINTER_ERR(klass_id, "Class (%p) is an invalid ref.", klass_id); err_obj: diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c index 889bfdd294..a8e6391b2e 100644 --- a/src/tests/eo/suite/eo_test_general.c +++ b/src/tests/eo/suite/eo_test_general.c @@ -327,6 +327,8 @@ EFL_START_TEST(efl_data_safe_fetch) fail_if(!efl_isa(obj, SIMPLE_CLASS)); fail_if(!efl_isa(obj, SIMPLE2_CLASS)); fail_if(!efl_isa(obj, SIMPLE3_CLASS)); + fail_if(!efl_isa(SIMPLE3_CLASS, SIMPLE_CLASS)); + fail_if(!efl_isa(SIMPLE_CLASS, SIMPLE_CLASS)); fail_if(!efl_data_scope_safe_get(obj, SIMPLE_CLASS)); fail_if(!efl_data_scope_safe_get(obj, SIMPLE3_CLASS)); fail_if(efl_data_scope_safe_get(obj, SIMPLE2_CLASS) != NULL);