Reduce memory allocation for edje match.

Just allocate and build the match automate for callbacks and programs
only when required. On load for programs and when callbacks list has
been updated.

Patch by Cedric BAIL. (with minor fixes to use TABS where context was using)


SVN revision: 33804
This commit is contained in:
Gustavo Sverzut Barbieri 2008-02-21 18:48:36 +00:00
parent e618b1d188
commit 435dfe2a2a
4 changed files with 81 additions and 80 deletions

View File

@ -410,6 +410,15 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *p
rp->text.text_source = ed->table_parts[rp->param1.description->text.id_text_source % ed->table_parts_size];
}
}
if (ed->patterns.programs.signals_patterns)
{
edje_match_patterns_free(ed->patterns.programs.signals_patterns);
edje_match_patterns_free(ed->patterns.programs.sources_patterns);
}
ed->patterns.programs.signals_patterns = edje_match_programs_signal_init(ed->collection->programs);
ed->patterns.programs.sources_patterns = edje_match_programs_source_init(ed->collection->programs);
n = evas_list_count(ed->collection->programs);
if (n > 0)
{

View File

@ -14,7 +14,6 @@ struct _Edje_State
size_t pos;
};
typedef struct _Edje_States Edje_States;
struct _Edje_States
{
size_t size;
@ -37,12 +36,13 @@ _edje_match_states_free(Edje_States *states,
Size++; \
};
static Edje_States*
_edje_match_states_alloc(size_t n,
size_t patterns_size,
size_t patterns_max_length)
static int
_edje_match_states_alloc(Edje_Patterns *ppat, int n)
{
Edje_States *l;
Edje_States *l;
const size_t patterns_size = ppat->patterns_size;
const size_t patterns_max_length = ppat->max_length;
const size_t array_len = (patterns_max_length + 1) * patterns_size;
@ -69,8 +69,9 @@ _edje_match_states_alloc(size_t n,
struct_size += states_has_size;
l = malloc(n * struct_size);
if (!l) return NULL;
if (!l) return 0;
ppat->states = l;
states = (unsigned char *) (l + n);
has = states + states_size;
@ -82,7 +83,7 @@ _edje_match_states_alloc(size_t n,
has += states_has_size;
}
return l;
return 1;
}
static void
@ -295,6 +296,12 @@ _edje_match_patterns_exec_init_states(Edje_States *states,
lst = evas_list_next(lst); \
} \
\
if (!_edje_match_states_alloc(r, 2)) \
{ \
free(r); \
return NULL; \
} \
\
return r; \
}
@ -451,22 +458,16 @@ int
edje_match_collection_dir_exec(const Edje_Patterns *ppat,
const char *string)
{
Edje_States *states = _edje_match_states_alloc(2,
ppat->patterns_size,
ppat->max_length);
Edje_States *result;
int r = 0;
if (!states)
return 0;
_edje_match_patterns_exec_init_states(states, ppat->patterns_size, ppat->max_length);
_edje_match_patterns_exec_init_states(ppat->states, ppat->patterns_size, ppat->max_length);
result = _edje_match_fn(ppat, string, states);
result = _edje_match_fn(ppat, string, ppat->states);
if (result)
r = _edje_match_collection_dir_exec_finals(ppat->finals, result);
_edje_match_states_free(states, 2);
return r;
}
@ -479,28 +480,19 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal,
int (*func)(Edje_Program *pr, void *data),
void *data)
{
Edje_States *signal_states = _edje_match_states_alloc(2,
ppat_signal->patterns_size,
ppat_signal->max_length);
Edje_States *source_states = _edje_match_states_alloc(2,
ppat_source->patterns_size,
ppat_source->max_length);
Edje_States *signal_result;
Edje_States *source_result;
int r = 0;
if (!signal_states || !source_states)
return 0;
_edje_match_patterns_exec_init_states(signal_states,
_edje_match_patterns_exec_init_states(ppat_signal->states,
ppat_signal->patterns_size,
ppat_signal->max_length);
_edje_match_patterns_exec_init_states(source_states,
_edje_match_patterns_exec_init_states(ppat_source->states,
ppat_source->patterns_size,
ppat_source->max_length);
signal_result = _edje_match_fn(ppat_signal, signal, signal_states);
source_result = _edje_match_fn(ppat_source, source, source_states);
signal_result = _edje_match_fn(ppat_signal, signal, ppat_signal->states);
source_result = _edje_match_fn(ppat_source, source, ppat_source->states);
if (signal_result && source_result)
r = edje_match_programs_exec_check_finals(ppat_signal->finals,
@ -510,9 +502,6 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal,
programs,
func,
data);
_edje_match_states_free(source_states, 2);
_edje_match_states_free(signal_states, 2);
return r;
}
@ -524,28 +513,19 @@ edje_match_callback_exec(const Edje_Patterns *ppat_signal,
Evas_List *callbacks,
Edje *ed)
{
Edje_States *signal_states = _edje_match_states_alloc(2,
ppat_signal->patterns_size,
ppat_signal->max_length);
Edje_States *source_states = _edje_match_states_alloc(2,
ppat_source->patterns_size,
ppat_source->max_length);
Edje_States *signal_result;
Edje_States *source_result;
int r = 0;
if (!signal_states || !source_states)
return 0;
_edje_match_patterns_exec_init_states(signal_states,
_edje_match_patterns_exec_init_states(ppat_signal->states,
ppat_signal->patterns_size,
ppat_signal->max_length);
_edje_match_patterns_exec_init_states(source_states,
_edje_match_patterns_exec_init_states(ppat_source->states,
ppat_source->patterns_size,
ppat_source->max_length);
signal_result = _edje_match_fn(ppat_signal, signal, signal_states);
source_result = _edje_match_fn(ppat_source, source, source_states);
signal_result = _edje_match_fn(ppat_signal, signal, ppat_signal->states);
source_result = _edje_match_fn(ppat_source, source, ppat_source->states);
if (signal_result && source_result)
r = edje_match_callback_exec_check_finals(ppat_signal->finals,
@ -556,15 +536,13 @@ edje_match_callback_exec(const Edje_Patterns *ppat_signal,
source,
callbacks,
ed);
_edje_match_states_free(source_states, 2);
_edje_match_states_free(signal_states, 2);
return r;
}
void
edje_match_patterns_free(Edje_Patterns *ppat)
{
_edje_match_states_free(ppat->states, 2);
free(ppat);
}

View File

@ -122,6 +122,7 @@ typedef struct _Edje_Part Edje_Part;
typedef struct _Edje_Part_Image_Id Edje_Part_Image_Id;
typedef struct _Edje_Part_Description Edje_Part_Description;
typedef struct _Edje_Spectrum_Color Edje_Spectrum_Color;
typedef struct _Edje_Patterns Edje_Patterns;
#define PI 3.14159265358979323846
@ -606,6 +607,17 @@ struct _Edje
int table_programs_size;
int table_parts_size;
struct {
struct {
Edje_Patterns *signals_patterns;
Edje_Patterns *sources_patterns;
} callbacks;
struct {
Edje_Patterns *signals_patterns;
Edje_Patterns *sources_patterns;
} programs;
} patterns;
int references;
int block;
int load_error;
@ -913,14 +925,16 @@ typedef enum _Edje_Match_Error
} Edje_Match_Error;
typedef struct _Edje_Patterns Edje_Patterns;
typedef struct _Edje_States Edje_States;
struct _Edje_Patterns
{
const char **patterns;
Edje_States *states;
size_t patterns_size;
size_t max_length;
size_t finals[];
};
Edje_Patterns *edje_match_collection_dir_init(Evas_List *lst);

View File

@ -5,6 +5,7 @@
#include "edje_private.h"
static void _edje_emit_cb(Edje *ed, const char *sig, const char *src);
static void _edje_clean_callbacks_patterns(Edje *ed);
int _edje_anim_count = 0;
Ecore_Animator *_edje_timer = NULL;
@ -105,6 +106,7 @@ edje_object_signal_callback_add(Evas_Object *obj, const char *emission, const ch
escb->just_added = 1;
ed->just_added_callbacks = 1;
}
_edje_clean_callbacks_patterns(ed);
}
/** Remove a callback from an object
@ -150,6 +152,8 @@ edje_object_signal_callback_del(Evas_Object *obj, const char *emission, const ch
}
else
{
_edje_clean_callbacks_patterns(ed);
ed->callbacks = evas_list_remove_list(ed->callbacks, l);
if (escb->signal) evas_stringshare_del(escb->signal);
if (escb->source) evas_stringshare_del(escb->source);
@ -926,29 +930,16 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src)
data.matched = 0;
data.matches = NULL;
#endif
Edje_Patterns *signals_patterns;
Edje_Patterns *sources_patterns;
if (ed->collection->programs)
{
signals_patterns = edje_match_programs_signal_init(ed->collection->programs);
sources_patterns = edje_match_programs_source_init(ed->collection->programs);
if (edje_match_programs_exec(signals_patterns,
sources_patterns,
if (edje_match_programs_exec(ed->patterns.programs.signals_patterns,
ed->patterns.programs.sources_patterns,
sig,
src,
ed->collection->programs,
_edje_glob_callback,
&data) == 0)
{
edje_match_patterns_free(signals_patterns);
edje_match_patterns_free(sources_patterns);
goto break_prog;
}
edje_match_patterns_free(signals_patterns);
edje_match_patterns_free(sources_patterns);
goto break_prog;
}
#ifdef EDJE_PROGRAM_CACHE
@ -979,8 +970,6 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src)
static void
_edje_emit_cb(Edje *ed, const char *sig, const char *src)
{
Edje_Patterns *signals_patterns;
Edje_Patterns *sources_patterns;
Evas_List *l;
if (ed->delete_me) return;
@ -993,25 +982,21 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src)
{
int r;
signals_patterns = edje_match_callback_signal_init(ed->callbacks);
sources_patterns = edje_match_callback_source_init(ed->callbacks);
if (!ed->patterns.callbacks.signals_patterns)
{
ed->patterns.callbacks.signals_patterns = edje_match_callback_signal_init(ed->callbacks);
ed->patterns.callbacks.sources_patterns = edje_match_callback_source_init(ed->callbacks);
}
r = edje_match_callback_exec(signals_patterns,
sources_patterns,
r = edje_match_callback_exec(ed->patterns.callbacks.signals_patterns,
ed->patterns.callbacks.sources_patterns,
sig,
src,
ed->callbacks,
ed);
if (!r)
{
edje_match_patterns_free(signals_patterns);
edje_match_patterns_free(sources_patterns);
goto break_prog;
}
edje_match_patterns_free(signals_patterns);
edje_match_patterns_free(sources_patterns);
goto break_prog;
}
ed->walking_callbacks = 0;
@ -1030,6 +1015,8 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src)
escb->just_added = 0;
if (escb->delete_me)
{
_edje_clean_callbacks_patterns(ed);
ed->callbacks = evas_list_remove_list(ed->callbacks, l);
if (escb->signal) evas_stringshare_del(escb->signal);
if (escb->source) evas_stringshare_del(escb->source);
@ -1043,3 +1030,16 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src)
_edje_thaw(ed);
_edje_unref(ed);
}
static void
_edje_clean_callbacks_patterns(Edje *ed)
{
if (ed->patterns.callbacks.signals_patterns)
{
edje_match_patterns_free(ed->patterns.callbacks.signals_patterns);
edje_match_patterns_free(ed->patterns.callbacks.sources_patterns);
ed->patterns.callbacks.signals_patterns = NULL;
ed->patterns.callbacks.sources_patterns = NULL;
}
}