cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=549bf6e2696e9d1d52cfd365397a98511b82f92b

commit 549bf6e2696e9d1d52cfd365397a98511b82f92b
Author: Cedric BAIL <[email protected]>
Date:   Fri Jan 18 14:04:59 2019 -0800

    eo: improve efl_isa to be able to know if a class is part of the hierarchy 
of another class.
    
    Reviewed-by: SangHyeon Jade Lee <[email protected]>
    Differential Revision: https://phab.enlightenment.org/D7703
---
 src/lib/eo/Eo.h                      |  5 ++++-
 src/lib/eo/eo.c                      | 28 ++++++++++++++++++++++++++++
 src/tests/eo/suite/eo_test_general.c |  2 ++
 3 files changed, 34 insertions(+), 1 deletion(-)

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

-- 


Reply via email to