Evas filters: Add explicit exec flag in data_set
authorJean-Philippe Andre <jp.andre@samsung.com>
Tue, 23 Jun 2015 07:40:51 +0000 (16:40 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Thu, 25 Jun 2015 05:36:09 +0000 (14:36 +0900)
This flag should be set iif the string passed is to be executed
rather than assigned. This is used to pass complex arguments
as data, like tables (eg. color class).

src/lib/edje/edje_calc.c
src/lib/efl/interfaces/efl_gfx_filter.eo
src/lib/evas/canvas/evas_filter_mixin.c
src/lib/evas/filters/evas_filter_parser.c
src/lib/evas/include/evas_filter.h
src/lib/evas/include/evas_private.h

index f06a637..adeef5c 100644 (file)
@@ -2486,7 +2486,7 @@ _edje_part_recalc_single_filter(Edje *ed,
                    char *value = tup->data;
                    if (!value)
                      {
-                        efl_gfx_filter_data_set(name, NULL);
+                        efl_gfx_filter_data_set(name, NULL, EINA_FALSE);
                      }
                    else if (!strncmp(value, "color_class('", sizeof("color_class('") - 1))
                      {
@@ -2504,7 +2504,7 @@ _edje_part_recalc_single_filter(Edje *ed,
                                   cc = _edje_color_class_find(ed, ccname);
                                   if (cc)
                                     {
-                                       static const char fmt[] = "--\n"
+                                       static const char fmt[] =
                                              "%s={r=%d,g=%d,b=%d,a=%d,"
                                              "r2=%d,g2=%d,b2=%d,a2=%d,"
                                              "r3=%d,g3=%d,b3=%d,a3=%d}";
@@ -2516,7 +2516,7 @@ _edje_part_recalc_single_filter(Edje *ed,
                                                 (int) cc->r2, (int) cc->g2, (int) cc->b2, (int) cc->a2,
                                                 (int) cc->r3, (int) cc->g3, (int) cc->b3, (int) cc->a3);
                                        buffer[len - 1] = 0;
-                                       efl_gfx_filter_data_set(name, buffer);
+                                       efl_gfx_filter_data_set(name, buffer, EINA_TRUE);
                                     }
                                   else
                                     {
@@ -2533,7 +2533,7 @@ _edje_part_recalc_single_filter(Edje *ed,
                           }
                      }
                    else
-                     efl_gfx_filter_data_set(name, value);
+                     efl_gfx_filter_data_set(name, value, EINA_FALSE);
                 }
               eina_iterator_free(it);
            }
index 2140acf..a633c48 100644 (file)
@@ -75,8 +75,9 @@ interface Efl.Gfx.Filter
 
          This sets a global value as a string.]]
          params {
-            @in name: const(char)*; [[name of the global variable]]
-            @in value: const(char)*; [[string value to use as data]]
+            @in name: const(char)*; [[Name of the global variable]]
+            @in value: const(char)*; [[String value to use as data]]
+            @in execute: bool; [[If true, execute 'name = value']]
          }
       }
    }
index 5c47468..70e37b0 100644 (file)
@@ -493,6 +493,8 @@ EOLIAN void
 _evas_filter_destructor(Eo *eo_obj, Evas_Filter_Data *pd)
 {
    Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+   Evas_Filter_Data_Binding *db;
+   Eina_Inlist *il;
 
    if (!pd->data) return;
    if (evas_object_filter_cow_default == pd->data) return;
@@ -500,7 +502,12 @@ _evas_filter_destructor(Eo *eo_obj, Evas_Filter_Data *pd)
    if (pd->data->output)
      ENFN->image_free(ENDT, pd->data->output);
    eina_hash_free(pd->data->sources);
-   eina_hash_free(pd->data->data);
+   EINA_INLIST_FOREACH_SAFE(pd->data->data, il, db)
+     {
+        eina_stringshare_del(db->name);
+        eina_stringshare_del(db->value);
+        free(db);
+     }
    evas_filter_program_del(pd->data->chain);
    eina_stringshare_del(pd->data->code);
    eina_cow_free(evas_object_filter_cow, (const Eina_Cow_Data **) &pd->data);
@@ -508,25 +515,45 @@ _evas_filter_destructor(Eo *eo_obj, Evas_Filter_Data *pd)
 
 EOLIAN void
 _evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
-                                     const char *name, const char *value)
+                                     const char *name, const char *value,
+                                     Eina_Bool execute)
 {
-   const char *check = NULL;
+   Evas_Filter_Data_Binding *db, *found = NULL;
 
-   if (!pd->data) return;
+   EINA_SAFETY_ON_NULL_RETURN(pd->data);
+   EINA_SAFETY_ON_NULL_RETURN(name);
 
-   if (pd->data->data && ((check = eina_hash_find(pd->data->data, name)) != NULL))
+   EINA_INLIST_FOREACH(pd->data->data, db)
      {
-        if (!strcmp(check, value))
-          return;
+        if (!strcmp(name, db->name))
+          {
+             if (db->execute == execute)
+               {
+                  if ((value == db->value) || (value && db->value && !strcmp(value, db->value)))
+                    return;
+               }
+             found = db;
+             break;
+          }
      }
 
    EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
      {
-        if (!fcow->data)
-          fcow->data = eina_hash_string_small_new(free);
-        eina_hash_set(fcow->data, name, value ? strdup(value) : NULL);
-        if (fcow->chain)
-          evas_filter_program_data_set_all(fcow->chain, fcow->data);
+        if (found)
+          {
+             // Note: we are keeping references to NULL values here.
+             eina_stringshare_replace(&found->value, value);
+             found->execute = execute;
+          }
+        else if (value)
+          {
+             db = calloc(1, sizeof(Evas_Filter_Data_Binding));
+             db->name = eina_stringshare_add(name);
+             db->value = eina_stringshare_add(value);
+             db->execute = execute;
+             fcow->data = eina_inlist_append(fcow->data, EINA_INLIST_GET(db));
+          }
+        evas_filter_program_data_set_all(fcow->chain, fcow->data);
         fcow->changed = 1;
      }
    EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
index 58f75b8..7c4082c 100644 (file)
@@ -341,7 +341,7 @@ struct _Evas_Filter_Program
       int l, r, t, b;
    } pad;
    Evas_Filter_Program_State state;
-   Eina_Hash /* str -> str */ *data;
+   Eina_Inlist *data; // Evas_Filter_Data_Binding
    lua_State *L;
    int       lua_func;
    int       last_bufid;
@@ -2636,36 +2636,31 @@ _filter_program_state_set(Evas_Filter_Program *pgm)
    /* now push all extra data */
    if (pgm->data)
      {
-        Eina_Iterator *it = eina_hash_iterator_tuple_new(pgm->data);
-        Eina_Hash_Tuple *tup;
-        EINA_ITERATOR_FOREACH(it, tup)
+        Evas_Filter_Data_Binding *db;
+        EINA_INLIST_FOREACH(pgm->data, db)
           {
-             const char *name = tup->key;
-             const char *value = tup->data;
-             if (value)
+             if (db->value)
                {
-                  if ((value[0] == '-') && (value[1] == '-') && value[2] == '\n')
+                  if (db->execute)
                     {
-                       if (luaL_dostring(L, value) != 0)
+                       if (luaL_dostring(L, db->value) != 0)
                          {
-                            eina_iterator_free(it);
                             ERR("Failed to run value: %s", lua_tostring(L, -1));
                             return EINA_FALSE;
                          }
                     }
                   else
                     {
-                       lua_pushstring(L, value);
-                       lua_setglobal(L, name);
+                       lua_pushstring(L, db->value);
+                       lua_setglobal(L, db->name);
                     }
                }
              else
                {
                   lua_pushnil(L);
-                  lua_setglobal(L, name);
+                  lua_setglobal(L, db->name);
                }
           }
-        eina_iterator_free(it);
      }
 
    return EINA_TRUE;
@@ -2959,7 +2954,7 @@ evas_filter_program_source_set_all(Evas_Filter_Program *pgm,
 }
 
 void
-evas_filter_program_data_set_all(Evas_Filter_Program *pgm, Eina_Hash *data)
+evas_filter_program_data_set_all(Evas_Filter_Program *pgm, Eina_Inlist *data)
 {
    if (!pgm) return;
    pgm->data = data;
index 6784a0d..f1cbffb 100644 (file)
@@ -133,7 +133,7 @@ Eina_Bool                evas_filter_context_program_use(Evas_Filter_Context *ct
 EAPI Eina_Bool           evas_filter_program_padding_get(Evas_Filter_Program *pgm, int *l, int *r, int *t, int *b);
 EAPI void                evas_filter_program_source_set_all(Evas_Filter_Program *pgm, Eina_Hash *sources);
 void                     evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, Eina_Bool do_async);
-void                     evas_filter_program_data_set_all(Evas_Filter_Program *pgm, Eina_Hash *data);
+void                     evas_filter_program_data_set_all(Evas_Filter_Program *pgm, Eina_Inlist *data);
 
 /* Filter context (low level) */
 Evas_Filter_Context     *evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async);
@@ -294,6 +294,14 @@ struct _Evas_Filter_Proxy_Binding
    Eina_Stringshare *name;
 };
 
+struct _Evas_Filter_Data_Binding
+{
+   EINA_INLIST;
+   Eina_Stringshare *name;
+   Eina_Stringshare *value;
+   Eina_Bool execute : 1;
+};
+
 #undef EAPI
 #define EAPI
 
index c94c5ed..872dbad 100644 (file)
@@ -78,6 +78,7 @@ typedef struct _Evas_Object_Protected_Data  Evas_Object_Protected_Data;
 
 typedef struct _Evas_Filter_Program         Evas_Filter_Program;
 typedef struct _Evas_Object_Filter_Data     Evas_Object_Filter_Data;
+typedef struct _Evas_Filter_Data_Binding    Evas_Filter_Data_Binding;
 
 // 3D stuff
 
@@ -1178,7 +1179,7 @@ struct _Evas_Object_Filter_Data
    Eina_Stringshare    *code;
    Evas_Filter_Program *chain;
    Eina_Hash           *sources; // Evas_Filter_Proxy_Binding
-   Eina_Hash           *data; // str -> str
+   Eina_Inlist         *data; // Evas_Filter_Data_Binding
    void                *output;
    struct {
       struct {