Eo: Added support for class functions.
authortasn <tasn>
Tue, 15 May 2012 14:16:58 +0000 (14:16 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 15 May 2012 14:16:58 +0000 (14:16 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@71119 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

examples/function_overrides/inherit2.c
examples/function_overrides/main.c
examples/function_overrides/simple.c
examples/function_overrides/simple.h
lib/Eo.h
lib/eo.c
tests/class_simple.c
tests/class_simple.h
tests/eo_test_class_errors.c

index 66f8168..e083236 100644 (file)
@@ -38,12 +38,22 @@ _print2(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UN
 }
 
 static void
+_class_print(const Eo_Class *klass, va_list *list)
+{
+   (void) list;
+   printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
+   fail_if(!eo_class_do_super(klass, simple_class_print()));
+   fail_if(eo_class_do_super(klass, simple_class_print2()));
+}
+
+static void
 _class_constructor(Eo_Class *klass)
 {
    const Eo_Op_Func_Description func_desc[] = {
         EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
         EO_OP_FUNC(INHERIT2_ID(INHERIT2_SUB_ID_PRINT), _print),
         EO_OP_FUNC(INHERIT2_ID(INHERIT2_SUB_ID_PRINT2), _print2),
+        EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT), _class_print),
         EO_OP_FUNC_SENTINEL
    };
 
index 16e9682..4eb770d 100644 (file)
@@ -38,6 +38,15 @@ main(int argc, char *argv[])
 
    fail_if(eo_do_super(obj, simple_a_print()));
 
+   fail_if(eo_do(obj, simple_class_print()));
+
+   fail_if(!eo_class_do(SIMPLE_CLASS, simple_class_print()));
+   fail_if(!eo_class_do(INHERIT_CLASS, simple_class_print()));
+   fail_if(!eo_class_do(INHERIT2_CLASS, simple_class_print()));
+   fail_if(!eo_class_do(INHERIT3_CLASS, simple_class_print()));
+
+   fail_if(eo_class_do(SIMPLE_CLASS, simple_a_print()));
+
    eo_constructor_super(obj);
    eo_destructor_super(obj);
 
index fa152d2..c4dea10 100644 (file)
@@ -2,6 +2,7 @@
 #include "simple.h"
 
 #include "config.h"
+#include "../eunit_tests.h"
 
 EAPI Eo_Op SIMPLE_BASE_ID = 0;
 
@@ -26,11 +27,29 @@ _a_print(const Eo *obj EINA_UNUSED, const void *class_data, va_list *list)
 }
 
 static void
+_class_print(const Eo_Class *klass, va_list *list)
+{
+   (void) list;
+   printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
+   fail_if(eo_class_do_super(klass, simple_class_print()));
+   fail_if(eo_class_do_super(klass, simple_class_print2()));
+}
+
+static void
+_class_print2(const Eo_Class *klass, va_list *list)
+{
+   (void) list;
+   printf("Print %s-%s\n", eo_class_name_get(klass), eo_class_name_get(MY_CLASS));
+}
+
+static void
 _class_constructor(Eo_Class *klass)
 {
    const Eo_Op_Func_Description func_desc[] = {
         EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
         EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
+        EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT), _class_print),
+        EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT2), _class_print2),
         EO_OP_FUNC_SENTINEL
    };
 
@@ -40,6 +59,8 @@ _class_constructor(Eo_Class *klass)
 static const Eo_Op_Description op_desc[] = {
      EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
      EO_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
+     EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_PRINT, "", "Print class name."),
+     EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_PRINT2, "", "Print2 class name."),
      EO_OP_DESCRIPTION_SENTINEL
 };
 
index c2c8766..4958e05 100644 (file)
@@ -8,6 +8,8 @@ extern EAPI Eo_Op SIMPLE_BASE_ID;
 enum {
      SIMPLE_SUB_ID_A_SET,
      SIMPLE_SUB_ID_A_PRINT,
+     SIMPLE_SUB_ID_CLASS_PRINT,
+     SIMPLE_SUB_ID_CLASS_PRINT2,
      SIMPLE_SUB_ID_LAST
 };
 
@@ -20,6 +22,8 @@ typedef struct
 
 #define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
 #define simple_a_print() SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT)
+#define simple_class_print() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT)
+#define simple_class_print2() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_PRINT2)
 
 extern const Eo_Event_Description _SIG_A_CHANGED;
 #define SIG_A_CHANGED (&(_SIG_A_CHANGED))
index e34507e..1e41674 100644 (file)
--- a/lib/Eo.h
+++ b/lib/Eo.h
 EAPI extern Eina_Lock _eo_class_creation_lock;
 
 /**
+ * @internal
+ * An enum representing the possible types of an Op.
+ */
+enum _Eo_Op_Type
+{
+   EO_OP_TYPE_REGULAR = 0, /**< Regular op. */
+   EO_OP_TYPE_CONST, /**< Const op - object should not change. */
+   EO_OP_TYPE_CLASS, /**< Class op - a class op. Like static in Java/C++. */
+};
+
+/**
+ * @internal
+ * @typedef Eo_Op_Type
+ * A convenience typedef for #_Eo_Op_Type.
+ */
+typedef enum _Eo_Op_Type Eo_Op_Type;
+
+/**
  * @defgroup Eo Eo Generic Object System
  *
  * The Eo generic object system. It was designed to be the base object
@@ -76,6 +94,13 @@ typedef struct _Eo Eo;
 typedef unsigned int Eo_Op;
 
 /**
+ * @typedef Eo_Class
+ * The basic Object class type.
+ * @ingroup Eo_Class
+ */
+typedef struct _Eo_Class Eo_Class;
+
+/**
  * @def EO_NOOP
  * A special #Eo_Op meaning "No operation".
  */
@@ -101,6 +126,16 @@ typedef void (*eo_op_func_type)(Eo *, void *class_data, va_list *list);
 typedef void (*eo_op_func_type_const)(const Eo *, const void *class_data, va_list *list);
 
 /**
+ * @typedef eo_op_func_type_class
+ * The type of the class Op functions. This is the same as #eo_op_func_type,\
+ * exepct that it's for usage with class functions, and not with object
+ * functions.
+ *
+ * @see eo_op_func_type
+ */
+typedef void (*eo_op_func_type_class)(const Eo_Class *, va_list *list);
+
+/**
  * @addtogroup Eo_Events Eo's Event Handling
  * @{
  */
@@ -142,12 +177,6 @@ typedef struct _Eo_Event_Description Eo_Event_Description;
  */
 
 /**
- * @typedef Eo_Class
- * The basic Object class type.
- */
-typedef struct _Eo_Class Eo_Class;
-
-/**
  * @def EO_DEFINE_CLASS(class_get_func_name, class_desc, parent_class, ...)
  * A convenience macro to be used for creating the class_get function. This
  * macro is fairly simple but should still be used as it'll let us improve
@@ -218,7 +247,7 @@ struct _Eo_Op_Func_Description
 {
    Eo_Op op; /**< The op */
    eo_op_func_type func; /**< The function to call for the op. */
-   Eina_Bool constant; /**< @c EINA_TRUE if this function is a const. */
+   Eo_Op_Type op_type; /**< The type of the op */
 };
 
 /**
@@ -234,7 +263,7 @@ typedef struct _Eo_Op_Func_Description Eo_Op_Func_Description;
  *
  * @see EO_OP_FUNC_CONST
  */
-#define EO_OP_FUNC(op, func) { op, EO_TYPECHECK(eo_op_func_type, func), EINA_FALSE }
+#define EO_OP_FUNC(op, func) { op, EO_TYPECHECK(eo_op_func_type, func), EO_OP_TYPE_REGULAR }
 
 /**
  * @def EO_OP_FUNC_CONST(op, func)
@@ -244,7 +273,17 @@ typedef struct _Eo_Op_Func_Description Eo_Op_Func_Description;
  *
  * @see EO_OP_FUNC
  */
-#define EO_OP_FUNC_CONST(op, func) { op, (eo_op_func_type) EO_TYPECHECK(eo_op_func_type_const, func), EINA_TRUE }
+#define EO_OP_FUNC_CONST(op, func) { op, (eo_op_func_type) EO_TYPECHECK(eo_op_func_type_const, func), EO_OP_TYPE_CONST }
+
+/**
+ * @def EO_OP_FUNC_CLASS(op, func)
+ * A convenience macro to be used when populating the #Eo_Op_Func_Description
+ * array.
+ * The same as #EO_OP_FUNC but for class functions.
+ *
+ * @see EO_OP_FUNC
+ */
+#define EO_OP_FUNC_CLASS(op, func) { op, (eo_op_func_type) EO_TYPECHECK(eo_op_func_type_class, func), EO_OP_TYPE_CLASS }
 
 /**
  * @def EO_OP_FUNC_SENTINEL
@@ -263,7 +302,7 @@ struct _Eo_Op_Description
    const char *name; /**< The name of the op. */
    const char *type; /**< descripbes the Op's function signature. */
    const char *doc; /**< Explanation about the Op. */
-   Eina_Bool constant; /**< @c EINA_TRUE if this op's implementation should not change the obj. */
+   Eo_Op_Type op_type; /**< The type of the Op. */
 };
 
 /**
@@ -317,10 +356,11 @@ typedef struct _Eo_Class_Description Eo_Class_Description;
  * @param type The type string for the op.
  * @param doc Additional doc for the op.
  * @see Eo_Op_Description
+ * @see EO_OP_DESCRIPTION_CLASS
  * @see EO_OP_DESCRIPTION_CONST
  * @see EO_OP_DESCRIPTION_SENTINEL
  */
-#define EO_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_FALSE }
+#define EO_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc, EO_OP_TYPE_REGULAR }
 
 /**
  * @def EO_OP_DESCRIPTION_CONST(op, type, doc)
@@ -334,7 +374,21 @@ typedef struct _Eo_Class_Description Eo_Class_Description;
  * @see EO_OP_DESCRIPTION
  * @see EO_OP_DESCRIPTION_SENTINEL
  */
-#define EO_OP_DESCRIPTION_CONST(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_TRUE }
+#define EO_OP_DESCRIPTION_CONST(sub_id, type, doc) { sub_id, #sub_id, type, doc, EO_OP_TYPE_CONST }
+
+/**
+ * @def EO_OP_DESCRIPTION_CLASS(op, type, doc)
+ * An helper macro to help populating #Eo_Op_Description
+ * This macro is the same as EO_OP_DESCRIPTION but indicates that the op's
+ * implementation is of type CLASS.
+ * @param sub_id The sub id of the op being described.
+ * @param type The type string for the op.
+ * @param doc Additional doc for the op.
+ * @see Eo_Op_Description
+ * @see EO_OP_DESCRIPTION
+ * @see EO_OP_DESCRIPTION_SENTINEL
+ */
+#define EO_OP_DESCRIPTION_CLASS(sub_id, type, doc) { sub_id, #sub_id, type, doc, EO_OP_TYPE_CLASS }
 
 /**
  * @def EO_OP_DESCRIPTION_SENTINEL
@@ -412,9 +466,16 @@ EAPI Eina_Bool eo_shutdown(void);
 #define eo_query(obj, ...) eo_do_internal((Eo *) EO_TYPECHECK(const Eo *, obj), EINA_TRUE, __VA_ARGS__, EO_NOOP)
 
 /**
- * @brief Issues ops on an object.
+ * @def eo_class_do
+ * A convenience wrapper around eo_class_do_internal()
+ * @see eo_class_do_internal
+ */
+#define eo_class_do(klass, ...) eo_class_do_internal(klass, __VA_ARGS__, EO_NOOP)
+
+/**
+ * @brief Calls op functions of an object
  * @param obj The object to work on
- * @param constant @c EINA_TRUE if this call is on a constant object.
+ * @param op_type The type of the ops that are passed.
  * @param ... NULL terminated list of OPs and parameters.
  * @return @c EINA_TRUE on success.
  *
@@ -423,7 +484,20 @@ EAPI Eina_Bool eo_shutdown(void);
  *
  * @see #eo_do
  */
-EAPI Eina_Bool eo_do_internal(Eo *obj, Eina_Bool constant, ...);
+EAPI Eina_Bool eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...);
+
+/**
+ * @brief Calls op functions of a class.
+ * @param klass The class to work on
+ * @param ... NULL terminated list of OPs and parameters.
+ * @return @c EINA_TRUE on success.
+ *
+ * Use the helper macros, don't pass the parameters manually.
+ * Use #eo_do instead of this function.
+ *
+ * @see #eo_class_do
+ */
+EAPI Eina_Bool eo_class_do_internal(const Eo_Class *klass, ...);
 
 /**
  * @brief Calls the super function for the specific op.
@@ -457,8 +531,20 @@ EAPI Eina_Bool eo_do_internal(Eo *obj, Eina_Bool constant, ...);
 
 /**
  * @brief Calls the super function for the specific op.
+ * @param klass The klass to work on
+ * @param ... list of parameters.
+ * @return @c EINA_TRUE on success.
+ *
+ * Unlike eo_class_do(), this function only accepts one op.
+ *
+ * @see #eo_class_do
+ */
+#define eo_class_do_super(klass, ...) eo_class_do_super_internal(klass, __VA_ARGS__)
+
+/**
+ * @brief Calls the super function for the specific op.
  * @param obj The object to work on
- * @param constant @c EINA_TRUE if this call is on a constant object.
+ * @param op_type The type of the ops that are passed.
  * @param op The wanted op.
  * @param ... list of parameters.
  * @return @c EINA_TRUE on success.
@@ -469,7 +555,21 @@ EAPI Eina_Bool eo_do_internal(Eo *obj, Eina_Bool constant, ...);
  * @see #eo_do_super
  * @see #eo_query_super
  */
-EAPI Eina_Bool eo_do_super_internal(Eo *obj, Eina_Bool constant, Eo_Op op, ...);
+EAPI Eina_Bool eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...);
+
+/**
+ * @brief Calls the super function for the specific op.
+ * @param klass The klass to work on
+ * @param op The wanted op.
+ * @param ... list of parameters.
+ * @return @c EINA_TRUE on success.
+ *
+ * Don't use this function, use the wrapping macros instead.
+ *
+ * @see #eo_class_do
+ * @see #eo_class_do_super
+ */
+EAPI Eina_Bool eo_class_do_super_internal(const Eo_Class *klass, Eo_Op op, ...);
 
 /**
  * @brief Gets the class of the object.
index 48f5858..81bc0ed 100644 (file)
--- a/lib/eo.c
+++ b/lib/eo.c
@@ -113,6 +113,7 @@ struct _Eo_Class
    size_t extn_data_size;
 
    const Eo_Class **mro;
+   Eo_Kls_Itr mro_itr;
 
    size_t data_offset; /* < Offset of the data within object data. */
 
@@ -340,29 +341,62 @@ _eo_kls_itr_reached_end(const Eo_Kls_Itr *cur)
    return !(*kls_itr && *(kls_itr + 1));
 }
 
+static inline const op_type_funcs *
+_eo_kls_itr_func_get(const Eo_Class *klass, Eo_Kls_Itr *mro_itr, Eo_Op op, Eo_Kls_Itr *prev_state)
+{
+   _eo_kls_itr_init(klass, mro_itr, op, prev_state);
+   klass = _eo_kls_itr_get(mro_itr);
+   if (klass)
+     {
+        const op_type_funcs *func = _dich_func_get(klass, op);
+
+        if (func && func->func)
+          {
+             return func;
+          }
+     }
+
+   return NULL;
+}
+
+static void
+_eo_op_err_no_op_print(Eo_Op op, const Eo_Class *klass)
+{
+   const Eo_Class *op_klass = OP_CLASS_GET(op);
+   const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
+   ERR("Can't find func for op %x ('%s' of domain '%s') for class '%s'. Aborting.",
+         op, _eo_op_id_name_get(op), _dom_name,
+         (klass) ? klass->desc->name : NULL);
+}
+
 static Eina_Bool
-_eo_op_internal(Eo *obj, Eina_Bool constant, Eo_Op op, va_list *p_list)
+_eo_op_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
 {
-   const Eo_Class *klass;
    Eina_Bool ret = EINA_FALSE;
 
    const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
 
-   if (op_desc &&
-         ((constant == EINA_TRUE) && (op_desc->constant == EINA_FALSE)))
+   if (op_desc)
      {
-        ERR("Tried calling non-const or non-existant op '%s' (%d) from a const (query) function.", (op_desc) ? op_desc->name : NULL, op);
-        return EINA_FALSE;
+        if (op_desc->op_type == EO_OP_TYPE_CLASS)
+          {
+             ERR("Tried calling a class op '%s' (%d) from a non-class context.", (op_desc) ? op_desc->name : NULL, op);
+             return EINA_FALSE;
+          }
+        else if ((op_type == EO_OP_TYPE_CONST) &&
+              (op_desc->op_type != EO_OP_TYPE_CONST))
+          {
+             ERR("Tried calling non-const or non-existant op '%s' (%d) from a const (query) function.", (op_desc) ? op_desc->name : NULL, op);
+             return EINA_FALSE;
+          }
      }
 
    Eo_Kls_Itr prev_state;
-   _eo_kls_itr_init(obj->klass, &obj->mro_itr, op, &prev_state);
-   klass = _eo_kls_itr_get(&obj->mro_itr);
-   if (klass)
-     {
-        const op_type_funcs *func = _dich_func_get(klass, op);
 
-        if (func && func->func)
+     {
+        const op_type_funcs *func =
+           _eo_kls_itr_func_get(obj->klass, &obj->mro_itr, op, &prev_state);
+        if (func)
           {
              func->func(obj, _eo_data_get(obj, func->src), p_list);
              ret = EINA_TRUE;
@@ -376,7 +410,7 @@ _eo_op_internal(Eo *obj, Eina_Bool constant, Eo_Op op, va_list *p_list)
         Eo *emb_obj;
         EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
           {
-             if (_eo_op_internal(emb_obj, constant, op, p_list))
+             if (_eo_op_internal(emb_obj, op_type, op, p_list))
                {
                   ret = EINA_TRUE;
                   goto end;
@@ -390,7 +424,7 @@ end:
 }
 
 EAPI Eina_Bool
-eo_do_internal(Eo *obj, Eina_Bool constant, ...)
+eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
 {
    Eina_Bool ret = EINA_TRUE;
    Eo_Op op = EO_NOOP;
@@ -400,18 +434,14 @@ eo_do_internal(Eo *obj, Eina_Bool constant, ...)
 
    _eo_ref(obj);
 
-   va_start(p_list, constant);
+   va_start(p_list, op_type);
 
    op = va_arg(p_list, Eo_Op);
    while (op)
      {
-        if (!_eo_op_internal(obj, constant, op, &p_list))
+        if (!_eo_op_internal(obj, op_type, op, &p_list))
           {
-             const Eo_Class *op_klass = OP_CLASS_GET(op);
-             const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
-             ERR("Can't find func for op %x ('%s' of domain '%s') for class '%s'. Aborting.",
-                   op, _eo_op_id_name_get(op), _dom_name,
-                   obj->klass->desc->name);
+             _eo_op_err_no_op_print(op, obj->klass);
              ret = EINA_FALSE;
              break;
           }
@@ -425,27 +455,110 @@ eo_do_internal(Eo *obj, Eina_Bool constant, ...)
 }
 
 EAPI Eina_Bool
-eo_do_super_internal(Eo *obj, Eina_Bool constant, Eo_Op op, ...)
+eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...)
 {
-   const Eo_Class *obj_klass;
+   const Eo_Class *nklass;
    Eina_Bool ret = EINA_TRUE;
    va_list p_list;
    EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE);
 
    /* Advance the kls itr. */
-   obj_klass = _eo_kls_itr_next(&obj->mro_itr, op);
+   nklass = _eo_kls_itr_next(&obj->mro_itr, op);
 
    if (obj->mro_itr.op != op)
       return EINA_FALSE;
 
    va_start(p_list, op);
-   if (!_eo_op_internal(obj, constant, op, &p_list))
+   if (!_eo_op_internal(obj, op_type, op, &p_list))
+     {
+        _eo_op_err_no_op_print(op, nklass);
+        ret = EINA_FALSE;
+     }
+   va_end(p_list);
+
+   return ret;
+}
+
+static Eina_Bool
+_eo_class_op_internal(Eo_Class *klass, Eo_Op op, va_list *p_list)
+{
+   Eina_Bool ret = EINA_FALSE;
+
+   const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
+
+   if (op_desc)
+     {
+        if (op_desc->op_type != EO_OP_TYPE_CLASS)
+          {
+             ERR("Tried calling an instant op '%s' (%d) from a class context.", (op_desc) ? op_desc->name : NULL, op);
+             return EINA_FALSE;
+          }
+     }
+
+   Eo_Kls_Itr prev_state;
+
+     {
+        const op_type_funcs *func =
+           _eo_kls_itr_func_get(klass, &klass->mro_itr, op, &prev_state);
+        if (func)
+          {
+             ((eo_op_func_type_class) func->func)(klass, p_list);
+             ret = EINA_TRUE;
+             goto end;
+          }
+     }
+
+end:
+   _eo_kls_itr_end(&klass->mro_itr, &prev_state);
+   return ret;
+}
+
+EAPI Eina_Bool
+eo_class_do_internal(const Eo_Class *klass, ...)
+{
+   Eina_Bool ret = EINA_TRUE;
+   Eo_Op op = EO_NOOP;
+   va_list p_list;
+
+   EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
+
+   va_start(p_list, klass);
+
+   op = va_arg(p_list, Eo_Op);
+   while (op)
+     {
+        if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
+          {
+             _eo_op_err_no_op_print(op, klass);
+             ret = EINA_FALSE;
+             break;
+          }
+        op = va_arg(p_list, Eo_Op);
+     }
+
+   va_end(p_list);
+
+   return ret;
+}
+
+EAPI Eina_Bool
+eo_class_do_super_internal(const Eo_Class *klass, Eo_Op op, ...)
+{
+   const Eo_Class *nklass;
+   Eina_Bool ret = EINA_TRUE;
+   va_list p_list;
+   EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
+
+   /* Advance the kls itr. */
+   nklass = _eo_kls_itr_next(&((Eo_Class *) klass)->mro_itr, op);
+
+   if (klass->mro_itr.op != op)
+      return EINA_FALSE;
+
+   va_start(p_list, op);
+   if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
      {
-        const Eo_Class *op_klass = OP_CLASS_GET(op);
-        const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
-        ERR("Can't find func for op %x ('%s' of domain '%s') for class '%s'. Aborting.",
-              op, _eo_op_id_name_get(op), _dom_name,
-              (obj_klass) ? obj_klass->desc->name : NULL);
+        _eo_op_err_no_op_print(op, nklass);
         ret = EINA_FALSE;
      }
    va_end(p_list);
@@ -635,13 +748,13 @@ eo_class_funcs_set(Eo_Class *klass, const Eo_Op_Func_Description *func_descs)
           {
              const Eo_Op_Description *op_desc = _eo_op_id_desc_get(itr->op);
 
-             if (EINA_LIKELY(!op_desc || (itr->constant == op_desc->constant)))
+             if (EINA_LIKELY(!op_desc || (itr->op_type == op_desc->op_type)))
                {
                   _dich_func_set(klass, itr->op, itr->func);
                }
              else
                {
-                  ERR("Set function's constant property (%d) is different than the one in the op description (%d) for op '%s' in class '%s'.", itr->constant, op_desc->constant, op_desc->name, klass->desc->name);
+                  ERR("Set function's op type (%d) is different than the one in the op description (%d) for op '%s' in class '%s'.", itr->op_type, op_desc->op_type, op_desc->name, klass->desc->name);
                }
           }
      }
index 889be04..1037641 100644 (file)
@@ -26,11 +26,19 @@ _a_print(const Eo *obj EINA_UNUSED, const void *class_data, va_list *list)
 }
 
 static void
+_class_hi_print(const Eo_Class *klass, va_list *list)
+{
+   (void) list;
+   printf("Hi Print %s\n", eo_class_name_get(klass));
+}
+
+static void
 _class_constructor(Eo_Class *klass)
 {
    const Eo_Op_Func_Description func_desc[] = {
         EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
         EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
+        EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), _class_hi_print),
         EO_OP_FUNC_SENTINEL
    };
 
@@ -40,6 +48,7 @@ _class_constructor(Eo_Class *klass)
 static const Eo_Op_Description op_desc[] = {
      EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
      EO_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
+     EO_OP_DESCRIPTION_CLASS(SIMPLE_SUB_ID_CLASS_HI_PRINT, "", "Print Hi"),
      EO_OP_DESCRIPTION_SENTINEL
 };
 
index c2c8766..35a58d2 100644 (file)
@@ -8,6 +8,7 @@ extern EAPI Eo_Op SIMPLE_BASE_ID;
 enum {
      SIMPLE_SUB_ID_A_SET,
      SIMPLE_SUB_ID_A_PRINT,
+     SIMPLE_SUB_ID_CLASS_HI_PRINT,
      SIMPLE_SUB_ID_LAST
 };
 
@@ -20,6 +21,7 @@ typedef struct
 
 #define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
 #define simple_a_print() SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT)
+#define simple_class_hi_print() SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT)
 
 extern const Eo_Event_Description _SIG_A_CHANGED;
 #define SIG_A_CHANGED (&(_SIG_A_CHANGED))
index d2ed29f..0a10035 100644 (file)
@@ -310,18 +310,28 @@ _const_ops_a_print(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *l
 }
 
 static void
+_const_ops_class_hi_print(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+   _const_ops_counter++;
+}
+
+static void
 _const_ops_class_constructor(Eo_Class *klass)
 {
    const Eo_Op_Func_Description func_desc[] = {
-        EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _const_ops_a_set),
-        EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _const_ops_a_print),
+        EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), (eo_op_func_type_const) _const_ops_a_set),
+        EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), (eo_op_func_type) _const_ops_a_print),
+        EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), (eo_op_func_type_class) _const_ops_a_set),
+        EO_OP_FUNC_CLASS(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), (eo_op_func_type_class) _const_ops_a_print),
+        EO_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), (eo_op_func_type_const) _const_ops_class_hi_print),
+        EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_CLASS_HI_PRINT), (eo_op_func_type) _const_ops_class_hi_print),
         EO_OP_FUNC_SENTINEL
    };
 
    eo_class_funcs_set(klass, func_desc);
 }
 
-START_TEST(eo_const_ops)
+START_TEST(eo_op_types)
 {
    eo_init();
 
@@ -343,7 +353,7 @@ START_TEST(eo_const_ops)
    fail_if(!klass);
 
    Eo *obj = eo_add(klass, NULL);
-   eo_do(obj, simple_a_set(7), simple_a_print());
+   eo_do(obj, simple_a_set(7), simple_a_print(), simple_class_hi_print());
    fail_if(_const_ops_counter != 0);
 
    eo_unref(obj);
@@ -358,5 +368,5 @@ void eo_test_class_errors(TCase *tc)
    tcase_add_test(tc, eo_inherit_errors);
    tcase_add_test(tc, eo_inconsistent_mro);
    tcase_add_test(tc, eo_bad_interface);
-   tcase_add_test(tc, eo_const_ops);
+   tcase_add_test(tc, eo_op_types);
 }