}
}
}
+ @property key_obj_weak {
+ [[Generic weak object reference with string key to object.
+
+ The object key will be removed if the object is removed, but
+ will not take or removed references like key_obj.
+
+ This is the same key store used by key_data and key_value so keys
+ are shared and can store only one thing
+ ]]
+ keys {
+ key: string; [[the key associated with the object ref]]
+ }
+ set {
+ values {
+ objdata: const(Eo.Base); [[the object to set]]
+ }
+ }
+ get {
+ values {
+ objdata: Eo.Base; [[the object to set]]
+ }
+ }
+ }
@property key_value {
[[Value on with string key on the object.
typedef enum {
DATA_PTR,
DATA_OBJ,
+ DATA_OBJ_WEAK,
DATA_VAL
} Eo_Generic_Data_Node_Type;
typedef struct
{
EINA_INLIST;
+ const Eo *obj;
Eina_Stringshare *key;
union {
- Eina_Value *val;
- Eo *obj;
- void *ptr;
+ Eina_Value *val;
+ Eo *obj;
+ void *ptr;
} d;
Eo_Generic_Data_Node_Type d_type;
} Eo_Generic_Data_Node;
pd->ext = NULL;
}
-
-
+static void _key_generic_cb_del(void *data, const Eo_Event *event);
static void
_eo_generic_data_node_free(Eo_Generic_Data_Node *node)
{
switch (node->d_type)
{
+ case DATA_PTR:
+ break;
case DATA_OBJ:
- eo_unref(node->d.obj);
- break;
+ eo_event_callback_del(node->d.obj, EO_EVENT_DEL, _key_generic_cb_del, node);
+ eo_unref(node->d.obj);
+ break;
+ case DATA_OBJ_WEAK:
+ eo_event_callback_del(node->d.obj, EO_EVENT_DEL, _key_generic_cb_del, node);
+ break;
case DATA_VAL:
- eina_value_free(node->d.val);
- break;
- case DATA_PTR:
- break;
+ eina_value_free(node->d.val);
+ break;
}
eina_stringshare_del(node->key);
free(node);
}
static void
-_eo_key_generic_del(const Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key)
+_eo_key_generic_direct_del(Eo_Base_Data *pd, Eo_Generic_Data_Node *node, Eina_Bool call_free)
+{
+ Eo_Base_Extension *ext = pd->ext;
+
+ ext->generic_data = eina_inlist_remove
+ (ext->generic_data, EINA_INLIST_GET(node));
+ if (call_free) _eo_generic_data_node_free(node);
+}
+
+static void
+_eo_key_generic_del(const Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key, Eina_Bool call_free)
{
Eo_Generic_Data_Node *node;
Eo_Base_Extension *ext = pd->ext;
{
ext->generic_data = eina_inlist_remove
(ext->generic_data, EINA_INLIST_GET(node));
- _eo_generic_data_node_free(node);
+ if (call_free) _eo_generic_data_node_free(node);
return;
}
}
}
/* Return TRUE if the object was newly added. */
-static Eina_Bool
-_key_generic_set(const Eo *obj, Eo_Base_Data *pd, const char *key, const void *data, Eo_Generic_Data_Node_Type d_type)
+static Eo_Generic_Data_Node *
+_key_generic_set(const Eo *obj, Eo_Base_Data *pd, const char *key, const void *data, Eo_Generic_Data_Node_Type d_type, Eina_Bool call_free)
{
Eo_Generic_Data_Node *node;
Eo_Base_Extension *ext = pd->ext;
- if (!key) return EINA_FALSE;
+ if (!key) return NULL;
if (ext)
{
if (!data)
{
- _eo_key_generic_del(obj, pd, key);
- return EINA_TRUE;
+ _eo_key_generic_del(obj, pd, key, call_free);
+ return NULL;
}
EINA_INLIST_FOREACH(ext->generic_data, node)
{
{
node = calloc(1, sizeof(Eo_Generic_Data_Node));
if (!node) return EINA_FALSE;
+ node->obj = obj;
node->key = eina_stringshare_add(key);
node->d.ptr = (void *) data;
node->d_type = d_type;
ext->generic_data = eina_inlist_prepend
(ext->generic_data, EINA_INLIST_GET(node));
- return EINA_TRUE;
+ return node;
}
- return EINA_FALSE;
+ return NULL;
}
static void *
return NULL;
}
+static void
+_key_generic_cb_del(void *data, const Eo_Event *event EINA_UNUSED)
+{
+ Eo_Generic_Data_Node *node = data;
+ Eo_Base_Data *pd = eo_data_scope_get(node->obj, EO_BASE_CLASS);
+ _eo_key_generic_direct_del(pd, node, EINA_FALSE);
+}
+
EOLIAN static void
_eo_base_key_data_set(Eo *obj, Eo_Base_Data *pd, const char *key, const void *data)
{
- _key_generic_set(obj, pd, key, data, DATA_PTR);
+ _key_generic_set(obj, pd, key, data, DATA_PTR, EINA_TRUE);
}
EOLIAN static void *
EOLIAN static void
_eo_base_key_obj_set(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key, const Eo *objdata)
{
- if (_key_generic_set(obj, pd, key, objdata, DATA_OBJ))
- eo_ref(objdata);
+ Eo_Generic_Data_Node *node;
+
+ node = _key_generic_set(obj, pd, key, objdata, DATA_OBJ, EINA_TRUE);
+ if (node)
+ {
+ eo_ref(objdata);
+ eo_event_callback_add((Eo *)objdata, EO_EVENT_DEL, _key_generic_cb_del, node);
+ }
}
EOLIAN static Eo *
}
EOLIAN static void
+_eo_base_key_obj_weak_set(Eo *obj, Eo_Base_Data *pd, const char * key, const Eo_Base *objdata)
+{
+ Eo_Generic_Data_Node *node;
+
+ node = _key_generic_set(obj, pd, key, objdata, DATA_OBJ_WEAK, EINA_TRUE);
+ if (node)
+ {
+ eo_event_callback_add((Eo *)objdata, EO_EVENT_DEL, _key_generic_cb_del, node);
+ }
+}
+
+EOLIAN static Eo *
+_eo_base_key_obj_weak_get(Eo *obj, Eo_Base_Data *pd, const char * key)
+{
+ return _key_generic_get(obj, pd, key, DATA_OBJ_WEAK);
+}
+
+EOLIAN static void
_eo_base_key_value_set(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key, Eina_Value *value)
{
- _key_generic_set(obj, pd, key, value, DATA_VAL);
+ _key_generic_set(obj, pd, key, value, DATA_VAL, EINA_TRUE);
}
EOLIAN static Eina_Value *
Eina_Value *value;
Eina_Value *value2;
+
+
eo_key_data_set(obj, "test1", (void *) 1);
data = eo_key_data_get(obj, "test1");
fail_if(1 != (intptr_t) data);
+
eo_key_data_set(obj, "test1", NULL);
data = eo_key_data_get(obj, "test1");
fail_if(data);
eo_key_data_set(obj, "test2", (void *) 2);
data = eo_key_data_get(obj, "test1");
fail_if(1 != (intptr_t) data);
+
data = eo_key_data_get(obj, "test2");
fail_if(2 != (intptr_t) data);
data = eo_key_data_get(obj, "test2");
fail_if(2 != (intptr_t) data);
+
eo_key_data_set(obj, "test2", NULL);
data = eo_key_data_get(obj, "test2");
fail_if(data);
data = eo_key_data_get(obj, "test1");
fail_if(1 != (intptr_t) data);
+
eo_key_data_set(obj, "test1", NULL);
data = eo_key_data_get(obj, "test1");
fail_if(data);
eo_key_obj_set(obj, "test1", obj2);
objtmp = eo_key_obj_get(obj, "test1");
fail_if(obj2 != objtmp);
+
eo_key_obj_set(obj, "test1", NULL);
objtmp = eo_key_obj_get(obj, "test1");
fail_if(objtmp);
eo_key_obj_set(obj, "test1", obj2);
+ fail_if(eo_ref_get(obj2) != 2);
+
eo_key_obj_set(obj, "test2", obj3);
+ fail_if(eo_ref_get(obj3) != 2);
+
objtmp = eo_key_obj_get(obj, "test1");
fail_if(obj2 != objtmp);
+
objtmp = eo_key_obj_get(obj, "test2");
fail_if(obj3 != objtmp);
data = eo_key_obj_get(obj, "test2");
fail_if(obj3 != objtmp);
+
eo_key_obj_set(obj, "test2", NULL);
+ fail_if(eo_ref_get(obj3) != 1);
+
objtmp = eo_key_obj_get(obj, "test2");
fail_if(objtmp);
objtmp = eo_key_obj_get(obj, "test1");
fail_if(obj2 != objtmp);
+
eo_key_obj_set(obj, "test1", NULL);
+ fail_if(eo_ref_get(obj2) != 1);
+
objtmp = eo_key_obj_get(obj, "test1");
fail_if(objtmp);
+ eo_key_obj_set(obj, "test1", obj2);
+ eo_key_obj_set(obj, "test2", obj3);
+ eo_del(obj2);
+ eo_del(obj2);
+ eo_del(obj3);
+ eo_del(obj3);
+ objtmp = eo_key_obj_get(obj, "test1");
+ fail_if(objtmp);
+
+ objtmp = eo_key_obj_get(obj, "test2");
+ fail_if(objtmp);
+
+
+
+ obj2 = eo_add(SIMPLE_CLASS, NULL);
+ obj3 = eo_add(SIMPLE_CLASS, NULL);
+
+ eo_key_obj_weak_set(obj, "test1", obj2);
+ objtmp = eo_key_obj_weak_get(obj, "test1");
+ fail_if(obj2 != objtmp);
+
+ eo_key_obj_weak_set(obj, "test1", NULL);
+ objtmp = eo_key_obj_weak_get(obj, "test1");
+ fail_if(objtmp);
+
+ eo_key_obj_weak_set(obj, "test1", obj2);
+ fail_if(eo_ref_get(obj2) != 1);
+
+ eo_key_obj_weak_set(obj, "test2", obj3);
+ fail_if(eo_ref_get(obj3) != 1);
+
+ objtmp = eo_key_obj_weak_get(obj, "test1");
+ fail_if(obj2 != objtmp);
+
+ objtmp = eo_key_obj_weak_get(obj, "test2");
+ fail_if(obj3 != objtmp);
+
+ data = eo_key_obj_weak_get(obj, "test2");
+ fail_if(obj3 != objtmp);
+
+ eo_key_obj_weak_set(obj, "test2", NULL);
+ fail_if(eo_ref_get(obj3) != 1);
+
+ objtmp = eo_key_obj_weak_get(obj, "test2");
+ fail_if(objtmp);
+
+ objtmp = eo_key_obj_weak_get(obj, "test1");
+ fail_if(obj2 != objtmp);
+
+ eo_key_obj_weak_set(obj, "test1", NULL);
+ fail_if(eo_ref_get(obj2) != 1);
+
+ objtmp = eo_key_obj_weak_get(obj, "test1");
+ fail_if(objtmp);
+
+ eo_key_obj_weak_set(obj, "test1", obj2);
+ eo_key_obj_weak_set(obj, "test2", obj3);
+ eo_del(obj2);
+ eo_del(obj3);
+ objtmp = eo_key_obj_weak_get(obj, "test1");
+ fail_if(objtmp);
+
+ objtmp = eo_key_obj_weak_get(obj, "test2");
+ fail_if(objtmp);
+
+
+
value = eina_value_new(EINA_VALUE_TYPE_INT);
eina_value_set(value, 1234);
value2 = eo_key_value_get(obj, "value1");
eo_key_value_set(obj, "value1", NULL);
value2 = eo_key_value_get(obj, "value1");
fail_if(value2 != NULL);
+
eo_key_value_set(obj, "value1", NULL);
eo_unref(obj);