Edje: Add proper filters section in the EDJ file

Don't [ab]use the file data section for filter scripts, instead
create a proper section for them. The rest of the behaviour stays
the same.
This commit is contained in:
Jean-Philippe Andre 2015-06-29 16:47:00 +09:00
parent a31222ae6f
commit 3648b0e252
4 changed files with 204 additions and 13 deletions

View File

@ -65,6 +65,7 @@
* <li>@ref sec_toplevel_data "Data"</li>
* <li>@ref sec_toplevel_color_classes "Color Classes"</li>
* <li>@ref sec_toplevel_styles "Styles"</li>
* <li>@ref sec_collections_group_filter "Filters"</li> <!-- dup -->
* </ul>
* <li>@ref sec_collections "Collections"</li>
* <ul>
@ -72,6 +73,7 @@
* <ul>
* <li>@ref sec_collections_sounds_sample "Sample"</li>
* </ul>
* <li>@ref sec_collections_group_filter "Filters"</li>
* <li>@ref sec_collections_vibrations "Vibrations"</li>
* <ul>
* <li>@ref sec_collections_vibrations_sample "Sample"</li>
@ -81,6 +83,7 @@
* <li>@ref sec_collections_group_script "Script"</li>
* <li>@ref sec_collections_group_limits "Limits"</li>
* <li>@ref sec_collections_group_data "Data"</li>
* <li>@ref sec_collections_group_filter "Filters"</li>
* <li>@ref sec_collections_group_parts "Parts"</li>
* <ul>
* <li>@ref sec_collections_group_parts_part "Part"</li>
@ -209,6 +212,9 @@ static void st_color_class_color2(void);
static void st_color_class_color3(void);
static void st_color_class_desc(void);
static void st_filters_filter_inline(void);
static void st_filters_filter_file(void);
static void ob_collections(void);
static void st_collections_base_scale(void);
@ -617,6 +623,12 @@ static void st_collections_group_nobroadcast(void);
ed->type_node.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION; \
}
#define FILTERS_STATEMENTS(PREFIX) \
{PREFIX"filters", NULL}, \
{PREFIX"filters.filter", NULL}, \
{PREFIX"filters.filter.inline", st_filters_filter_inline}, \
{PREFIX"filters.filter.file", st_filters_filter_file},
New_Statement_Handler statement_handlers[] =
{
{"externals.external", st_externals_external},
@ -624,6 +636,7 @@ New_Statement_Handler statement_handlers[] =
FONT_STYLE_CC_STATEMENTS("")
{"data.item", st_data_item},
{"data.file", st_data_file},
FILTERS_STATEMENTS("")
{"collections.externals.external", st_externals_external}, /* dup */
IMAGE_STATEMENTS("collections.")
IMAGE_SET_STATEMENTS("collections")
@ -643,6 +656,7 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.sounds.tone", st_collections_group_sound_tone}, /* dup */
{"collections.vibrations.sample.name", st_collections_group_vibration_sample_name},
{"collections.vibrations.sample.source", st_collections_group_vibration_sample_source},
FILTERS_STATEMENTS("collections.") /* dup */
{"collections.group.vibrations.sample.name", st_collections_group_vibration_sample_name}, /* dup */
{"collections.group.vibrations.sample.source", st_collections_group_vibration_sample_source}, /* dup */
{"collections.group.name", st_collections_group_name},
@ -903,6 +917,7 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.physics.world.z", st_collections_group_physics_world_z},
{"collections.group.physics.world.depth", st_collections_group_physics_world_depth},
#endif
FILTERS_STATEMENTS("collections.group.") /* dup */
PROGRAM_STATEMENTS("collections.group.parts.part.description")
PROGRAM_STATEMENTS("collections.group.parts.part")
PROGRAM_STATEMENTS("collections.group.parts")
@ -4283,6 +4298,148 @@ st_collections_group_data_item(void)
eina_hash_direct_add(pc->data, key, es);
}
/** @edcsubsection{collections_group_filter,
* Group.Filter} */
/**
@page edcref
@block
filters
@context
filters {
filter {
inline: "key" "Lua script here";
file: "key" "Lua script filename";
..
}
}
@description
The "filter" block lets you embed filter scripts into an EDC group,
that can then be referred to in a @ref sec_collections_group_parts_description_filter "Text.Filter"
or @ref collections_group_parts_description_filter "Image.Filter" statement.
In a similar way to the @ref sec_collections_group_data "Group.Data" blocks,
it is possible to embed filters from a external file inside the final EDJ.
Please also refer to @ref evasfiltersref "Evas filters reference".
@endblock
@property
inline
@parameters
[name] [Lua script]
@effect
Defines a new Lua script used for filtering.
@endproperty
@property
file
@parameters
[name] [Lua script filename]
@effect
Includes an external file to define a new Lua script used for filtering.
@endproperty
*/
// ensure order so we could do binary search later on
// since this here happens at build time, we don't care about very hi-perf
static void
_filters_filter_insert(const char *name, const char *script)
{
Edje_Gfx_Filter *array;
int k, i;
if (!edje_file->filter_dir)
edje_file->filter_dir = mem_alloc(sizeof(Edje_Gfx_Filter_Directory));
for (k = 0; k < edje_file->filter_dir->filters_count; k++)
{
int cmp = strcmp(name, edje_file->filter_dir->filters[k].name);
if (!cmp)
{
ERR("parse error %s:%i. A filter named '%s' already exists within this block.",
file_in, line - 1, name);
exit(-1);
}
else if (cmp < 0)
break;
}
array = realloc(edje_file->filter_dir->filters,
sizeof(Edje_Gfx_Filter) * (edje_file->filter_dir->filters_count + 1));
if (!array)
{
ERR("Memory allocation failed (array grow)");
exit(-1);
}
for (i = edje_file->filter_dir->filters_count - 1; i >= k; i--)
array[i + 1] = array[i];
array[k].name = eina_stringshare_add(name);
array[k].script = eina_stringshare_add(script);
edje_file->filter_dir->filters_count++;
edje_file->filter_dir->filters = array;
}
static void
st_filters_filter_inline(void)
{
char *name, *script;
check_arg_count(2);
name = parse_str(0);
script = parse_str(1);
_filters_filter_insert(name, script);
free(name);
free(script);
}
static void
st_filters_filter_file(void)
{
char *name, *file, *script;
Eina_File *f;
check_arg_count(2);
name = parse_str(0);
file = parse_str(1);
f = eina_file_open(file, EINA_FALSE);
if (!f)
{
char path[PATH_MAX], *dir;
Eina_List *l;
// TODO: Introduce special filters_dir? needs new edje_cc argument :(
EINA_LIST_FOREACH(data_dirs, l, dir)
{
snprintf(path, sizeof(path), "%s/%s", dir, file);
f = eina_file_open(path, EINA_FALSE);
if (f) break;
}
if (!f)
{
ERR("parse error %s:%i. Could not open filter script file '%s'",
file_in, line - 1, file);
exit(-1);
}
}
script = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!script)
{
ERR("parse error %s:%i. Could not read filter script file %s",
file_in, line - 1, file);
exit(-1);
}
_filters_filter_insert(name, script);
eina_file_map_free(f, script);
eina_file_close(f);
free(name);
}
/** @edcsubsection{collections_group_limits,
* Group.Limits} */

View File

@ -2406,22 +2406,25 @@ _edje_part_recalc_single_map(Edje *ed,
}
static inline const char *
_edje_filter_get(Edje *ed, Edje_Real_Part *ep, Edje_Part_Description_Spec_Filter *filter)
_edje_filter_get(Edje *ed, Edje_Part_Description_Spec_Filter *filter)
{
int k;
if (!filter->code) return NULL;
if (EINA_UNLIKELY(!filter->checked_data))
{
Edje_String *st;
filter->checked_data = 1;
st = eina_hash_find(ed->file->data, filter->code);
if (st)
{
filter->name = filter->code;
filter->code = st->str;
filter->no_free = 1;
}
else
filter->name = eina_stringshare_add(ep->part->name);
// FIXME: bisect search instead of linear search
filter->checked_data = EINA_TRUE;
if (ed->file->filter_dir)
for (k = 0; k <= ed->file->filter_dir->filters_count; k++)
{
if (!strcmp(filter->code, ed->file->filter_dir->filters[k].name))
{
filter->name = ed->file->filter_dir->filters[k].name;
filter->code = ed->file->filter_dir->filters[k].script;
filter->no_free = EINA_TRUE;
return filter->code;
}
}
}
return filter->code;
}
@ -2463,7 +2466,7 @@ _edje_part_recalc_single_filter(Edje *ed,
}
/* common code below */
code = _edje_filter_get(ed, ep, filter);
code = _edje_filter_get(ed, filter);
if (!code)
{
eo_do(obj, efl_gfx_filter_program_set(NULL, NULL));

View File

@ -75,6 +75,8 @@ Eet_Data_Descriptor *_edje_edd_edje_part_limit = NULL;
Eet_Data_Descriptor *_edje_edd_edje_physics_face = NULL;
Eet_Data_Descriptor *_edje_edd_edje_map_colors = NULL;
Eet_Data_Descriptor *_edje_edd_edje_map_colors_pointer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_filter = NULL;
Eet_Data_Descriptor *_edje_edd_edje_filter_directory = NULL;
/* allocate a description struct.
* this initializes clip_to_id as this field will not be present in most
@ -239,6 +241,8 @@ _edje_edd_shutdown(void)
FREED(_edje_edd_edje_mo_directory);
FREED(_edje_edd_edje_vibration_sample);
FREED(_edje_edd_edje_vibration_directory);
FREED(_edje_edd_edje_filter);
FREED(_edje_edd_edje_filter_directory);
FREED(_edje_edd_edje_program);
FREED(_edje_edd_edje_program_pointer);
FREED(_edje_edd_edje_program_target);
@ -460,6 +464,16 @@ _edje_edd_init(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_3d_vec, Edje_3D_Vec, "y", y, EDJE_T_FLOAT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_3d_vec, Edje_3D_Vec, "z", z, EDJE_T_FLOAT);
/* Efl.Gfx.Filter */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Gfx_Filter);
_edje_edd_edje_filter = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_filter, Edje_Gfx_Filter, "name", name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_filter, Edje_Gfx_Filter, "script", script, EET_T_STRING);
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Gfx_Filter_Directory);
_edje_edd_edje_filter_directory = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_filter_directory, Edje_Gfx_Filter_Directory, "filters", filters, _edje_edd_edje_filter);
/* collection directory */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Collection_Directory_Entry);
_edje_edd_edje_part_collection_directory_entry =
@ -533,6 +547,7 @@ _edje_edd_init(void)
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "model_dir", model_dir, _edje_edd_edje_model_directory);
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "sound_dir", sound_dir, _edje_edd_edje_sound_directory);
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "mo_dir", mo_dir, _edje_edd_edje_mo_directory);
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "filter_dir", filter_dir, _edje_edd_edje_filter_directory);
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "vibration_dir", vibration_dir, _edje_edd_edje_vibration_directory);
EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, "styles", styles, _edje_edd_edje_style);

View File

@ -326,6 +326,8 @@ typedef struct _Edje_Sound_Tone Edje_Sound_Tone;
typedef struct _Edje_Sound_Directory Edje_Sound_Directory;
typedef struct _Edje_Mo Edje_Mo;
typedef struct _Edje_Mo_Directory Edje_Mo_Directory;
typedef struct _Edje_Gfx_Filter Edje_Gfx_Filter;
typedef struct _Edje_Gfx_Filter_Directory Edje_Gfx_Filter_Directory;
typedef struct _Edje_Vibration_Sample Edje_Vibration_Sample;
typedef struct _Edje_Vibration_Directory Edje_Vibration_Directory;
@ -533,6 +535,7 @@ struct _Edje_File
Edje_Sound_Directory *sound_dir;
Edje_Vibration_Directory *vibration_dir;
Edje_Mo_Directory *mo_dir;
Edje_Gfx_Filter_Directory *filter_dir;
Eina_List *styles;
@ -719,6 +722,19 @@ struct _Edje_Vibration_Directory
Edje_Vibration_Sample *samples; /* an array of Edje_Sound_Sample entries */
unsigned int samples_count;
};
struct _Edje_Gfx_Filter
{
Eina_Stringshare *name;
Eina_Stringshare *script;
};
struct _Edje_Gfx_Filter_Directory
{
Edje_Gfx_Filter *filters; /* array */
int filters_count;
};
/*----------*/
struct _Edje_Program /* a conditional program to be run */