1 #include "edje_private.h"
4 static Eina_Hash *_edje_file_hash = NULL;
5 static int _edje_file_cache_size = 16;
6 static Eina_List *_edje_file_cache = NULL;
8 static int _edje_collection_cache_size = 16;
10 static Edje_Part_Collection *
11 _edje_file_coll_open(Edje_File *edf, const char *coll)
13 Edje_Part_Collection *edc = NULL;
14 Edje_Part_Collection_Directory_Entry *ce;
15 int id = -1, size = 0;
21 ce = eina_hash_find(edf->collection, coll);
26 ce->ref->references++;
30 EINA_LIST_FOREACH(edf->collection_cache, l, edc)
32 if (!strcmp(edc->part, coll))
37 edf->collection_cache = eina_list_remove_list(edf->collection_cache, l);
43 if (id < 0) return NULL;
45 #define INIT_EMP(Tp, Sz, Ce) \
46 buffer = alloca(strlen(ce->entry) + strlen(#Tp) + 2); \
47 sprintf(buffer, "%s/%s", ce->entry, #Tp); \
48 Ce->mp.Tp = eina_mempool_add("one_big", buffer, NULL, sizeof (Sz), Ce->count.Tp); \
49 _emp_##Tp = Ce->mp.Tp;
51 #define INIT_EMP_BOTH(Tp, Sz, Ce) \
52 INIT_EMP(Tp, Sz, Ce) \
53 Ce->mp_rtl.Tp = eina_mempool_add("one_big", buffer, NULL, \
54 sizeof (Sz), Ce->count.Tp);
56 INIT_EMP_BOTH(RECTANGLE, Edje_Part_Description_Common, ce);
57 INIT_EMP_BOTH(TEXT, Edje_Part_Description_Text, ce);
58 INIT_EMP_BOTH(IMAGE, Edje_Part_Description_Image, ce);
59 INIT_EMP_BOTH(PROXY, Edje_Part_Description_Proxy, ce);
60 INIT_EMP_BOTH(SWALLOW, Edje_Part_Description_Common, ce);
61 INIT_EMP_BOTH(TEXTBLOCK, Edje_Part_Description_Text, ce);
62 INIT_EMP_BOTH(GROUP, Edje_Part_Description_Common, ce);
63 INIT_EMP_BOTH(BOX, Edje_Part_Description_Box, ce);
64 INIT_EMP_BOTH(TABLE, Edje_Part_Description_Table, ce);
65 INIT_EMP_BOTH(EXTERNAL, Edje_Part_Description_External, ce);
66 INIT_EMP_BOTH(SPACER, Edje_Part_Description_Common, ce);
67 INIT_EMP(part, Edje_Part, ce);
69 snprintf(buf, sizeof(buf), "edje/collections/%i", id);
70 edc = eet_data_read(edf->ef, _edje_edd_edje_part_collection, buf);
71 if (!edc) return NULL;
74 edc->part = ce->entry;
76 /* For Edje file build with Edje 1.0 */
77 if (edf->version <= 3 && edf->minor <= 1)
79 /* This will preserve previous rendering */
82 /* people expect signal to not be broadcasted */
83 edc->broadcast_signal = EINA_FALSE;
85 /* people expect text.align to be 0.0 0.0 */
86 for (i = 0; i < edc->parts_count; ++i)
88 if (edc->parts[i]->type == EDJE_PART_TYPE_TEXTBLOCK)
90 Edje_Part_Description_Text *text;
93 text = (Edje_Part_Description_Text*) edc->parts[i]->default_desc;
94 text->text.align.x = TO_DOUBLE(0.0);
95 text->text.align.y = TO_DOUBLE(0.0);
97 for (j = 0; j < edc->parts[i]->other.desc_count; ++j)
99 text = (Edje_Part_Description_Text*) edc->parts[i]->other.desc[j];
100 text->text.align.x = TO_DOUBLE(0.0);
101 text->text.align.y = TO_DOUBLE(0.0);
107 snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%i", id);
108 data = eet_read(edf->ef, buf, &size);
112 edc->script = embryo_program_new(data, size);
113 _edje_embryo_script_init(edc);
117 snprintf(buf, sizeof(buf), "edje/scripts/lua/%i", id);
118 data = eet_read(edf->ef, buf, &size);
122 _edje_lua2_script_load(edc, data, size);
133 _edje_file_warn(void *data)
135 Edje_File *edf = data;
141 EINA_LIST_FOREACH(edf->edjes, l, ed)
144 EINA_LIST_FOREACH(edf->edjes, l, ed)
146 _edje_emit(ed, "edje,change,file", "edje");
149 EINA_LIST_FOREACH_SAFE(edf->edjes, l, ll, ed)
159 _edje_file_change(void *data, int ev_type __UNUSED__, void *event)
161 Edje_File *edf = data;
162 Eio_Monitor_Event *ev = event;
164 if (ev->monitor == edf->monitor)
166 if (edf->timeout) ecore_timer_del(edf->timeout);
167 edf->timeout = ecore_timer_add(0.5, _edje_file_warn, edf);
169 return ECORE_CALLBACK_PASS_ON;
174 _edje_file_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, time_t mtime)
176 Edje_Color_Class *cc;
179 Edje_Part_Collection *edc;
182 Ecore_Event_Handler *ev;
185 ef = eet_open(file, EET_FILE_MODE_READ);
188 *error_ret = EDJE_LOAD_ERROR_UNKNOWN_FORMAT;
191 edf = eet_data_read(ef, _edje_edd_edje_file, "edje/file");
194 *error_ret = EDJE_LOAD_ERROR_CORRUPT_FILE;
202 edf->monitor = eio_monitor_add(file);
203 ev = ecore_event_handler_add(EIO_MONITOR_FILE_DELETED, _edje_file_change, edf);
204 edf->handlers = eina_list_append(edf->handlers, ev);
205 ev = ecore_event_handler_add(EIO_MONITOR_FILE_MODIFIED, _edje_file_change, edf);
206 edf->handlers = eina_list_append(edf->handlers, ev);
207 ev = ecore_event_handler_add(EIO_MONITOR_FILE_CREATED, _edje_file_change, edf);
208 edf->handlers = eina_list_append(edf->handlers, ev);
209 ev = ecore_event_handler_add(EIO_MONITOR_SELF_DELETED, _edje_file_change, edf);
210 edf->handlers = eina_list_append(edf->handlers, ev);
213 if (edf->version != EDJE_FILE_VERSION)
215 *error_ret = EDJE_LOAD_ERROR_INCOMPATIBLE_FILE;
216 _edje_file_free(edf);
219 if (!edf->collection)
221 *error_ret = EDJE_LOAD_ERROR_CORRUPT_FILE;
222 _edje_file_free(edf);
226 if (edf->minor > EDJE_FILE_MINOR)
228 WRN("`%s` may use feature from a newer edje and could not show up as expected.", file);
231 edf->path = eina_stringshare_add(file);
234 /* This should be done at edje generation time */
235 _edje_textblock_style_parse_and_fix(edf);
236 edf->color_hash = eina_hash_string_small_new(NULL);
237 EINA_LIST_FOREACH(edf->color_classes, l, cc)
239 eina_hash_direct_add(edf->color_hash, cc->name, cc);
243 edc = _edje_file_coll_open(edf, coll);
246 *error_ret = EDJE_LOAD_ERROR_UNKNOWN_COLLECTION;
248 if (edc_ret) *edc_ret = edc;
255 _edje_file_dangling(Edje_File *edf)
257 if (edf->dangling) return;
258 edf->dangling = EINA_TRUE;
260 eina_hash_del(_edje_file_hash, edf->path, edf);
261 if (!eina_hash_population(_edje_file_hash))
263 eina_hash_free(_edje_file_hash);
264 _edje_file_hash = NULL;
269 _edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, Edje_Part_Collection **edc_ret, Edje *ed)
273 Edje_Part_Collection *edc;
277 if (stat(file, &st) != 0)
279 *error_ret = EDJE_LOAD_ERROR_DOES_NOT_EXIST;
283 if (!_edje_file_hash)
285 _edje_file_hash = eina_hash_string_small_new(NULL);
289 edf = eina_hash_find(_edje_file_hash, file);
292 if (edf->mtime != st.st_mtime)
294 _edje_file_dangling(edf);
303 EINA_LIST_FOREACH(_edje_file_cache, l, edf)
305 if (!strcmp(edf->path, file))
307 if (edf->mtime != st.st_mtime)
309 _edje_file_cache = eina_list_remove_list(_edje_file_cache, l);
310 _edje_file_free(edf);
315 _edje_file_cache = eina_list_remove_list(_edje_file_cache, l);
316 eina_hash_add(_edje_file_hash, file, edf);
322 if (!_edje_file_hash)
323 _edje_file_hash = eina_hash_string_small_new(NULL);
325 edf = _edje_file_open(file, coll, error_ret, edc_ret, st.st_mtime);
330 if (ed) edf->edjes = eina_list_append(edf->edjes, ed);
335 eina_hash_add(_edje_file_hash, file, edf);
342 edc = _edje_file_coll_open(edf, coll);
345 *error_ret = EDJE_LOAD_ERROR_UNKNOWN_COLLECTION;
353 for (j = 0; j < edc->parts_count; ++j)
359 /* Register any color classes in this parts descriptions. */
361 hist = eina_list_append(hist, ep);
363 while (ep2->dragable.confine_id >= 0)
365 if (ep2->dragable.confine_id >= (int) edc->parts_count)
367 ERR("confine_to above limit. invalidating it.");
368 ep2->dragable.confine_id = -1;
372 ep2 = edc->parts[ep2->dragable.confine_id];
373 if (eina_list_data_find(hist, ep2))
375 ERR("confine_to loops. invalidating loop.");
376 ep2->dragable.confine_id = -1;
379 hist = eina_list_append(hist, ep2);
381 eina_list_free(hist);
383 hist = eina_list_append(hist, ep);
385 while (ep2->dragable.event_id >= 0)
389 if (ep2->dragable.event_id >= (int) edc->parts_count)
391 ERR("event_id above limit. invalidating it.");
392 ep2->dragable.event_id = -1;
397 ep2 = edc->parts[ep2->dragable.event_id];
398 if (!ep2->dragable.x && !ep2->dragable.y)
400 prev->dragable.event_id = -1;
404 if (eina_list_data_find(hist, ep2))
406 ERR("events_to loops. invalidating loop.");
407 ep2->dragable.event_id = -1;
410 hist = eina_list_append(hist, ep2);
412 eina_list_free(hist);
414 hist = eina_list_append(hist, ep);
416 while (ep2->clip_to_id >= 0)
418 if (ep2->clip_to_id >= (int) edc->parts_count)
420 ERR("clip_to_id above limit. invalidating it.");
421 ep2->clip_to_id = -1;
425 ep2 = edc->parts[ep2->clip_to_id];
426 if (eina_list_data_find(hist, ep2))
428 ERR("clip_to loops. invalidating loop.");
429 ep2->clip_to_id = -1;
432 hist = eina_list_append(hist, ep2);
434 eina_list_free(hist);
441 if (edc && ed) edf->edjes = eina_list_append(edf->edjes, ed);
446 if (edc_ret) *edc_ret = edc;
452 _edje_cache_coll_clean(Edje_File *edf)
454 while ((edf->collection_cache) &&
455 (eina_list_count(edf->collection_cache) > (unsigned int) _edje_collection_cache_size))
457 Edje_Part_Collection_Directory_Entry *ce;
458 Edje_Part_Collection *edc;
460 edc = eina_list_data_get(eina_list_last(edf->collection_cache));
461 edf->collection_cache = eina_list_remove_list(edf->collection_cache, eina_list_last(edf->collection_cache));
463 ce = eina_hash_find(edf->collection, edc->part);
464 _edje_collection_free(edf, edc, ce);
469 _edje_cache_coll_flush(Edje_File *edf)
471 while (edf->collection_cache)
473 Edje_Part_Collection_Directory_Entry *ce;
474 Edje_Part_Collection *edc;
477 last = eina_list_last(edf->collection_cache);
478 edc = eina_list_data_get(last);
479 edf->collection_cache = eina_list_remove_list(edf->collection_cache,
482 ce = eina_hash_find(edf->collection, edc->part);
483 _edje_collection_free(edf, edc, ce);
488 _edje_cache_coll_unref(Edje_File *edf, Edje_Part_Collection *edc)
490 Edje_Part_Collection_Directory_Entry *ce;
493 if (edc->references != 0) return;
495 ce = eina_hash_find(edf->collection, edc->part);
498 ERR("Something is wrong with reference count of '%s'.", edc->part);
506 /* No need to keep the collection around if the file is dangling */
507 _edje_collection_free(edf, edc, ce);
508 _edje_cache_coll_flush(edf);
512 edf->collection_cache = eina_list_prepend(edf->collection_cache, edc);
513 _edje_cache_coll_clean(edf);
519 _edje_cache_file_clean(void)
523 count = eina_list_count(_edje_file_cache);
524 while ((_edje_file_cache) && (count > _edje_file_cache_size))
529 last = eina_list_last(_edje_file_cache);
530 edf = eina_list_data_get(last);
531 _edje_file_cache = eina_list_remove_list(_edje_file_cache, last);
532 _edje_file_free(edf);
533 count = eina_list_count(_edje_file_cache);
538 _edje_cache_file_unref(Edje_File *edf)
541 if (edf->references != 0) return;
545 _edje_file_free(edf);
549 eina_hash_del(_edje_file_hash, edf->path, edf);
550 if (!eina_hash_population(_edje_file_hash))
552 eina_hash_free(_edje_file_hash);
553 _edje_file_hash = NULL;
555 _edje_file_cache = eina_list_prepend(_edje_file_cache, edf);
556 _edje_cache_file_clean();
560 _edje_file_cache_shutdown(void)
562 edje_file_cache_flush();
566 /*============================================================================*
568 *============================================================================*/
570 /*============================================================================*
572 *============================================================================*/
576 edje_file_cache_set(int count)
578 if (count < 0) count = 0;
579 _edje_file_cache_size = count;
580 _edje_cache_file_clean();
585 edje_file_cache_get(void)
587 return _edje_file_cache_size;
592 edje_file_cache_flush(void)
596 ps = _edje_file_cache_size;
597 _edje_file_cache_size = 0;
598 _edje_cache_file_clean();
599 _edje_file_cache_size = ps;
604 edje_collection_cache_set(int count)
609 if (count < 0) count = 0;
610 _edje_collection_cache_size = count;
611 EINA_LIST_FOREACH(_edje_file_cache, l, edf)
612 _edje_cache_coll_clean(edf);
613 /* FIXME: freach in file hash too! */
618 edje_collection_cache_get(void)
620 return _edje_collection_cache_size;
625 edje_collection_cache_flush(void)
631 ps = _edje_collection_cache_size;
632 _edje_collection_cache_size = 0;
633 EINA_LIST_FOREACH(_edje_file_cache, l, edf)
634 _edje_cache_coll_flush(edf);
635 /* FIXME: freach in file hash too! */
636 _edje_collection_cache_size = ps;