summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Hacohen <tom@stosb.com>2016-05-05 16:08:08 +0100
committerTom Hacohen <tom@stosb.com>2016-05-05 16:45:12 +0100
commit537b138a2328008c16cf54401dc442bd6c8d11c5 (patch)
tree525c571f79524bb6fac6dd32f84b12453b601c5d /src
parent9d5caf00b624b149b01fc689f3e16c2ff3469335 (diff)
Eo composite: change composite objects to not be tied to parent
This commit breaks behaviour! Re-parenting no longer detaches composite objects, so watch out. Now you can have an object be a composite object of an object although it's not its child. This allows widgets to do things like having an object as the child of a child object while still making it a composite object to the main object. With this change, composite objects don't keep a reference to the child, but instead composite "bonds" are implicitly removed when either the parent or the child are destructed.
Diffstat (limited to 'src')
-rw-r--r--src/lib/eo/eo_base_class.c62
-rw-r--r--src/lib/eo/eo_private.h1
-rw-r--r--src/tests/eo/suite/eo_test_general.c18
3 files changed, 59 insertions, 22 deletions
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index 1cbb644e37..f8f1814cca 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -19,6 +19,7 @@ typedef struct
19{ 19{
20 const char *id; 20 const char *id;
21 const char *comment; 21 const char *comment;
22 Eo *composite_parent;
22 Eina_Inlist *generic_data; 23 Eina_Inlist *generic_data;
23 Eo ***wrefs; 24 Eo ***wrefs;
24} Eo_Base_Extension; 25} Eo_Base_Extension;
@@ -82,7 +83,7 @@ _eo_base_extension_noneed(Eo_Base_Data *pd)
82{ 83{
83 Eo_Base_Extension *ext = pd->ext; 84 Eo_Base_Extension *ext = pd->ext;
84 if ((!ext) || (ext->id) || (ext->comment) || (ext->generic_data) || 85 if ((!ext) || (ext->id) || (ext->comment) || (ext->generic_data) ||
85 (ext->wrefs)) return; 86 (ext->wrefs) || (ext->composite_parent)) return;
86 _eo_base_extension_free(pd->ext); 87 _eo_base_extension_free(pd->ext);
87 pd->ext = NULL; 88 pd->ext = NULL;
88} 89}
@@ -478,11 +479,6 @@ _eo_base_parent_set(Eo *obj, Eo_Base_Data *pd, Eo *parent_id)
478 if (pd->parent == parent_id) 479 if (pd->parent == parent_id)
479 return; 480 return;
480 481
481 if (eo_composite_part_is(obj) && pd->parent)
482 {
483 eo_composite_detach(pd->parent, obj);
484 }
485
486 if (pd->parent) 482 if (pd->parent)
487 { 483 {
488 Eo_Base_Data *old_parent_pd; 484 Eo_Base_Data *old_parent_pd;
@@ -1236,23 +1232,34 @@ _eo_base_composite_attach(Eo *parent_id, Eo_Base_Data *pd EINA_UNUSED, Eo *comp_
1236 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE); 1232 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
1237 EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE); 1233 EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
1238 1234
1239 if (!eo_isa(parent_id, _eo_class_id_get(comp_obj->klass))) return EINA_FALSE; 1235 if (!eo_isa(parent_id, _eo_class_id_get(comp_obj->klass)))
1236 {
1237 return EINA_FALSE;
1238 }
1240 1239
1240 Eo_Base_Data *comp_pd = eo_data_scope_get(comp_obj_id, EO_BASE_CLASS);
1241 /* Don't composite if we already have a composite object of this type */
1241 { 1242 {
1242 Eina_List *itr; 1243 Eina_List *itr;
1243 Eo *emb_obj_id; 1244 Eo *emb_obj_id;
1244 EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id) 1245 EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id)
1245 { 1246 {
1246 EO_OBJ_POINTER_RETURN_VAL(emb_obj_id, emb_obj, EINA_FALSE); 1247 EO_OBJ_POINTER_RETURN_VAL(emb_obj_id, emb_obj, EINA_FALSE);
1247 if(emb_obj->klass == comp_obj->klass) 1248 if (emb_obj->klass == comp_obj->klass)
1248 return EINA_FALSE; 1249 return EINA_FALSE;
1249 } 1250 }
1250 } 1251 }
1251 1252
1252 comp_obj->composite = EINA_TRUE; 1253 if (eo_composite_part_is(comp_obj_id))
1253 parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id); 1254 {
1255 eo_composite_detach(comp_pd->ext->composite_parent, comp_obj_id);
1256 }
1257
1258 /* Set the parent comp on the child. */
1259 _eo_base_extension_need(comp_pd);
1260 comp_pd->ext->composite_parent = parent_id;
1254 1261
1255 eo_parent_set(comp_obj_id, parent_id); 1262 parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id);
1256 1263
1257 return EINA_TRUE; 1264 return EINA_TRUE;
1258} 1265}
@@ -1263,22 +1270,25 @@ _eo_base_composite_detach(Eo *parent_id, Eo_Base_Data *pd EINA_UNUSED, Eo *comp_
1263 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE); 1270 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
1264 EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE); 1271 EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
1265 1272
1266 if (!comp_obj->composite) 1273 if (!eo_composite_part_is(comp_obj_id))
1267 return EINA_FALSE; 1274 return EINA_FALSE;
1268 1275
1269 comp_obj->composite = EINA_FALSE;
1270 parent->composite_objects = eina_list_remove(parent->composite_objects, comp_obj_id); 1276 parent->composite_objects = eina_list_remove(parent->composite_objects, comp_obj_id);
1271 eo_parent_set(comp_obj_id, NULL); 1277 /* Clear the comp parent on the child. */
1278 {
1279 Eo_Base_Data *comp_pd = eo_data_scope_get(comp_obj_id, EO_BASE_CLASS);
1280 comp_pd->ext->composite_parent = NULL;
1281
1282 _eo_base_extension_noneed(comp_pd);
1283 }
1272 1284
1273 return EINA_TRUE; 1285 return EINA_TRUE;
1274} 1286}
1275 1287
1276EOLIAN static Eina_Bool 1288EOLIAN static Eina_Bool
1277_eo_base_composite_part_is(Eo *comp_obj_id, Eo_Base_Data *pd EINA_UNUSED) 1289_eo_base_composite_part_is(Eo *comp_obj_id EINA_UNUSED, Eo_Base_Data *pd)
1278{ 1290{
1279 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE); 1291 return pd->ext && pd->ext->composite_parent;
1280
1281 return comp_obj->composite;
1282} 1292}
1283 1293
1284/* Eo_Dbg */ 1294/* Eo_Dbg */
@@ -1408,6 +1418,22 @@ _eo_base_destructor(Eo *obj, Eo_Base_Data *pd)
1408 eo_parent_set(child, NULL); 1418 eo_parent_set(child, NULL);
1409 } 1419 }
1410 1420
1421 /* If we are a composite object, detach children */
1422 {
1423 EO_OBJ_POINTER_RETURN(obj, obj_data);
1424 Eina_List *itr;
1425 Eo *emb_obj_id;
1426 EINA_LIST_FOREACH(obj_data->composite_objects, itr, emb_obj_id)
1427 {
1428 eo_composite_detach(obj, emb_obj_id);
1429 }
1430 }
1431
1432 if (pd->ext && pd->ext->composite_parent)
1433 {
1434 eo_composite_detach(pd->ext->composite_parent, obj);
1435 }
1436
1411 if (pd->parent) 1437 if (pd->parent)
1412 { 1438 {
1413 ERR("Object '%p' still has a parent at the time of destruction.", obj); 1439 ERR("Object '%p' still has a parent at the time of destruction.", obj);
diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h
index 323fc02117..4f60740822 100644
--- a/src/lib/eo/eo_private.h
+++ b/src/lib/eo/eo_private.h
@@ -103,7 +103,6 @@ struct _Eo_Object
103 Eina_Bool condtor_done:1; 103 Eina_Bool condtor_done:1;
104 Eina_Bool finalized:1; 104 Eina_Bool finalized:1;
105 105
106 Eina_Bool composite:1;
107 Eina_Bool del_triggered:1; 106 Eina_Bool del_triggered:1;
108 Eina_Bool destructed:1; 107 Eina_Bool destructed:1;
109 Eina_Bool manual_free:1; 108 Eina_Bool manual_free:1;
diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c
index 51b1ac4553..65788647b0 100644
--- a/src/tests/eo/suite/eo_test_general.c
+++ b/src/tests/eo/suite/eo_test_general.c
@@ -299,12 +299,24 @@ START_TEST(eo_composite_tests)
299 fail_if(!obj); 299 fail_if(!obj);
300 Eo *obj2 = eo_add(SIMPLE_CLASS, NULL); 300 Eo *obj2 = eo_add(SIMPLE_CLASS, NULL);
301 fail_if(!obj2); 301 fail_if(!obj2);
302 Eo *obj3 = eo_add(SIMPLE_CLASS, NULL);
303 fail_if(!obj3);
302 304
303 eo_composite_attach(obj, obj2); 305 eo_composite_attach(obj, obj2);
304 eo_parent_set(obj2, NULL); 306 fail_if(!eo_composite_part_is(obj2));
305 fail_if(eo_composite_part_is(obj2)); 307
308 /* Check swapping attachments works. */
309 eo_composite_attach(obj3, obj2);
310 fail_if(!eo_composite_part_is(obj2));
311
312 /* Check that a deletion of a child detaches from the parent. */
313 eo_del(obj2);
314 fail_if(!eo_composite_attach(obj3, obj));
315
316 /* Check that a deletion of the parent detaches the child. */
317 eo_del(obj3);
318 fail_if(eo_composite_part_is(obj));
306 319
307 eo_unref(obj2);
308 eo_unref(obj); 320 eo_unref(obj);
309 321
310 eo_shutdown(); 322 eo_shutdown();