raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=45456d9e82ddc0e514a2b0003cbffa259e9eb9b1

commit 45456d9e82ddc0e514a2b0003cbffa259e9eb9b1
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Tue Apr 19 18:25:15 2016 +0900

    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
---
 src/lib/eo/eo_base.eo                |  28 ++++++++++
 src/lib/eo/eo_base_class.c           | 103 +++++++++++++++++++++++++++++++++--
 src/tests/eo/suite/eo_test_general.c |  15 +++++
 3 files changed, 142 insertions(+), 4 deletions(-)

diff --git a/src/lib/eo/eo_base.eo b/src/lib/eo/eo_base.eo
index 0cd1354..51385f1 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 4c5fe71..2420568 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 9b19210..c1ca0d8 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);

-- 


Reply via email to