eo: eo_composite_attach check composite class, disallow duplicates
authorJérémy Zurcher <jeremy@asynk.ch>
Tue, 18 Feb 2014 14:33:24 +0000 (15:33 +0100)
committerJérémy Zurcher <jeremy@asynk.ch>
Wed, 26 Feb 2014 15:25:00 +0000 (16:25 +0100)
eo_composite_attach fail if the class of the composite is not
listed in the parent class extensions, or if there is already a
composite of the same class. The later because calls are
forwarded to the first responding composite, see _eo_op_internal().

src/lib/eo/Eo.h
src/lib/eo/eo.c
src/tests/eo/composite_objects/composite_objects_main.c

index 9ae740ca1f0d9206c1c5cf14d5d9afa6dd1fab96..06a8ca179b15da4728dbb3e61feb36ef7dc0d754 100644 (file)
@@ -936,13 +936,16 @@ EAPI Eina_Bool eo_destructed_is(const Eo *obj);
  * @brief Make an object a composite object of another.
  * @param comp_obj the object that will be used to composite parent.
  * @param parent the "parent" object.
+ * @return EINA_TRUE if successfull. EINA_FALSE otherwise.
  *
+ * The class of comp_obj must be part of the extensions of the class of the parent.
+ * It is not possible to attach more then 1 composite of the same class.
  * This functions also sets the parent of comp_obj to parent.
  *
  * @see eo_composite_detach()
  * @see eo_composite_is()
  */
-EAPI void eo_composite_attach(Eo *comp_obj, Eo *parent);
+EAPI Eina_Bool eo_composite_attach(Eo *comp_obj, Eo *parent);
 
 /**
  * @brief Detach a composite object from another object.
index fc644642d77d778a92a5c412a250e34827b79f73..bfee7ebb917d7d8ea559279683d8cd9b5d1537ad 100644 (file)
@@ -1485,16 +1485,31 @@ eo_shutdown(void)
    return EINA_TRUE;
 }
 
-EAPI void
+EAPI Eina_Bool
 eo_composite_attach(Eo *comp_obj_id, Eo *parent_id)
 {
-   EO_OBJ_POINTER_RETURN(comp_obj_id, comp_obj);
-   EO_OBJ_POINTER_RETURN(parent_id, parent);
+   EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
+   EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
+
+   if (!eo_isa(parent_id, _eo_class_id_get(comp_obj->klass))) return EINA_FALSE;
+
+     {
+        Eina_List *itr;
+        Eo *emb_obj_id;
+        EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id)
+          {
+             EO_OBJ_POINTER_RETURN_VAL(emb_obj_id, emb_obj, EINA_FALSE);
+             if(emb_obj->klass == comp_obj->klass)
+               return EINA_FALSE;
+          }
+     }
 
    comp_obj->composite = EINA_TRUE;
    parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id);
 
    eo_do(comp_obj_id, eo_parent_set(parent_id));
+
+   return EINA_TRUE;
 }
 
 EAPI void
index 2e5d9ab005a6714f860510d573c17eeef81d26f1..1d5b8c047483234e67658957190cfac6cacd3446 100644 (file)
@@ -33,6 +33,9 @@ main(int argc, char *argv[])
    Eo *obj = eo_add(COMP_CLASS, NULL);
    eo_do(obj, eo_event_callback_add(EV_A_CHANGED, _a_changed_cb, NULL));
 
+   fail_if(!eo_isa(obj, COMP_CLASS));
+   fail_if(!eo_isa(obj, SIMPLE_CLASS));
+
    int a;
    eo_do(obj, simple_a_set(1));
    fail_if(!cb_called);
@@ -53,8 +56,11 @@ main(int argc, char *argv[])
    fail_if(!eo_composite_is(simple));
    eo_composite_detach(simple, obj);
    fail_if(eo_composite_is(simple));
-   eo_composite_attach(simple, obj);
+   fail_if(!eo_composite_attach(simple, obj));
    fail_if(!eo_composite_is(simple));
+   fail_if(eo_composite_attach(simple, obj));
+
+   fail_if(eo_composite_attach(obj, simple));
 
    eo_unref(simple);
    eo_unref(obj);