summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-04-19 18:25:15 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-04-19 18:36:57 +0900
commit45456d9e82ddc0e514a2b0003cbffa259e9eb9b1 (patch)
treedd56384fb1b342e08ee84e6b076bdcec36df8c07
parent1b266ff1e45f965ddab03a1179084810632305e1 (diff)
downloadefl-45456d9e82ddc0e514a2b0003cbffa259e9eb9b1.tar.gz
eo base - add value keys in addition to object and void ptr data keys
eina value would allow any value to be attached to an eo object and also be freed nicely too. this would allow any generic data to go there without overloading a void * that us c coders love to abuse. @feature
-rw-r--r--src/lib/eo/eo_base.eo28
-rw-r--r--src/lib/eo/eo_base_class.c103
-rw-r--r--src/tests/eo/suite/eo_test_general.c15
3 files changed, 142 insertions, 4 deletions
diff --git a/src/lib/eo/eo_base.eo b/src/lib/eo/eo_base.eo
index 0cd1354afe..51385f1599 100644
--- a/src/lib/eo/eo_base.eo
+++ b/src/lib/eo/eo_base.eo
@@ -223,6 +223,34 @@ abstract Eo.Base ()
@in key: const(char)*; [[the key associated with the object ref]]
}
}
+ key_value_set {
+ [[Set value on the object.
+
+ This stores the value with the given string key on the object
+ and it will be freed when replaced or deleted or the referring
+ object is deleted.
+
+ This is the same key store used by key_data_set and key_obj_set
+ etc. so keys are shared and can store only one thing
+ ]]
+ params {
+ @in key: const(char)*; [[the key associated with the value]]
+ @in value: Eina_Value *; [[the value to set]]
+ }
+ }
+ key_value_get @const {
+ [[Get generic value from object.]]
+ params {
+ @in key: const(char)*; [[the key associated with the value]]
+ }
+ return: Eina_Value *; [[the value for the key]]
+ }
+ key_value_del {
+ [[Del generic value from object.]]
+ params {
+ @in key: const(char)*; [[the key associated with the value]]
+ }
+ }
event_thaw {
[[thaw events of object.
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index 4c5fe71a48..2420568ead 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -42,6 +42,7 @@ typedef struct
Eina_Stringshare *key;
void *data;
Eina_Bool data_is_obj : 1;
+ Eina_Bool data_is_value : 1;
} Eo_Generic_Data_Node;
@@ -110,6 +111,7 @@ _eo_generic_data_del_all(Eo *obj, Eo_Base_Data *pd)
_eo_base_cb_key_obj_del, obj);
eo_unref(node->data);
}
+ else if (node->data_is_value) eina_value_free(node->data);
_eo_generic_data_node_free(node);
}
}
@@ -124,7 +126,8 @@ _eo_base_key_data_set(Eo *obj, Eo_Base_Data *pd, const char *key, const void *da
{
if (!strcmp(node->key, key))
{
- if ((!node->data_is_obj) && (node->data == data)) return;
+ if ((!node->data_is_obj) && (!node->data_is_value) &&
+ (node->data == data)) return;
pd->generic_data = eina_inlist_remove(pd->generic_data,
EINA_INLIST_GET(node));
if (node->data_is_obj)
@@ -133,6 +136,7 @@ _eo_base_key_data_set(Eo *obj, Eo_Base_Data *pd, const char *key, const void *da
_eo_base_cb_key_obj_del, obj);
eo_unref(node->data);
}
+ else if (node->data_is_value) eina_value_free(node->data);
_eo_generic_data_node_free(node);
break;
}
@@ -157,7 +161,7 @@ _eo_base_key_data_get(const Eo *obj, Eo_Base_Data *pd, const char *key)
{
if (!strcmp(node->key, key))
{
- if (!node->data_is_obj)
+ if ((!node->data_is_obj) && (!node->data_is_value))
{
pd->generic_data = eina_inlist_promote(pd->generic_data,
EINA_INLIST_GET(node));
@@ -165,7 +169,7 @@ _eo_base_key_data_get(const Eo *obj, Eo_Base_Data *pd, const char *key)
}
else
{
- ERR("Object %p key '%s' is an object, not raw data",
+ ERR("Object %p key '%s' wants raw data but is not raw data",
obj, key);
return NULL;
}
@@ -192,6 +196,7 @@ _eo_base_key_data_del(Eo *obj, Eo_Base_Data *pd, const char *key)
_eo_base_cb_key_obj_del, obj);
eo_unref(node->data);
}
+ else if (node->data_is_value) eina_value_free(node->data);
_eo_generic_data_node_free(node);
return;
}
@@ -217,6 +222,7 @@ _eo_base_key_obj_set(Eo *obj, Eo_Base_Data *pd, const char *key, Eo *objdata)
_eo_base_cb_key_obj_del, obj);
eo_unref(node->data);
}
+ else if (node->data_is_value) eina_value_free(node->data);
_eo_generic_data_node_free(node);
break;
}
@@ -252,7 +258,7 @@ _eo_base_key_obj_get(const Eo *obj, Eo_Base_Data *pd, const char *key)
}
else
{
- ERR("Object %p key '%s' is an object, not an object",
+ ERR("Object %p key '%s' asked for object but is not an object",
obj, key);
return NULL;
}
@@ -279,6 +285,95 @@ _eo_base_key_obj_del(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key)
_eo_base_cb_key_obj_del, obj);
eo_unref(node->data);
}
+ else if (node->data_is_value) eina_value_free(node->data);
+ _eo_generic_data_node_free(node);
+ return;
+ }
+ }
+}
+
+EOLIAN static void
+_eo_base_key_value_set(Eo *obj, Eo_Base_Data *pd, const char *key, Eina_Value *value)
+{
+ Eo_Generic_Data_Node *node;
+
+ if (!key) return;
+ EINA_INLIST_FOREACH(pd->generic_data, node)
+ {
+ if (!strcmp(node->key, key))
+ {
+ if ((node->data_is_value) && (node->data == value)) return;
+ pd->generic_data = eina_inlist_remove(pd->generic_data,
+ EINA_INLIST_GET(node));
+ if (node->data_is_obj)
+ {
+ eo_event_callback_del(node->data, EO_BASE_EVENT_DEL,
+ _eo_base_cb_key_obj_del, obj);
+ eo_unref(node->data);
+ }
+ else if (node->data_is_value) eina_value_free(node->data);
+ _eo_generic_data_node_free(node);
+ break;
+ }
+ }
+
+ node = calloc(1, sizeof(Eo_Generic_Data_Node));
+ if (!node) return;
+ node->key = eina_stringshare_add(key);
+ node->data = (void *)value;
+ node->data_is_value = EINA_TRUE;
+ eo_event_callback_add(node->data, EO_BASE_EVENT_DEL,
+ _eo_base_cb_key_obj_del, obj);
+ pd->generic_data = eina_inlist_prepend(pd->generic_data,
+ EINA_INLIST_GET(node));
+}
+
+EOLIAN static Eina_Value *
+_eo_base_key_value_get(const Eo *obj, Eo_Base_Data *pd, const char *key)
+{
+ Eo_Generic_Data_Node *node;
+
+ if (!key) return NULL;
+ EINA_INLIST_FOREACH(pd->generic_data, node)
+ {
+ if (!strcmp(node->key, key))
+ {
+ if (node->data_is_value)
+ {
+ pd->generic_data = eina_inlist_promote(pd->generic_data,
+ EINA_INLIST_GET(node));
+ return node->data;
+ }
+ else
+ {
+ ERR("Object %p key '%s' asked for value but is not a value",
+ obj, key);
+ return NULL;
+ }
+ }
+ }
+ return NULL;
+}
+
+EOLIAN static void
+_eo_base_key_value_del(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key)
+{
+ Eo_Generic_Data_Node *node;
+
+ if (!key) return;
+ EINA_INLIST_FOREACH(pd->generic_data, node)
+ {
+ if (!strcmp(node->key, key))
+ {
+ pd->generic_data = eina_inlist_remove(pd->generic_data,
+ EINA_INLIST_GET(node));
+ if (node->data_is_obj)
+ {
+ eo_event_callback_del(node->data, EO_BASE_EVENT_DEL,
+ _eo_base_cb_key_obj_del, obj);
+ eo_unref(node->data);
+ }
+ else if (node->data_is_value) eina_value_free(node->data);
_eo_generic_data_node_free(node);
return;
}
diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c
index 9b19210d8c..c1ca0d8bac 100644
--- a/src/tests/eo/suite/eo_test_general.c
+++ b/src/tests/eo/suite/eo_test_general.c
@@ -602,6 +602,8 @@ START_TEST(eo_generic_data)
Eo *obj3 = eo_add(SIMPLE_CLASS, NULL);
Eo *objtmp;
void *data = NULL;
+ Eina_Value *value;
+ Eina_Value *value2;
eo_key_data_set(obj, "test1", (void *) 1);
data = eo_key_data_get(obj, "test1");
@@ -657,6 +659,19 @@ START_TEST(eo_generic_data)
objtmp = eo_key_obj_get(obj, "test1");
fail_if(objtmp);
+ value = eina_value_new(EINA_VALUE_TYPE_INT);
+ eina_value_set(value, 1234);
+ value2 = eo_key_value_get(obj, "value1");
+ fail_if(value2 != NULL);
+
+ eo_key_value_set(obj, "value1", value);
+ value2 = eo_key_value_get(obj, "value1");
+ fail_if(value != value2);
+
+ eo_key_value_del(obj, "value1");
+ value2 = eo_key_value_get(obj, "value1");
+ fail_if(value2 != NULL);
+
eo_unref(obj);
eo_unref(obj2);
eo_unref(obj3);