edje: add edje_file_mmap_set.
This reduce the number of system call to stat especially when using GROUP and reduce the risk of a race condition when using GROUP.
This commit is contained in:
parent
861823848a
commit
7506faaca2
|
@ -1,3 +1,7 @@
|
|||
2013-08-09 Cedric Bail
|
||||
|
||||
* Edje: add edje_object_mmap_set().
|
||||
|
||||
2013-08-08 Tom Hacohen
|
||||
|
||||
* Evas textblock: Make the ellipsis format the same as the surrounding.
|
||||
|
|
1
NEWS
1
NEWS
|
@ -128,6 +128,7 @@ Additions:
|
|||
- support edc map color set
|
||||
- Add threshold support to Edje draggable part.
|
||||
- Reduce load time of Edje_Object using Evas_Object_Textblock and many styles.
|
||||
- Add edje_object_mmap_set.
|
||||
* Eeze:
|
||||
- Add a dummy libmount replacement for when libmount is not there.
|
||||
* Ecore_Con:
|
||||
|
|
|
@ -132,6 +132,7 @@ enum
|
|||
EDJE_OBJ_SUB_ID_PART_EXTERNAL_PARAM_TYPE_GET,
|
||||
|
||||
EDJE_OBJ_SUB_ID_FILE_SET,
|
||||
EDJE_OBJ_SUB_ID_MMAP_SET,
|
||||
EDJE_OBJ_SUB_ID_FILE_GET,
|
||||
EDJE_OBJ_SUB_ID_LOAD_ERROR_GET,
|
||||
|
||||
|
@ -611,6 +612,19 @@ enum
|
|||
*/
|
||||
#define edje_obj_file_set(file, group, ret) EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_FILE_SET), EO_TYPECHECK(const char*, file), EO_TYPECHECK(const char *, group), EO_TYPECHECK(Eina_Bool *, ret)
|
||||
|
||||
/**
|
||||
* @def edje_obj_mmap_set
|
||||
* @since 1.8
|
||||
*
|
||||
* @param[in] file in
|
||||
* @param[in] group in
|
||||
* @param[in] nested in
|
||||
* @param[out] ret out
|
||||
*
|
||||
* @see edje_object_file_set
|
||||
*/
|
||||
#define edje_obj_mmap_set(file, group, ret) EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_MMAP_SET), EO_TYPECHECK(Eina_File*, file), EO_TYPECHECK(const char *, group), EO_TYPECHECK(Eina_Bool *, ret)
|
||||
|
||||
/**
|
||||
* @def edje_obj_file_get
|
||||
* @since 1.8
|
||||
|
|
|
@ -1770,9 +1770,45 @@ EAPI const char *edje_object_data_get (const Evas_Object *obj, const
|
|||
*
|
||||
* @see edje_object_add()
|
||||
* @see edje_object_file_get()
|
||||
* @see edje_object_mmap_set()
|
||||
*/
|
||||
EAPI Eina_Bool edje_object_file_set (Evas_Object *obj, const char *file, const char *group);
|
||||
|
||||
/**
|
||||
* @brief Sets the @b EDJ file (and group within it) to load an Edje
|
||||
* object's contents from
|
||||
*
|
||||
* @param obj A handle to an Edje object
|
||||
* @param file The Eina_File pointing to the EDJ file to load @p from
|
||||
* @param group The name of the group, in @p file, which implements an
|
||||
* Edje object
|
||||
* @return @c EINA_TRUE, on success or @c EINA_FALSE, on errors (check
|
||||
* edje_object_load_error_get() after this call to get errors causes)
|
||||
*
|
||||
* Edje expects EDJ files, which are theming objects' descriptions and
|
||||
* resources packed together in an EET file, to read Edje object
|
||||
* definitions from. They usually are created with the @c .edj
|
||||
* extension. EDJ files, in turn, are assembled from @b textual object
|
||||
* description files, where one describes Edje objects declaratively
|
||||
* -- the EDC files (see @ref edcref "the syntax" for those files).
|
||||
*
|
||||
* Those description files were designed so that many Edje object
|
||||
* definitions -- also called @b groups (or collections) -- could be
|
||||
* packed together <b>in the same EDJ file</b>, so that a whole
|
||||
* application's theme could be packed in one file only. This is the
|
||||
* reason for the @p group argument.
|
||||
*
|
||||
* Use this function after you instantiate a new Edje object, so that
|
||||
* you can "give him life", telling where to get its contents from.
|
||||
*
|
||||
* @see edje_object_add()
|
||||
* @see edje_object_file_get()
|
||||
* @see edje_object_mmap_set()
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI Eina_Bool edje_object_mmap_set(Evas_Object *obj, Eina_File *file, const char *group);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the file and group name that a given Edje object is bound to
|
||||
*
|
||||
|
|
|
@ -399,32 +399,22 @@ _edje_file_dangling(Edje_File *edf)
|
|||
#endif
|
||||
|
||||
Edje_File *
|
||||
_edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed)
|
||||
_edje_cache_file_coll_open(Eina_File *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed)
|
||||
{
|
||||
Eina_File *f;
|
||||
Edje_File *edf;
|
||||
Eina_List *l, *hist;
|
||||
Edje_Part_Collection *edc;
|
||||
Edje_Part *ep;
|
||||
|
||||
f = eina_file_open(file, EINA_FALSE);
|
||||
if (!f)
|
||||
{
|
||||
*error_ret = EDJE_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_edje_file_hash)
|
||||
{
|
||||
_edje_file_hash = eina_hash_pointer_new(NULL);
|
||||
goto find_list;
|
||||
}
|
||||
|
||||
edf = eina_hash_find(_edje_file_hash, f);
|
||||
edf = eina_hash_find(_edje_file_hash, file);
|
||||
if (edf)
|
||||
{
|
||||
eina_file_close(f);
|
||||
|
||||
edf->references++;
|
||||
goto open;
|
||||
}
|
||||
|
@ -432,23 +422,17 @@ _edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, E
|
|||
find_list:
|
||||
EINA_LIST_FOREACH(_edje_file_cache, l, edf)
|
||||
{
|
||||
if (edf->f == f)
|
||||
if (edf->f == file)
|
||||
{
|
||||
eina_file_close(f);
|
||||
|
||||
edf->references = 1;
|
||||
_edje_file_cache = eina_list_remove_list(_edje_file_cache, l);
|
||||
eina_hash_direct_add(_edje_file_hash, f, edf);
|
||||
eina_hash_direct_add(_edje_file_hash, file, edf);
|
||||
goto open;
|
||||
}
|
||||
}
|
||||
|
||||
edf = _edje_file_open(f, coll, error_ret, edc_ret, eina_file_mtime_get(f));
|
||||
if (!edf)
|
||||
{
|
||||
eina_file_close(f);
|
||||
return NULL;
|
||||
}
|
||||
edf = _edje_file_open(file, coll, error_ret, edc_ret, eina_file_mtime_get(file));
|
||||
if (!edf) return NULL;
|
||||
|
||||
#ifdef HAVE_EIO
|
||||
if (ed) edf->edjes = eina_list_append(edf->edjes, ed);
|
||||
|
@ -456,7 +440,7 @@ find_list:
|
|||
(void) ed;
|
||||
#endif
|
||||
|
||||
eina_hash_direct_add(_edje_file_hash, f, edf);
|
||||
eina_hash_direct_add(_edje_file_hash, file, edf);
|
||||
/* return edf; */
|
||||
|
||||
open:
|
||||
|
|
|
@ -24,6 +24,8 @@ struct _Edje_Drag_Items
|
|||
} page;
|
||||
};
|
||||
|
||||
void _edje_file_add(Edje *ed, Eina_File *f);
|
||||
|
||||
/* START - Nested part support */
|
||||
#define _edje_smart_nested_type "Evas_Smart_Nested"
|
||||
typedef struct _Edje_Nested_Support Edje_Nested_Support;
|
||||
|
@ -80,6 +82,16 @@ edje_object_file_set(Evas_Object *obj, const char *file, const char *group)
|
|||
return ret;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edje_object_mmap_set(Evas_Object *obj, Eina_File *file, const char *group)
|
||||
{
|
||||
if (!obj) return EINA_FALSE;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
eo_do(obj, edje_obj_mmap_set(file, group, &ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edje_object_file_get(const Evas_Object *obj, const char **file, const char **group)
|
||||
{
|
||||
|
@ -149,11 +161,14 @@ EAPI Eina_List *
|
|||
edje_file_collection_list(const char *file)
|
||||
{
|
||||
Eina_List *lst = NULL;
|
||||
Eina_File *f;
|
||||
Edje_File *edf;
|
||||
int error_ret = 0;
|
||||
|
||||
if ((!file) || (!*file)) return NULL;
|
||||
edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL, NULL);
|
||||
f = eina_file_open(file, EINA_FALSE);
|
||||
if (!f) return NULL;
|
||||
edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
|
||||
if (edf)
|
||||
{
|
||||
Eina_Iterator *i;
|
||||
|
@ -168,6 +183,7 @@ edje_file_collection_list(const char *file)
|
|||
|
||||
_edje_cache_file_unref(edf);
|
||||
}
|
||||
eina_file_close(f);
|
||||
return lst;
|
||||
}
|
||||
|
||||
|
@ -185,6 +201,7 @@ EAPI Eina_Bool
|
|||
edje_file_group_exists(const char *file, const char *glob)
|
||||
{
|
||||
Edje_File *edf;
|
||||
Eina_File *f;
|
||||
int error_ret = 0;
|
||||
Eina_Bool succeed = EINA_FALSE;
|
||||
Eina_Bool is_glob = EINA_FALSE;
|
||||
|
@ -193,9 +210,11 @@ edje_file_group_exists(const char *file, const char *glob)
|
|||
if ((!file) || (!*file) || (!glob))
|
||||
return EINA_FALSE;
|
||||
|
||||
edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL, NULL);
|
||||
if (!edf)
|
||||
return EINA_FALSE;
|
||||
f = eina_file_open(file, EINA_FALSE);
|
||||
if (!f) return EINA_FALSE;
|
||||
|
||||
edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
|
||||
if (!edf) goto on_error;
|
||||
|
||||
for (p = glob; *p; p++)
|
||||
{
|
||||
|
@ -240,6 +259,8 @@ edje_file_group_exists(const char *file, const char *glob)
|
|||
|
||||
DBG("edje_file_group_exists: '%s', '%s': %i.", file, glob, succeed);
|
||||
|
||||
on_error:
|
||||
eina_file_close(f);
|
||||
return succeed;
|
||||
}
|
||||
|
||||
|
@ -248,12 +269,16 @@ EAPI char *
|
|||
edje_file_data_get(const char *file, const char *key)
|
||||
{
|
||||
Edje_File *edf;
|
||||
Eina_File *f;
|
||||
char *str = NULL;
|
||||
int error_ret = 0;
|
||||
|
||||
if (key)
|
||||
{
|
||||
edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL, NULL);
|
||||
f = eina_file_open(file, EINA_FALSE);
|
||||
if (!f) return NULL;
|
||||
|
||||
edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
|
||||
if (edf)
|
||||
{
|
||||
str = (char*) edje_string_get(eina_hash_find(edf->data, key));
|
||||
|
@ -262,6 +287,8 @@ edje_file_data_get(const char *file, const char *key)
|
|||
|
||||
_edje_cache_file_unref(edf);
|
||||
}
|
||||
|
||||
eina_file_close(f);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
@ -290,7 +317,7 @@ _edje_physics_world_update_cb(void *data, EPhysics_World *world EINA_UNUSED, voi
|
|||
#endif
|
||||
|
||||
int
|
||||
_edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested)
|
||||
_edje_object_file_set_internal(Evas_Object *obj, Eina_File *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested)
|
||||
{
|
||||
Edje *ed;
|
||||
Evas *tev;
|
||||
|
@ -310,18 +337,11 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
|
|||
|
||||
ed = _edje_fetch(obj);
|
||||
if (!ed) return 0;
|
||||
if (!file) file = "";
|
||||
if (!group) group = "";
|
||||
if (((ed->path) && (!strcmp(file, ed->path))) &&
|
||||
(ed->group) && (!strcmp(group, ed->group)) &&
|
||||
ed->file)
|
||||
if ((ed->file) && (ed->file->f == file) &&
|
||||
(ed->group) && (!strcmp(group, ed->group)))
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(file, &st) != 0)
|
||||
return 1;
|
||||
if (st.st_mtime == ed->file->mtime)
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
tev = evas_object_evas_get(obj);
|
||||
|
@ -343,13 +363,13 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
|
|||
|
||||
_edje_file_del(ed);
|
||||
|
||||
eina_stringshare_replace(&ed->path, file);
|
||||
eina_stringshare_replace(&ed->path, file ? eina_file_filename_get(file) : NULL);
|
||||
eina_stringshare_replace(&ed->group, group);
|
||||
|
||||
ed->parent = eina_stringshare_add(parent);
|
||||
|
||||
ed->load_error = EDJE_LOAD_ERROR_NONE;
|
||||
_edje_file_add(ed);
|
||||
_edje_file_add(ed, file);
|
||||
ed->block_break = EINA_FALSE;
|
||||
|
||||
if (ed->file && ed->file->external_dir)
|
||||
|
@ -567,7 +587,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
|
|||
break;
|
||||
case EDJE_PART_TYPE_GRADIENT:
|
||||
ERR("SPANK ! SPANK ! SPANK ! YOU ARE USING GRADIENT IN PART %s FROM GROUP %s INSIDE FILE %s !! THEY ARE NOW REMOVED !",
|
||||
ep->name, group, file);
|
||||
ep->name, group, eina_file_filename_get(file));
|
||||
break;
|
||||
case EDJE_PART_TYPE_SPACER:
|
||||
rp->object = NULL;
|
||||
|
@ -834,7 +854,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
|
|||
if (data == group_path_entry)
|
||||
{
|
||||
ERR("recursive loop group '%s' already included inside part '%s' of group '%s' from file '%s'",
|
||||
group_path_entry, rp->part->name, group, file);
|
||||
group_path_entry, rp->part->name, group, eina_file_filename_get(file));
|
||||
ed->load_error = EDJE_LOAD_ERROR_RECURSIVE_REFERENCE;
|
||||
eina_stringshare_del(group_path_entry);
|
||||
goto on_error;
|
||||
|
@ -862,7 +882,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
|
|||
if (!_edje_object_file_set_internal(child_obj, file, source, rp->part->name, group_path, nested))
|
||||
{
|
||||
ERR("impossible to set part '%s' of group '%s' from file '%s' to '%s'",
|
||||
rp->part->name, group_path_entry, file, source);
|
||||
rp->part->name, group_path_entry, eina_file_filename_get(file), source);
|
||||
ed->load_error = edje_object_load_error_get(child_obj);
|
||||
evas_object_del(child_obj);
|
||||
eina_stringshare_del(group_path_entry);
|
||||
|
@ -1106,13 +1126,20 @@ on_error:
|
|||
}
|
||||
|
||||
void
|
||||
_edje_file_add(Edje *ed)
|
||||
_edje_file_add(Edje *ed, Eina_File *f)
|
||||
{
|
||||
if (!_edje_edd_edje_file) return;
|
||||
ed->file = _edje_cache_file_coll_open(ed->path, ed->group,
|
||||
&(ed->load_error),
|
||||
&(ed->collection),
|
||||
ed);
|
||||
if (!f)
|
||||
{
|
||||
ed->load_error = EDJE_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
ed->file = _edje_cache_file_coll_open(f, ed->group,
|
||||
&(ed->load_error),
|
||||
&(ed->collection),
|
||||
ed);
|
||||
}
|
||||
|
||||
if (!ed->collection)
|
||||
{
|
||||
|
|
|
@ -1967,9 +1967,8 @@ void *_edje_signal_callback_disable(const Edje_Signal_Callback_Group *cgp,
|
|||
EAPI void _edje_edd_init(void);
|
||||
EAPI void _edje_edd_shutdown(void);
|
||||
|
||||
int _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested);
|
||||
int _edje_object_file_set_internal(Evas_Object *obj, Eina_File *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested);
|
||||
|
||||
void _edje_file_add(Edje *ed);
|
||||
void _edje_file_del(Edje *ed);
|
||||
void _edje_file_free(Edje_File *edf);
|
||||
void _edje_file_cache_shutdown(void);
|
||||
|
@ -2150,7 +2149,7 @@ void _edje_textblock_styles_del(Edje *ed);
|
|||
void _edje_textblock_style_all_update(Edje *ed);
|
||||
void _edje_textblock_style_parse_and_fix(Edje_File *edf);
|
||||
void _edje_textblock_style_cleanup(Edje_File *edf);
|
||||
Edje_File *_edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed);
|
||||
Edje_File *_edje_cache_file_coll_open(Eina_File *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed);
|
||||
void _edje_cache_coll_clean(Edje_File *edf);
|
||||
void _edje_cache_coll_flush(Edje_File *edf);
|
||||
void _edje_cache_coll_unref(Edje_File *edf, Edje_Part_Collection *edc);
|
||||
|
|
|
@ -333,12 +333,37 @@ _edje_smart_file_set(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
|
|||
const char *file = va_arg(*list, const char *);
|
||||
const char *group = va_arg(*list, const char *);
|
||||
Eina_Bool *ret = va_arg(*list, Eina_Bool *);
|
||||
Eina_File *f;
|
||||
Eina_Array *nested;
|
||||
|
||||
if (ret) *ret = EINA_FALSE;
|
||||
|
||||
f = eina_file_open(file, EINA_FALSE);
|
||||
nested = eina_array_new(8);
|
||||
|
||||
if (_edje_object_file_set_internal(obj, f, group, NULL, NULL, nested))
|
||||
if (ret) *ret = EINA_TRUE;
|
||||
|
||||
eina_array_free(nested);
|
||||
eina_file_close(f);
|
||||
_edje_object_orientation_inform(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_smart_mmap_set(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
|
||||
{
|
||||
Eina_File *f = va_arg(*list, Eina_File *);
|
||||
const char *group = va_arg(*list, const char *);
|
||||
Eina_Bool *ret = va_arg(*list, Eina_Bool *);
|
||||
Eina_Array *nested;
|
||||
|
||||
if (ret) *ret = EINA_FALSE;
|
||||
|
||||
nested = eina_array_new(8);
|
||||
if (_edje_object_file_set_internal(obj, file, group, NULL, NULL, nested))
|
||||
|
||||
if (_edje_object_file_set_internal(obj, f, group, NULL, NULL, nested))
|
||||
if (ret) *ret = EINA_TRUE;
|
||||
|
||||
eina_array_free(nested);
|
||||
_edje_object_orientation_inform(obj);
|
||||
}
|
||||
|
@ -481,6 +506,7 @@ _edje_smart_class_constructor(Eo_Class *klass)
|
|||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_PART_EXTERNAL_CONTENT_GET), _part_external_content_get),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_PART_EXTERNAL_PARAM_TYPE_GET), _part_external_param_type_get),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_FILE_SET), _edje_smart_file_set),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_MMAP_SET), _edje_smart_mmap_set),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_FILE_GET), _file_get),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_LOAD_ERROR_GET), _load_error_get),
|
||||
EO_OP_FUNC(EDJE_OBJ_ID(EDJE_OBJ_SUB_ID_MESSAGE_SEND), _message_send),
|
||||
|
@ -626,6 +652,7 @@ static const Eo_Op_Description op_desc[] = {
|
|||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_PART_EXTERNAL_CONTENT_GET, "Get an object contained in an part of type EXTERNAL"),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_PART_EXTERNAL_PARAM_TYPE_GET, "Facility to query the type of the given parameter of the given part."),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_FILE_SET, "Sets the @b EDJ file (and group within it) to load an Edje"),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_MMAP_SET, "Sets the @b EDJ file (and group within it) to load an Edje"),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_FILE_GET, "Get the file and group name that a given Edje object is bound to"),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_LOAD_ERROR_GET, "Gets the (last) file loading error for a given Edje object"),
|
||||
EO_OP_DESCRIPTION(EDJE_OBJ_SUB_ID_MESSAGE_SEND, "Send an (Edje) message to a given Edje object"),
|
||||
|
|
Loading…
Reference in New Issue