diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index f06a6374ea..adeef5ce64 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -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); } diff --git a/src/lib/efl/interfaces/efl_gfx_filter.eo b/src/lib/efl/interfaces/efl_gfx_filter.eo index 2140acf4da..a633c48e0f 100644 --- a/src/lib/efl/interfaces/efl_gfx_filter.eo +++ b/src/lib/efl/interfaces/efl_gfx_filter.eo @@ -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']] } } } diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c index 5c4746817d..70e37b0991 100644 --- a/src/lib/evas/canvas/evas_filter_mixin.c +++ b/src/lib/evas/canvas/evas_filter_mixin.c @@ -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); diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c index 58f75b858b..7c4082c51d 100644 --- a/src/lib/evas/filters/evas_filter_parser.c +++ b/src/lib/evas/filters/evas_filter_parser.c @@ -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; diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h index 6784a0d9e7..f1cbffb31c 100644 --- a/src/lib/evas/include/evas_filter.h +++ b/src/lib/evas/include/evas_filter.h @@ -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 diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index c94c5edbd4..872dbade8e 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -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 {