Eo: Added eo_add_custom and support for passing ops to eo_add.
authortasn <tasn>
Thu, 23 Aug 2012 10:35:14 +0000 (10:35 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 23 Aug 2012 10:35:14 +0000 (10:35 +0000)
We can no do things like eo_add(CLASS, parent, age_set(7), score_set(100)),
or pass different constructors to object creation by using eo_add_custom and
passing the constructor.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@75614 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/Eo.h
src/lib/eo.c
src/tests/eo_suite/eo_test_general.c

index f9de616..b6e10f3 100644 (file)
@@ -553,12 +553,46 @@ EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line);
 /* @endcond */
 
 /**
+ * @def eo_add
+ * @brief Create a new object with the default constructor.
+ * @param klass the class of the object to create.
+ * @param parent the parent to set to the object.
+ * @param ... The ops to run.
+ * @return An handle to the new object on success, NULL otherwise.
+ */
+#define eo_add(klass, parent, ...) \
+   ({ \
+    (void) klass; \
+    eo_add_internal(klass, parent, eo_constructor(), ## __VA_ARGS__, EO_NOOP); \
+    })
+
+/**
+ * @def eo_add_custom
+ * @brief Create a new object with a custom constructor.
+ * @param klass the class of the object to create.
+ * @param parent the parent to set to the object.
+ * @param ... The ops to run. With the constructor being first.
+ * @return An handle to the new object on success, NULL otherwise.
+ */
+#define eo_add_custom(klass, parent, ...) \
+   ({ \
+    (void) klass; \
+    eo_add_internal(klass, parent, ## __VA_ARGS__, EO_NOOP); \
+    })
+
+/**
  * @brief Create a new object.
  * @param klass the class of the object to create.
  * @param parent the parent to set to the object.
+ * @param ... The ops to run. With the constructor being first.
  * @return An handle to the new object on success, NULL otherwise.
+ *
+ * Use the helper macros, don't pass the parameters manually.
+ * Use #eo_add or #eo_add_custom instead of this function.
+ *
+ * @see #eo_add
  */
-EAPI Eo *eo_add(const Eo_Class *klass, Eo *parent);
+EAPI Eo *eo_add_internal(const Eo_Class *klass, Eo *parent, ...);
 
 /**
  * @brief Get the parent of an object
index 7d8f07f..4d2a2f2 100644 (file)
@@ -378,22 +378,19 @@ _eo_op_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
    return EINA_FALSE;
 }
 
-EAPI Eina_Bool
-eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
+static inline Eina_Bool
+_eo_dov_internal(Eo *obj, Eo_Op_Type op_type, va_list p_list)
 {
    Eina_Bool prev_error;
    Eina_Bool ret = EINA_TRUE;
    Eo_Op op = EO_NOOP;
    Eo_Kls_Itr prev_state;
-   va_list p_list;
 
    EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE);
 
    prev_error = obj->do_error;
    _eo_ref(obj);
 
-   va_start(p_list, op_type);
-
    op = va_arg(p_list, Eo_Op);
    while (op)
      {
@@ -409,8 +406,6 @@ eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
         _eo_kls_itr_end(&obj->mro_itr, &prev_state);
      }
 
-   va_end(p_list);
-
    _eo_unref(obj);
 
    if (obj->do_error)
@@ -422,6 +417,21 @@ eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
 }
 
 EAPI Eina_Bool
+eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
+{
+   Eina_Bool ret = EINA_TRUE;
+   va_list p_list;
+
+   va_start(p_list, op_type);
+
+   ret = _eo_dov_internal(obj, op_type, p_list);
+
+   va_end(p_list);
+
+   return ret;
+}
+
+EAPI Eina_Bool
 eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...)
 {
    const Eo_Class *nklass;
@@ -1095,7 +1105,7 @@ eo_parent_set(Eo *obj, const Eo *parent)
 }
 
 EAPI Eo *
-eo_add(const Eo_Class *klass, Eo *parent)
+eo_add_internal(const Eo_Class *klass, Eo *parent, ...)
 {
    Eina_Bool do_err;
    EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, NULL);
@@ -1120,7 +1130,14 @@ eo_add(const Eo_Class *klass, Eo *parent)
    _eo_condtor_reset(obj);
 
    _eo_ref(obj);
-   do_err = !eo_do(obj, eo_constructor());
+
+   /* Run the relevant do stuff. */
+     {
+        va_list p_list;
+        va_start(p_list, parent);
+        do_err = !_eo_dov_internal(obj, EO_OP_TYPE_REGULAR, p_list);
+        va_end(p_list);
+     }
 
    if (EINA_UNLIKELY(do_err))
      {
@@ -1133,6 +1150,7 @@ eo_add(const Eo_Class *klass, Eo *parent)
         ERR("Object of class '%s' - Not all of the object constructors have been executed.", klass->desc->name);
         goto fail;
      }
+
    _eo_unref(obj);
 
    return obj;
index ac395d2..20ab4b5 100644 (file)
@@ -695,6 +695,32 @@ START_TEST(eo_multiple_do)
 }
 END_TEST
 
+START_TEST(eo_add_do_and_custom)
+{
+   Simple_Public_Data *pd = NULL;
+   Eo *obj = NULL;
+   eo_init();
+
+   obj = eo_add_custom(SIMPLE_CLASS, NULL, eo_constructor());
+   fail_if(!obj);
+   eo_unref(obj);
+
+   obj = eo_add(SIMPLE_CLASS, NULL, simple_a_set(7));
+   fail_if(!obj);
+   pd = eo_data_get(obj, SIMPLE_CLASS);
+   fail_if(pd->a != 7);
+   eo_unref(obj);
+
+   obj = eo_add_custom(SIMPLE_CLASS, NULL, eo_constructor(), simple_a_set(7));
+   fail_if(!obj);
+   pd = eo_data_get(obj, SIMPLE_CLASS);
+   fail_if(pd->a != 7);
+   eo_unref(obj);
+
+   eo_shutdown();
+}
+END_TEST
+
 void eo_test_general(TCase *tc)
 {
    tcase_add_test(tc, eo_generic_data);
@@ -708,4 +734,5 @@ void eo_test_general(TCase *tc)
    tcase_add_test(tc, eo_composite_tests);
    tcase_add_test(tc, eo_isa_tests);
    tcase_add_test(tc, eo_multiple_do);
+   tcase_add_test(tc, eo_add_do_and_custom);
 }