Eobj: Added infrastructure for const functions and eobj_query.
authorTom Hacohen <tom@stosb.com>
Tue, 24 Apr 2012 08:04:14 +0000 (08:04 +0000)
committerTom Hacohen <tom@stosb.com>
Tue, 24 Apr 2012 08:04:14 +0000 (08:04 +0000)
SVN revision: 70431

18 files changed:
legacy/eobj/examples/access/inherit.c
legacy/eobj/examples/composite_objects/comp.c
legacy/eobj/examples/composite_objects/simple.c
legacy/eobj/examples/constructors/mixin.c
legacy/eobj/examples/constructors/simple.c
legacy/eobj/examples/evas/evas_obj.c
legacy/eobj/examples/evas/evas_obj.h
legacy/eobj/examples/function_overrides/simple.c
legacy/eobj/examples/mixin/mixin.c
legacy/eobj/examples/mixin/mixin2.c
legacy/eobj/examples/mixin/mixin3.c
legacy/eobj/examples/mixin/simple.c
legacy/eobj/lib/Eobj.h
legacy/eobj/lib/eobj.c
legacy/eobj/lib/eobj_base_class.c
legacy/eobj/tests/class_simple.c
legacy/eobj/tests/eobj_test_class_errors.c
legacy/eobj/tests/eobj_test_general.c

index 26860bc..b2fc51a 100644 (file)
@@ -11,7 +11,7 @@ EAPI Eobj_Op INHERIT_BASE_ID = 0;
 #define MY_CLASS INHERIT_CLASS
 
 static void
-_prot_print(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
+_prot_print(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
 {
    Simple_Protected_Data *pd = eobj_data_get(obj, SIMPLE_CLASS);
    (void) list;
@@ -22,7 +22,7 @@ static void
 _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
-        EOBJ_OP_FUNC(INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT), _prot_print),
+        EOBJ_OP_FUNC_CONST(INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT), _prot_print),
         EOBJ_OP_FUNC_SENTINEL
    };
 
@@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass)
 }
 
 static const Eobj_Op_Description op_desc[] = {
-     EOBJ_OP_DESCRIPTION(INHERIT_SUB_ID_PROT_PRINT, "", "Print protected var x1."),
+     EOBJ_OP_DESCRIPTION_CONST(INHERIT_SUB_ID_PROT_PRINT, "", "Print protected var x1."),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
 
index 0129a1e..d1239b8 100644 (file)
@@ -11,11 +11,11 @@ EAPI Eobj_Op COMP_BASE_ID = 0;
 #define MY_CLASS COMP_CLASS
 
 static void
-_a_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
+_a_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
 {
    int *a;
    a = va_arg(*list, int *);
-   eobj_do_super(obj, SIMPLE_A_GET(a));
+   eobj_query_super(obj, SIMPLE_A_GET(a));
 }
 
 static void
@@ -39,7 +39,7 @@ static void
 _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
-        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
         EOBJ_OP_FUNC_SENTINEL
    };
 
index 446ff35..5687eb0 100644 (file)
@@ -23,9 +23,9 @@ _a_set(Eobj *obj, void *class_data, va_list *list)
 }
 
 static void
-_a_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
+_a_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list)
 {
-   Simple_Public_Data *pd = class_data;
+   const Simple_Public_Data *pd = class_data;
    int *a;
    a = va_arg(*list, int *);
    *a = pd->a;
@@ -36,7 +36,7 @@ _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
         EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
-        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
         EOBJ_OP_FUNC_SENTINEL
    };
 
@@ -45,7 +45,7 @@ _class_constructor(Eobj_Class *klass)
 
 static const Eobj_Op_Description op_desc[] = {
      EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
-     EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
+     EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
 
index 8ecfd65..3399537 100644 (file)
@@ -9,10 +9,10 @@ EAPI Eobj_Op MIXIN_BASE_ID = 0;
 #define MY_CLASS MIXIN_CLASS
 
 static void
-_add_and_print_set(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
+_add_and_print_set(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
 {
    int a, b, x;
-   eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b));
+   eobj_query(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b));
    x = va_arg(*list, const int);
    printf("%s %d\n", __func__, a + b + x);
 }
@@ -39,7 +39,7 @@ static void
 _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
-        EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set),
+        EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set),
         EOBJ_OP_FUNC_SENTINEL
    };
 
@@ -47,7 +47,7 @@ _class_constructor(Eobj_Class *klass)
 }
 
 static const Eobj_Op_Description op_desc[] = {
-     EOBJ_OP_DESCRIPTION(MIXIN_SUB_ID_ADD_AND_SET, "i", "Add A + B + param and print it"),
+     EOBJ_OP_DESCRIPTION_CONST(MIXIN_SUB_ID_ADD_AND_SET, "i", "Add A + B + param and print it"),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
 
index c127776..3f050c4 100644 (file)
@@ -18,9 +18,9 @@ static char *class_var = NULL;
 
 #define _GET_SET_FUNC(name) \
 static void \
-_##name##_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) \
+_##name##_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) \
 { \
-   Private_Data *pd = class_data; \
+   const Private_Data *pd = class_data; \
    int *name; \
    name = va_arg(*list, int *); \
    *name = pd->name; \
@@ -62,9 +62,9 @@ _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
         EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
-        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
         EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set),
-        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
         EOBJ_OP_FUNC_SENTINEL
    };
 
@@ -81,9 +81,9 @@ _class_destructor(Eobj_Class *klass EINA_UNUSED)
 
 static const Eobj_Op_Description op_desc[] = {
      EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
-     EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
+     EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
      EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "i", "Set property B"),
-     EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "i", "Get property B"),
+     EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_B_GET, "i", "Get property B"),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
 
index 4289804..a7cb3d8 100644 (file)
@@ -47,7 +47,7 @@ _color_set(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
 }
 
 static void
-_color_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
+_color_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
 {
    Evas_Object *evas_obj = eobj_evas_object_get(obj);
    int *r, *g, *b, *a;
@@ -109,7 +109,7 @@ _class_constructor(Eobj_Class *klass)
         EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_POSITION_SET), _position_set),
         EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_SIZE_SET), _size_set),
         EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_SET), _color_set),
-        EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_GET), _color_get),
+        EOBJ_OP_FUNC_CONST(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_GET), _color_get),
         EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_VISIBILITY_SET), _visibility_set),
         EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_CHILD_ADD), _child_add),
         EOBJ_OP_FUNC_SENTINEL
@@ -122,7 +122,7 @@ static const Eobj_Op_Description op_desc[] = {
      EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_POSITION_SET, "ii", "Position of an evas object."),
      EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_SIZE_SET, "ii", "Size of an evas object."),
      EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_COLOR_SET, "iiii", "Color of an evas object."),
-     EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_COLOR_GET, "iiii", "Color of an evas object."),
+     EOBJ_OP_DESCRIPTION_CONST(EVAS_OBJ_SUB_ID_COLOR_GET, "iiii", "Color of an evas object."),
      EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_VISIBILITY_SET, "b", "Visibility of an evas object."),
      EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_CHILD_ADD, "o", "Add a child eobj."),
      EOBJ_OP_DESCRIPTION_SENTINEL
index 28c50e4..67f7951 100644 (file)
@@ -73,10 +73,10 @@ const Eobj_Class *evas_object_class_get(void) EINA_CONST;
 #define EVAS_OBJ_STR "Evas_Obj"
 /* FIXME: Hack in the meanwhile. */
 static inline Evas_Object *
-eobj_evas_object_get(Eobj *obj)
+eobj_evas_object_get(const Eobj *obj)
 {
    void *data;
-   eobj_do(obj, EOBJ_BASE_DATA_GET(EVAS_OBJ_STR, &data));
+   eobj_query(obj, EOBJ_BASE_DATA_GET(EVAS_OBJ_STR, &data));
    return data;
 }
 
index 1399c2c..adeabfb 100644 (file)
@@ -18,9 +18,9 @@ _a_set(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
 }
 
 static void
-_a_print(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
+_a_print(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list)
 {
-   Simple_Public_Data *pd = class_data;
+   const Simple_Public_Data *pd = class_data;
    (void) list;
    printf("Print %s %d\n", eobj_class_name_get(MY_CLASS), pd->a);
 }
@@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
         EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
-        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
         EOBJ_OP_FUNC_SENTINEL
    };
 
@@ -39,7 +39,7 @@ _class_constructor(Eobj_Class *klass)
 
 static const Eobj_Op_Description op_desc[] = {
      EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
-     EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
+     EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
 
index 2938097..dae8284 100644 (file)
@@ -9,10 +9,10 @@ EAPI Eobj_Op MIXIN_BASE_ID = 0;
 #define MY_CLASS MIXIN_CLASS
 
 static void
-_ab_sum_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
+_ab_sum_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
 {
    int a, b;
-   eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b));
+   eobj_query(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b));
    int *sum = va_arg(*list, int *);
    if (sum)
       *sum = a + b;
@@ -35,7 +35,7 @@ static void
 _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
-        EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
+        EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
         EOBJ_OP_FUNC_SENTINEL
    };
 
@@ -44,7 +44,7 @@ _class_constructor(Eobj_Class *klass)
 
 
 static const Eobj_Op_Description op_desc[] = {
-     EOBJ_OP_DESCRIPTION(MIXIN_SUB_ID_AB_SUM_GET, "i", "Get the sum of a and b."),
+     EOBJ_OP_DESCRIPTION_CONST(MIXIN_SUB_ID_AB_SUM_GET, "i", "Get the sum of a and b."),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
 
index f663f69..bd638f4 100644 (file)
 #define MY_CLASS MIXIN2_CLASS
 
 static void
-_ab_sum_get(Eobj *obj, void *class_data, va_list *list)
+_ab_sum_get(const Eobj *obj, const void *class_data, va_list *list)
 {
-   Mixin2_Public_Data *pd = class_data;
+   /* This cast is a hack just for the tests... */
+   Mixin2_Public_Data *pd = (Mixin2_Public_Data *) class_data;
    int *sum = va_arg(*list, int *);
    printf("%s %s\n", eobj_class_name_get(MY_CLASS), __func__);
-   eobj_do_super(obj, MIXIN_AB_SUM_GET(sum));
+   eobj_query_super(obj, MIXIN_AB_SUM_GET(sum));
 
    ++*sum;
    pd->count += 2;
 
      {
         int _a, _b;
-        eobj_do(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b));
+        eobj_query(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b));
         fail_if(*sum != _a + _b + 1);
      }
 }
@@ -43,7 +44,7 @@ static void
 _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
-        EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
+        EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
         EOBJ_OP_FUNC_SENTINEL
    };
 
index 4737828..349fe83 100644 (file)
 #define MY_CLASS MIXIN3_CLASS
 
 static void
-_ab_sum_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list)
+_ab_sum_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list)
 {
-   Mixin3_Public_Data *pd = class_data;
+   /* This cast is just a hack for the test. */
+   Mixin3_Public_Data *pd = (Mixin3_Public_Data *) class_data;
    int *sum = va_arg(*list, int *);
    printf("%s %s\n", eobj_class_name_get(MY_CLASS), __func__);
-   eobj_do_super(obj, MIXIN_AB_SUM_GET(sum));
+   eobj_query_super(obj, MIXIN_AB_SUM_GET(sum));
 
    ++*sum;
    pd->count += 3;
 
      {
         int _a, _b;
-        eobj_do(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b));
+        eobj_query(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b));
         fail_if(*sum != _a + _b + 2);
      }
 }
@@ -43,7 +44,7 @@ static void
 _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
-        EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
+        EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get),
         EOBJ_OP_FUNC_SENTINEL
    };
 
index 2d9ca2b..f6c6232 100644 (file)
@@ -18,9 +18,9 @@ typedef struct
 
 #define _GET_SET_FUNC(name) \
 static void \
-_##name##_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) \
+_##name##_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) \
 { \
-   Private_Data *pd = class_data; \
+   const Private_Data *pd = class_data; \
    int *name; \
    name = va_arg(*list, int *); \
    *name = pd->name; \
@@ -44,9 +44,9 @@ _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
         EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
-        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
         EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set),
-        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get),
         EOBJ_OP_FUNC_SENTINEL
    };
 
@@ -55,9 +55,9 @@ _class_constructor(Eobj_Class *klass)
 
 static const Eobj_Op_Description op_desc[] = {
      EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
-     EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
+     EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"),
      EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "i", "Set property B"),
-     EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "i", "Get property B"),
+     EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_B_GET, "i", "Get property B"),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
 
index b149d89..68eb4bd 100644 (file)
@@ -86,10 +86,22 @@ typedef unsigned int Eobj_Op;
  * @typedef eobj_op_func_type
  * The type of the Op functions. This is the type of the functions used by
  * Eobj.
+ *
+ * @see eobj_op_func_type_const
  */
 typedef void (*eobj_op_func_type)(Eobj *, void *class_data, va_list *list);
 
 /**
+ * @typedef eobj_op_func_type_const
+ * The type of the const Op functions. This is the type of the functions used
+ * by Eobj. This is the same as #eobj_op_func_type, except that this should
+ * be used with functions that don't modify the data.
+ *
+ * @see eobj_op_func_type
+ */
+typedef void (*eobj_op_func_type_const)(const Eobj *, const void *class_data, va_list *list);
+
+/**
  * @addtogroup Eobj_Events Eobj's Event Handling
  * @{
  */
@@ -207,6 +219,7 @@ struct _Eobj_Op_Func_Description
 {
    Eobj_Op op; /**< The op */
    eobj_op_func_type func; /**< The function to call for the op. */
+   Eina_Bool constant; /**< #EINA_TRUE if this function is a const. */
 };
 
 /**
@@ -219,15 +232,27 @@ typedef struct _Eobj_Op_Func_Description Eobj_Op_Func_Description;
  * @def EOBJ_OP_FUNC(op, func)
  * A convenience macro to be used when populating the #Eobj_Op_Func_Description
  * array.
+ *
+ * @see EOBJ_OP_FUNC_CONST
+ */
+#define EOBJ_OP_FUNC(op, func) { op, EOBJ_TYPECHECK(eobj_op_func_type, func), EINA_FALSE }
+
+/**
+ * @def EOBJ_OP_FUNC_CONST(op, func)
+ * A convenience macro to be used when populating the #Eobj_Op_Func_Description
+ * array.
+ * The same as #EOBJ_OP_FUNC but for const functions.
+ *
+ * @see EOBJ_OP_FUNC
  */
-#define EOBJ_OP_FUNC(op, func) { op, func }
+#define EOBJ_OP_FUNC_CONST(op, func) { op, (eobj_op_func_type) EOBJ_TYPECHECK(eobj_op_func_type_const, func), EINA_TRUE }
 
 /**
  * @def EOBJ_OP_FUNC_SENTINEL
  * A convenience macro to be used when populating the #Eobj_Op_Func_Description
  * array. It must appear at the end of the ARRAY.
  */
-#define EOBJ_OP_FUNC_SENTINEL { 0, NULL }
+#define EOBJ_OP_FUNC_SENTINEL { 0, NULL, EINA_FALSE }
 
 /**
  * @struct _Eobj_Op_Description
@@ -239,6 +264,7 @@ struct _Eobj_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; /**< #EINA_TRUE if this op's implementation should not change the obj. */
 };
 
 /**
@@ -292,9 +318,25 @@ typedef struct _Eobj_Class_Description Eobj_Class_Description;
  * @param type The type string for the op.
  * @param doc Additional doc for the op.
  * @see Eobj_Op_Description
+ * @see EOBJ_OP_DESCRIPTION_CONST
  * @see EOBJ_OP_DESCRIPTION_SENTINEL
  */
-#define EOBJ_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc }
+#define EOBJ_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_FALSE }
+
+/**
+ * @def EOBJ_OP_DESCRIPTION_CONST(op, type, doc)
+ * An helper macro to help populating #Eobj_Op_Description
+ * This macro is the same as EOBJ_OP_DESCRIPTION but indicates that the op's
+ * implementation should not change the object.
+ * @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 Eobj_Op_Description
+ * @see EOBJ_OP_DESCRIPTION
+ * @see EOBJ_OP_DESCRIPTION_SENTINEL
+ */
+#define EOBJ_OP_DESCRIPTION_CONST(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_TRUE }
+
 /**
  * @def EOBJ_OP_DESCRIPTION_SENTINEL
  * An helper macro to help populating #Eobj_Op_Description
@@ -302,7 +344,7 @@ typedef struct _Eobj_Class_Description Eobj_Class_Description;
  * @see Eobj_Op_Description
  * @see EOBJ_OP_DESCRIPTION
  */
-#define EOBJ_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, NULL }
+#define EOBJ_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, NULL, EINA_FALSE }
 
 /**
  * @brief Create a new class.
@@ -361,11 +403,19 @@ EAPI Eina_Bool eobj_shutdown(void);
  * A convenience wrapper around eobj_do_internal()
  * @see eobj_do_internal
  */
-#define eobj_do(object, ...) eobj_do_internal(object, __VA_ARGS__, (Eobj_Op) 0)
+#define eobj_do(obj, ...) eobj_do_internal(obj, EINA_FALSE, __VA_ARGS__, EOBJ_NOOP)
+
+/**
+ * @def eobj_query
+ * Same as #eobj_do but only for const ops.
+ * @see eobj_do
+ */
+#define eobj_query(obj, ...) eobj_do_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_TRUE, __VA_ARGS__, EOBJ_NOOP)
 
 /**
  * @brief Issues ops on an object.
  * @param obj The object to work on
+ * @param constant #EINA_TRUE if this call is on a constant object.
  * @param ... NULL terminated list of OPs and parameters.
  * @return #EINA_TRUE on success.
  *
@@ -374,20 +424,53 @@ EAPI Eina_Bool eobj_shutdown(void);
  *
  * @see #eobj_do
  */
-EAPI Eina_Bool eobj_do_internal(Eobj *obj, ...);
+EAPI Eina_Bool eobj_do_internal(Eobj *obj, Eina_Bool constant, ...);
 
 /**
  * @brief Calls the super function for the specific op.
  * @param obj The object to work on
- * @param op The wanted op.
  * @param ... list of parameters.
  * @return #EINA_TRUE on success.
  *
+ * Unlike eobj_do() and eobj_query(), this function only accepts one op.
+ *
  * Use the helper macros, don't pass the parameters manually.
  *
+ * Same as eobj_do_super() just for const objects.
+ *
+ * @see #eobj_query
+ * @see eobj_do_super()
+ */
+#define eobj_query_super(obj, ...) eobj_do_super_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_TRUE, __VA_ARGS__)
+
+/**
+ * @brief Calls the super function for the specific op.
+ * @param obj The object to work on
+ * @param ... list of parameters.
+ * @return #EINA_TRUE on success.
+ *
+ * Unlike eobj_do() and eobj_query(), this function only accepts one op.
+ *
+ * @see #eobj_query
+ * @see eobj_query_super()
+ */
+#define eobj_do_super(obj, ...) eobj_do_super_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_FALSE, __VA_ARGS__)
+
+/**
+ * @brief Calls the super function for the specific op.
+ * @param obj The object to work on
+ * @param constant #EINA_TRUE if this call is on a constant object.
+ * @param op The wanted op.
+ * @param ... list of parameters.
+ * @return #EINA_TRUE on success.
+ *
+ * Don't use this function, use the wrapping macros instead.
+ *
  * @see #eobj_do
+ * @see #eobj_do_super
+ * @see #eobj_query_super
  */
-EAPI Eina_Bool eobj_do_super(Eobj *obj, Eobj_Op op, ...);
+EAPI Eina_Bool eobj_do_super_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, ...);
 
 /**
  * @brief Gets the class of the object.
index eb8f8d4..6580abb 100644 (file)
@@ -345,12 +345,21 @@ _eobj_kls_itr_reached_end(const Eobj *obj)
 }
 
 static Eina_Bool
-_eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list)
+_eobj_op_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, va_list *p_list)
 {
    const Eobj_Class *klass;
    Eina_Bool ret = EINA_FALSE;
    Eina_Bool _itr_init;
 
+   const Eobj_Op_Description *op_desc = _eobj_op_id_desc_get(op);
+
+   if (op_desc &&
+         ((constant == EINA_TRUE) && (op_desc->constant == EINA_FALSE)))
+     {
+        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;
+     }
+
    _itr_init = _eobj_kls_itr_init(obj, op);
    klass = _eobj_kls_itr_get(obj);
    while (klass)
@@ -373,7 +382,7 @@ _eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list)
         Eobj *emb_obj;
         EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
           {
-             if (_eobj_op_internal(emb_obj, op, p_list))
+             if (_eobj_op_internal(emb_obj, constant, op, p_list))
                {
                   ret = EINA_TRUE;
                   goto end;
@@ -388,7 +397,7 @@ end:
 }
 
 EAPI Eina_Bool
-eobj_do_internal(Eobj *obj, ...)
+eobj_do_internal(Eobj *obj, Eina_Bool constant, ...)
 {
    Eina_Bool ret = EINA_TRUE;
    Eobj_Op op = EOBJ_NOOP;
@@ -398,12 +407,12 @@ eobj_do_internal(Eobj *obj, ...)
 
    eobj_ref(obj);
 
-   va_start(p_list, obj);
+   va_start(p_list, constant);
 
    op = va_arg(p_list, Eobj_Op);
    while (op)
      {
-        if (!_eobj_op_internal(obj, op, &p_list))
+        if (!_eobj_op_internal(obj, constant, op, &p_list))
           {
              const Eobj_Class *op_klass = OP_CLASS_GET(op);
              const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
@@ -423,7 +432,7 @@ eobj_do_internal(Eobj *obj, ...)
 }
 
 EAPI Eina_Bool
-eobj_do_super(Eobj *obj, Eobj_Op op, ...)
+eobj_do_super_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, ...)
 {
    const Eobj_Class *obj_klass;
    Eina_Bool ret = EINA_TRUE;
@@ -439,7 +448,7 @@ eobj_do_super(Eobj *obj, Eobj_Op op, ...)
      }
 
    va_start(p_list, op);
-   if (!_eobj_op_internal(obj, op, &p_list))
+   if (!_eobj_op_internal(obj, constant, op, &p_list))
      {
         const Eobj_Class *op_klass = OP_CLASS_GET(op);
         const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL;
@@ -616,7 +625,16 @@ eobj_class_funcs_set(Eobj_Class *klass, const Eobj_Op_Func_Description *func_des
      {
         for ( ; itr->op != 0 ; itr++)
           {
-             dich_func_set(klass, itr->op, itr->func);
+             const Eobj_Op_Description *op_desc = _eobj_op_id_desc_get(itr->op);
+
+             if (EINA_LIKELY(!op_desc || (itr->constant == op_desc->constant)))
+               {
+                  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);
+               }
           }
      }
 }
index a48265c..abdf523 100644 (file)
@@ -67,9 +67,10 @@ _data_set(Eobj *obj, void *class_data, va_list *list)
 }
 
 static void
-_data_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
+_data_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list)
 {
-   Private_Data *pd = class_data;
+   /* We don't really change it... */
+   Private_Data *pd = (Private_Data *) class_data;
    const char *key = va_arg(*list, const char *);
    void **data = va_arg(*list, void **);
    Eobj_Generic_Data_Node *node;
@@ -145,7 +146,7 @@ _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
         EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_SET), _data_set),
-        EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_GET), _data_get),
+        EOBJ_OP_FUNC_CONST(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_GET), _data_get),
         EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_DEL), _data_del),
         EOBJ_OP_FUNC_SENTINEL
    };
@@ -155,7 +156,7 @@ _class_constructor(Eobj_Class *klass)
 
 static const Eobj_Op_Description op_desc[] = {
      EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_SET, "?", "Set data for key."),
-     EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_GET, "?", "Get data for key."),
+     EOBJ_OP_DESCRIPTION_CONST(EOBJ_BASE_SUB_ID_DATA_GET, "?", "Get data for key."),
      EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_DEL, "?", "Del key."),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
index 3b90760..aba52ff 100644 (file)
@@ -18,9 +18,9 @@ _a_set(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
 }
 
 static void
-_a_print(Eobj *obj EINA_UNUSED, void *class_data, va_list *list)
+_a_print(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list)
 {
-   Simple_Public_Data *pd = class_data;
+   const Simple_Public_Data *pd = class_data;
    (void) list;
    printf("Print %s %d\n", eobj_class_name_get(MY_CLASS), pd->a);
 }
@@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass)
 {
    const Eobj_Op_Func_Description func_desc[] = {
         EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
-        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print),
         EOBJ_OP_FUNC_SENTINEL
    };
 
@@ -39,7 +39,7 @@ _class_constructor(Eobj_Class *klass)
 
 static const Eobj_Op_Description op_desc[] = {
      EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"),
-     EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
+     EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"),
      EOBJ_OP_DESCRIPTION_SENTINEL
 };
 
index 5637905..b7bfbfd 100644 (file)
@@ -293,10 +293,70 @@ START_TEST(eobj_bad_interface)
 }
 END_TEST
 
+static int _const_ops_counter = 0;
+
+static void
+_const_ops_a_set(const Eobj *obj EINA_UNUSED, const void *class_data EINA_UNUSED, va_list *list)
+{
+   int a = va_arg(*list, int);
+   (void) a;
+   _const_ops_counter++;
+}
+
+static void
+_const_ops_a_print(Eobj *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+   _const_ops_counter++;
+}
+
+static void
+_const_ops_class_constructor(Eobj_Class *klass)
+{
+   const Eobj_Op_Func_Description func_desc[] = {
+        EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _const_ops_a_set),
+        EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _const_ops_a_print),
+        EOBJ_OP_FUNC_SENTINEL
+   };
+
+   eobj_class_funcs_set(klass, func_desc);
+}
+
+START_TEST(eobj_const_ops)
+{
+   eobj_init();
+
+   const Eobj_Class *klass;
+
+   static Eobj_Class_Description class_desc = {
+        "Simple",
+        EOBJ_CLASS_TYPE_REGULAR,
+        EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
+        NULL,
+        0,
+        NULL,
+        NULL,
+        _const_ops_class_constructor,
+        NULL
+   };
+
+   klass = eobj_class_new(&class_desc, SIMPLE_CLASS, NULL);
+   fail_if(!klass);
+
+   Eobj *obj = eobj_add(klass, NULL);
+   eobj_do(obj, SIMPLE_A_SET(7), SIMPLE_A_PRINT());
+   fail_if(_const_ops_counter != 0);
+
+   eobj_unref(obj);
+
+   eobj_shutdown();
+}
+END_TEST
+
 void eobj_test_class_errors(TCase *tc)
 {
    tcase_add_test(tc, eobj_incomplete_desc);
    tcase_add_test(tc, eobj_inherit_errors);
    tcase_add_test(tc, eobj_inconsistent_mro);
    tcase_add_test(tc, eobj_bad_interface);
+   tcase_add_test(tc, eobj_const_ops);
 }
index d3aed07..cf43e4c 100644 (file)
@@ -165,6 +165,12 @@ START_TEST(eobj_op_errors)
    fail_if(eobj_ref_get(obj) != 1);
 
    eobj_unref(obj);
+
+   obj = eobj_add(SIMPLE_CLASS, NULL);
+   fail_if(!eobj_do(obj, SIMPLE_A_PRINT()));
+   fail_if(!eobj_query(obj, SIMPLE_A_PRINT()));
+   fail_if(eobj_query(obj, SIMPLE_A_SET(1)));
+
    eobj_shutdown();
 }
 END_TEST