nikawhite pushed a commit to branch master. http://git.enlightenment.org/tools/eflete.git/commit/?id=9791064d0f7b31da229259db72dab1fea2959955
commit 9791064d0f7b31da229259db72dab1fea2959955 Author: Mykyta Biliavskyi <m.biliavs...@samsung.com> Date: Tue Aug 9 14:46:25 2016 +0300 Project manager: add submodule for export resources. Submodule project_manager_export_resources provide functionality for export resources (like images, sounds, styles etc.) from binary file onto disk. For each resource type new thread is started. That maked for make lighter main loop, which makes animation for UI. --- src/bin/Makefile.am | 1 + src/bin/project_manager/project_manager.c | 453 +++++------------- .../project_manager_export_resources.c | 524 +++++++++++++++++++++ .../project_manager/project_manager_import_edj.c | 6 +- src/bin/project_manager/project_manager_open.c | 3 +- src/bin/project_manager/project_manager_private.h | 25 +- 6 files changed, 667 insertions(+), 345 deletions(-) diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 7034a0f..f8cb0cd 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -67,6 +67,7 @@ libete_a_SOURCES = \ ../../src/bin/project_manager/project_manager.c \ ../../src/bin/project_manager/project_manager_open.c \ ../../src/bin/project_manager/project_manager_import_edj.c \ +../../src/bin/project_manager/project_manager_export_resources.c \ ../../src/bin/project_manager/resource_manager.c \ ../../src/bin/logger/logger.c \ ../../src/bin/config/config.c \ diff --git a/src/bin/project_manager/project_manager.c b/src/bin/project_manager/project_manager.c index 0957200..1d853d0 100644 --- a/src/bin/project_manager/project_manager.c +++ b/src/bin/project_manager/project_manager.c @@ -91,24 +91,6 @@ static Project_Thread worker; } static Eina_Bool -_image_resources_load(Project *project); - -static Eina_Bool -_sound_resources_load(Project *project); - -static Eina_Bool -_font_resources_load(Project *project); - -static void -_tones_resources_load(Project *project); - -static void -_colorclasses_resources_load(Project *project); - -static void -_styles_resources_load(Project *project); - -static Eina_Bool _project_dev_file_create(Project *pro) { Eina_Bool result; @@ -190,17 +172,28 @@ _progress_send(void *data) } void -_end_send(void *data __UNUSED__) +_end_send(void *data) { PM_Project_End_Cb func; + Project_Thread *ptd = (Project_Thread *)data; PM_Project_Result result; void *udata; /** Copy the links to callback and meesage, to fast release worker resource. */ - worker.func_progress = NULL; - func = worker.func_end; - result = worker.result; - udata = worker.data; + func = ptd->func_end; + result = ptd->result; + udata = ptd->data; + ecore_event_handler_del(ptd->del_handler); + ecore_event_handler_del(ptd->error_handler); + ecore_event_handler_del(ptd->data_handler); + + if (ptd->tmp_dirname != NULL) + { + ecore_file_recursive_rm(ptd->tmp_dirname); + eina_tmpstr_del(ptd->tmp_dirname); + } + + free(ptd); func(udata, result); } @@ -242,6 +235,60 @@ exit: return res; } +void +_gm_group_load_cancel_cb(void *data, + Ecore_Thread *th __UNUSED__) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + ecore_thread_global_data_del("ptd"); + edje_file_cache_flush(); + ptd->result = PM_PROJECT_ERROR; + ERR("Failed to load group tree."); + + eina_lock_release(&ftd->mutex); + TODO("Remove static worker from this module"); + worker.project = ptd->project; + free(ftd); + _end_send(ptd); +} + +void +_gm_group_load_end_cb(void *data, + Ecore_Thread *th __UNUSED__) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + ecore_thread_global_data_del("ptd"); + edje_file_cache_flush(); + ptd->result = PM_PROJECT_SUCCESS; + + eina_lock_release(&ftd->mutex); + TODO("Remove static worker from this module"); + worker.project = ptd->project; + free(ftd); + _end_send(ptd); +} + +void +_gm_group_load_feedback_job(void *data, Ecore_Thread *th) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + if (!eina_lock_take(&ftd->mutex)) + { + ERR("Failed access data"); + ecore_thread_cancel(th); + return; + } + Project *project = (Project *) ptd->project; + + Eina_Stringshare *message = eina_stringshare_printf(_("Load group tree")); + ecore_thread_feedback(th, message); + + gm_groups_load(project); +} + #define MKDIR(NAME) \ tmp = eina_stringshare_printf("%s/"#NAME, pro->develop_path); \ ecore_file_mkdir(tmp); \ @@ -351,9 +398,10 @@ _project_edj_file_copy(void) } void -_project_open_internal(Project *project) +_project_open_internal(Project_Thread *ptd) { - assert(project != NULL); + assert(ptd != NULL); + Project *project = ptd->project; _project_dev_file_create(project); project->mmap_file = eina_file_open(project->dev, false); @@ -364,16 +412,52 @@ _project_open_internal(Project *project) project->global_object = edje_edit_object_add(ecore_evas_get(project->ecore_evas)); edje_object_mmap_set(project->global_object, project->mmap_file, EFLETE_INTERNAL_GROUP_NAME); - _image_resources_load(project); - _sound_resources_load(project); - _font_resources_load(project); - _tones_resources_load(project); - _colorclasses_resources_load(project); - _styles_resources_load(project); + Feedback_Thread_Data *ftd; + ftd = mem_calloc(1, sizeof(Feedback_Thread_Data)); + ftd->queue = 6; + eina_lock_new(&ftd->mutex); + ecore_thread_global_data_add("ptd", ptd, NULL, false); + /* Launch images load inside thread with feedback */ + ecore_thread_feedback_run(_image_resources_feedback_job, _resources_export_feedback_cb, + _resources_export_end_cb, _resources_export_cancel_cb, ftd, + true); - gm_groups_load(project); + /*------------------------------------------------*/ - edje_file_cache_flush(); + /* Launch sound load inside thread with feedback */ + ecore_thread_feedback_run(_sound_resources_feedback_job, _resources_export_feedback_cb, + _resources_export_end_cb, _resources_export_cancel_cb, ftd, + true); + + /*------------------------------------------------*/ + + /* Launch font load inside thread with feedback */ + ecore_thread_feedback_run(_font_resources_feedback_job, _resources_export_feedback_cb, + _resources_export_end_cb, _resources_export_cancel_cb, ftd, + true); + + /*------------------------------------------------*/ + + /* Launch tones load inside thread with feedback */ + ecore_thread_feedback_run(_tones_resources_feedback_job, _resources_export_feedback_cb, + _resources_export_end_cb, _resources_export_cancel_cb, ftd, + true); + + /*------------------------------------------------*/ + + /* Launch colorclasses load inside thread with feedback */ + ecore_thread_feedback_run(_colorclasses_resources_feedback_job, _resources_export_feedback_cb, + _resources_export_end_cb, _resources_export_cancel_cb, ftd, + true); + + /*------------------------------------------------*/ + + /* Launch colorclasses load inside thread with feedback */ + ecore_thread_feedback_run(_styles_resources_feedback_job, _resources_export_feedback_cb, + _resources_export_end_cb, _resources_export_cancel_cb, ftd, + true); + + /*------------------------------------------------*/ } void @@ -833,309 +917,6 @@ pm_project_meta_data_set(Project *project, return res; } -static Eina_Bool -_image_resources_load(Project *project) -{ - External_Resource *res; - Eina_List *images; - Eina_Stringshare *resource_folder; - Eina_Stringshare *image_name, *source_file; - Eina_List *l; - Evas *e; - Evas_Object *im; - int id; - char *file_dir; - int im_total, im_proc; - - assert(project != NULL); - - resource_folder = eina_stringshare_printf("%s/images", project->develop_path); - ecore_file_recursive_rm(resource_folder); - - if (!ecore_file_mkpath(resource_folder)) - { - ERR("Failed create path %s for export images", resource_folder); - eina_stringshare_del(resource_folder); - return false; - } - - images = edje_edit_images_list_get(project->global_object); - - e = ecore_evas_get(project->ecore_evas); - im_total = eina_list_count(images); - im_proc = 0; - Edje_Edit_Image_Comp comp_type; - PROGRESS_SEND(_("Start image processing, total %d:"), im_total); - EINA_LIST_FOREACH(images, l, image_name) - { - /* for supporting old themes, which were compilled - * with edje_cc version less than 1.10 */ - if (!image_name) continue; - - im_proc++; - PROGRESS_SEND(_("image processing (%d/%d): %s"), - im_proc, im_total, image_name); - - res = (External_Resource *) resource_add(image_name, RESOURCE_TYPE_IMAGE); - comp_type = edje_edit_image_compression_type_get(project->global_object, - res->name); - if (comp_type == EDJE_EDIT_IMAGE_COMP_USER) - res->source = eina_stringshare_add(image_name); - else - res->source = eina_stringshare_printf("%s/%s", resource_folder, image_name); - resource_insert(&project->images, (Resource *)res); - - if (!ecore_file_exists(res->source)) - { - file_dir = ecore_file_dir_get(res->source); - ecore_file_mkpath(file_dir); - free(file_dir); - THREAD_CONTEXT_SWITCH_BEGIN; - im = evas_object_image_add(e); - id = edje_edit_image_id_get(project->global_object, image_name); - if (id < 0) - { - WARN("Image %s coudn't be exported", image_name); - THREAD_CONTEXT_SWITCH_END; - continue; - } - source_file = eina_stringshare_printf("edje/images/%i", id); - evas_object_image_file_set(im, project->dev, source_file); - THREAD_CONTEXT_SWITCH_END; - evas_object_image_save(im, res->source, NULL, NULL); - THREAD_CONTEXT_SWITCH_BEGIN; - evas_object_del(im); - eina_stringshare_del(source_file); - THREAD_CONTEXT_SWITCH_END; - } - } - - edje_edit_string_list_free(images); - eina_stringshare_del(resource_folder); - return true; -} - -static Eina_Bool -_sound_resources_load(Project *project) -{ - External_Resource *res; - Eina_List *sounds; - Eina_Stringshare *resource_folder; - Eina_Stringshare *sound_name, *sound_file; - Eina_List *l; - Eina_Binbuf *sound_bin; - FILE *f; - char *file_dir; - int snd_total, snd_proc; - - assert(project != NULL); - - resource_folder = eina_stringshare_printf("%s/sounds", project->develop_path); - ecore_file_recursive_rm(resource_folder); - - if (!ecore_file_mkpath(resource_folder)) - { - ERR("Failed create path %s for export sounds", resource_folder); - eina_stringshare_del(resource_folder); - return false; - } - - sounds = edje_edit_sound_samples_list_get(project->global_object); - - snd_total = eina_list_count(sounds); - snd_proc = 0; - PROGRESS_SEND(_("Start sound processing: total %d:"), snd_total); - EINA_LIST_FOREACH(sounds, l, sound_name) - { - sound_file = edje_edit_sound_samplesource_get(project->global_object, sound_name); - snd_proc++; - PROGRESS_SEND(_("sound processing (%d/%d): %s"), - snd_proc, snd_total, sound_file); - - res = (External_Resource*)resource_add(sound_name, RESOURCE_TYPE_SOUND); - res->source = eina_stringshare_printf("%s/%s", resource_folder, sound_file); - resource_insert(&project->sounds, (Resource *)res); - - if (!ecore_file_exists(res->source)) - { - file_dir = ecore_file_dir_get(res->source); - ecore_file_mkpath(file_dir); - free(file_dir); - sound_bin = edje_edit_sound_samplebuffer_get(project->global_object, sound_name); - if (!(f = fopen(res->source, "wb"))) - { - ERR("Could not open file: %s", res->source); - continue; - } - if (fwrite(eina_binbuf_string_get(sound_bin), - eina_binbuf_length_get(sound_bin), 1, f) != 1) - ERR("Could not write sound: %s", strerror(errno)); - if (f) fclose(f); - eina_binbuf_free(sound_bin); - } - edje_edit_string_free(sound_file); - } - - edje_edit_string_list_free(sounds); - eina_stringshare_del(resource_folder); - return true; -} - -static Eina_Bool -_font_resources_load(Project *project) -{ - External_Resource *res; - Eina_List *fonts; - Eina_Stringshare *resource_folder; - Eet_File *ef; - Eina_List *l; - Eina_Stringshare *font_name, *font_file; - void *font; - FILE *f; - int size, fnt_total, fnt_proc; - - assert(project != NULL); - - resource_folder = eina_stringshare_printf("%s/fonts", project->develop_path); - ecore_file_recursive_rm(resource_folder); - - if (!ecore_file_mkpath(resource_folder)) - { - ERR("Failed create path %s for export fonts", resource_folder); - eina_stringshare_del(resource_folder); - return false; - } - - fonts = edje_edit_fonts_list_get(project->global_object); - - ef = eet_open(project->dev, EET_FILE_MODE_READ); - fnt_total = eina_list_count(fonts); - fnt_proc = 0; - PROGRESS_SEND(_("Start font processing, total %d:"), fnt_total); - EINA_LIST_FOREACH(fonts, l, font_name) - { - font_file = edje_edit_font_path_get(project->global_object, font_name); - fnt_proc++; - PROGRESS_SEND(_("font processing (%d/%d): %s"), - fnt_proc, fnt_total, font_file); - - res = (External_Resource *)resource_add(font_file, RESOURCE_TYPE_FONT); - res->source = eina_stringshare_printf("%s/%s", resource_folder, font_file); - resource_insert(&project->fonts, (Resource *)res); - - if (!ecore_file_exists(res->source)) - { - edje_edit_string_free(font_file); - font_file = eina_stringshare_printf("edje/fonts/%s", font_name); - font = eet_read(ef, font_file, &size); - if (!font) continue; - if (!(f = fopen(res->source, "wb"))) - { - ERR("Could not open file: %s", res->source); - continue; - } - if (fwrite(font, size, 1, f) != 1) - ERR("Could not write font: %s", strerror(errno)); - if (f) fclose(f); - free(font); - eina_stringshare_del(font_file); - } - } - eet_close(ef); - edje_edit_string_list_free(fonts); - eina_stringshare_del(resource_folder); - return true; -} - -static void -_tones_resources_load(Project *project) -{ - Eina_List *tones, *l; - Tone_Resource *res; - Eina_Stringshare *name; - int tones_total, tones_proc = 0; - - assert(project != NULL); - - tones = edje_edit_sound_tones_list_get(project->global_object); - tones_total = eina_list_count(tones); - - PROGRESS_SEND(_("Start tone processing, total %d:"), tones_total); - EINA_LIST_FOREACH(tones, l, name) - { - PROGRESS_SEND(_("tone processing (%d/%d): %s"), - ++tones_proc, tones_total, name); - - res = (Tone_Resource *)resource_add(name, RESOURCE_TYPE_TONE); - res->freq = edje_edit_sound_tone_frequency_get(project->global_object, name); - resource_insert(&project->tones, (Resource *)res); - } - - edje_edit_string_list_free(tones); -} - -static void -_colorclasses_resources_load(Project *project) -{ - Eina_List *colorclasses, *l; - Colorclass_Resource *res; - Eina_Stringshare *name; - int cc_total, cc_proc = 0; - - assert(project != NULL); - - colorclasses = edje_edit_color_classes_list_get(project->global_object); - cc_total = eina_list_count(colorclasses); - - PROGRESS_SEND(_("Start colorclass processing, total %d:"), cc_total); - EINA_LIST_FOREACH(colorclasses, l, name) - { - PROGRESS_SEND(_("colorclass processing (%d/%d): %s"), - ++cc_proc, cc_total, name); - - res = (Colorclass_Resource *)resource_add(name, RESOURCE_TYPE_COLORCLASS); - - if (!edje_edit_color_class_colors_get(project->global_object, name, - &res->color1.r, &res->color1.g, &res->color1.b, &res->color1.a, - &res->color2.r, &res->color2.g, &res->color2.b, &res->color2.a, - &res->color3.r, &res->color3.g, &res->color3.b, &res->color3.a)) - { - eina_stringshare_del(res->name); - resource_free((Resource *)res); - } - else - resource_insert(&project->colorclasses, (Resource *)res); - } - - edje_edit_string_list_free(colorclasses); -} - -static void -_styles_resources_load(Project *project) -{ - Eina_List *styles, *l; - Resource *res; - Eina_Stringshare *name; - int styles_total, styles_proc = 0; - - assert(project != NULL); - - styles = edje_edit_styles_list_get(project->global_object); - styles_total = eina_list_count(styles); - - PROGRESS_SEND(_("Start style processing, total %d:"), styles_total); - EINA_LIST_FOREACH(styles, l, name) - { - PROGRESS_SEND(_("style processing (%d/%d): %s"), - ++styles_proc, styles_total, name); - - res = resource_add(name, RESOURCE_TYPE_STYLE); - resource_insert(&project->styles, res); - } - - edje_edit_string_list_free(styles); -} - Eina_Bool pm_project_resource_export(Project *pro __UNUSED__, const char* dir_path __UNUSED__) { diff --git a/src/bin/project_manager/project_manager_export_resources.c b/src/bin/project_manager/project_manager_export_resources.c new file mode 100644 index 0000000..6fd9534 --- /dev/null +++ b/src/bin/project_manager/project_manager_export_resources.c @@ -0,0 +1,524 @@ +/* + * Efl Edje Theme Editor + * Copyright (C) 2013-2016 Samsung Electronics. + * + * This file is part of Edje Theme Editor. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see www.gnu.org/licenses/lgpl.html. + */ +#include "project_manager.h" +#include "project_manager_private.h" +/* --------------- Common functions ---------------------*/ +void +_resources_export_feedback_cb(void *data __UNUSED__, + Ecore_Thread *th __UNUSED__, + void *msg_data) +{ + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + Eina_Stringshare *message = (Eina_Stringshare *)msg_data; + assert(message != NULL); + assert(ptd != NULL); + + ptd->func_progress(NULL, message); + eina_stringshare_del(message); +} + +void +_resources_export_cancel_cb(void *data __UNUSED__, Ecore_Thread *th __UNUSED__) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + ecore_thread_global_data_del("ptd"); + ptd->result = PM_PROJECT_ERROR; + ERR("Failed to export resources."); + ptd->result = PM_PROJECT_ERROR; + free(ftd); + _end_send(ptd); +} + +void +_resources_export_end_cb(void *data __UNUSED__, Ecore_Thread *th __UNUSED__) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + + ftd->queue--; + if (ftd->queue != 0) + return; + + ecore_thread_feedback_run(_gm_group_load_feedback_job, _resources_export_feedback_cb, + _gm_group_load_end_cb, _gm_group_load_cancel_cb, ftd, + true); +} + +/* --------------- Export images ---------------------*/ +typedef struct +{ + Evas *e; + Evas_Object *im; + const char *id; + const char *dev; + const char *source; + Eina_Lock mutex; +} Image_Data_Save; + +static void* +_image_save_routine(void *data) +{ + Image_Data_Save *ids = (Image_Data_Save *)data; + eina_lock_take(&ids->mutex); + + ids->im = evas_object_image_add(ids->e); + evas_object_image_file_set(ids->im, ids->dev, ids->id); + eina_lock_release(&ids->mutex); + return NULL; +} + +void +_image_resources_feedback_job(void *data, Ecore_Thread *th) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + if (!eina_lock_take(&ftd->mutex)) + { + ERR("Failed access data"); + ecore_thread_cancel(th); + return; + } + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + Project *project = (Project *) ptd->project; + External_Resource *res; + Eina_List *images; + Eina_Stringshare *resource_folder; + Eina_Stringshare *image_name, *source_file; + Eina_List *l; + Evas *e; + int id; + char *file_dir; + int im_total, im_proc; + + assert(project != NULL); + + resource_folder = eina_stringshare_printf("%s/images", project->develop_path); + ecore_file_recursive_rm(resource_folder); + + if (!ecore_file_mkpath(resource_folder)) + { + ERR("Failed create path %s for export images", resource_folder); + eina_stringshare_del(resource_folder); + eina_lock_release(&ftd->mutex); + ecore_thread_cancel(th); + return; + } + + images = edje_edit_images_list_get(project->global_object); + + e = ecore_evas_get(project->ecore_evas); + im_total = eina_list_count(images); + im_proc = 0; + Edje_Edit_Image_Comp comp_type; + + Eina_Stringshare *message = eina_stringshare_printf(_("Start image processing, total %d:"), im_total); + ecore_thread_feedback(th, message); + + Image_Data_Save *ids = mem_calloc(1, sizeof(Image_Data_Save)); + ids->e = e; + ids->dev = project->dev; + eina_lock_new(&ids->mutex); + eina_lock_take(&ids->mutex); + EINA_LIST_FOREACH(images, l, image_name) + { + /* for supporting old themes, which were compilled + * with edje_cc version less than 1.10 */ + if (!image_name) continue; + + im_proc++; + + message = eina_stringshare_printf(_("image processing (%d/%d): %s"), im_proc, im_total, image_name); + ecore_thread_feedback(th, message); + + res = (External_Resource *) resource_add(image_name, RESOURCE_TYPE_IMAGE); + comp_type = edje_edit_image_compression_type_get(project->global_object, + res->name); + if (comp_type == EDJE_EDIT_IMAGE_COMP_USER) + res->source = eina_stringshare_add(image_name); + else + res->source = eina_stringshare_printf("%s/%s", resource_folder, image_name); + resource_insert(&project->images, (Resource *)res); + + if (!ecore_file_exists(res->source)) + { + file_dir = ecore_file_dir_get(res->source); + ecore_file_mkpath(file_dir); + free(file_dir); + id = edje_edit_image_id_get(project->global_object, image_name); + if (id < 0) + { + message = eina_stringshare_printf(_("Image %s coudn't be exported"), image_name); + ecore_thread_feedback(th, message); + WARN("Image %s coudn't be exported", image_name); + sleep(2); + continue; + } + source_file = eina_stringshare_printf("edje/images/%i", id); + ids->id = source_file; + ids->im = NULL; + ids->source = res->source; + eina_lock_release(&ids->mutex); + ecore_main_loop_thread_safe_call_sync(_image_save_routine, ids); + eina_lock_take(&ids->mutex); + evas_object_image_save(ids->im, res->source, NULL, NULL); + evas_object_del(ids->im); + eina_stringshare_del(source_file); + } + } + eina_lock_release(&ids->mutex); + eina_lock_free(&ids->mutex); + free(ids); + + edje_edit_string_list_free(images); + eina_stringshare_del(resource_folder); + eina_lock_release(&ftd->mutex); +} + + +/* --------------- Export sounds ---------------------*/ +void +_sound_resources_feedback_job(void *data, Ecore_Thread *th) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + if (!eina_lock_take(&ftd->mutex)) + { + ERR("Failed access data"); + ecore_thread_cancel(th); + return; + } + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + Project *project = (Project *) ptd->project; + External_Resource *res; + Eina_List *sounds; + Eina_Stringshare *resource_folder; + Eina_Stringshare *sound_name, *sound_file; + Eina_List *l; + Eina_Binbuf *sound_bin; + FILE *f; + char *file_dir; + int snd_total, snd_proc; + + assert(project != NULL); + + resource_folder = eina_stringshare_printf("%s/sounds", project->develop_path); + ecore_file_recursive_rm(resource_folder); + + if (!ecore_file_mkpath(resource_folder)) + { + ERR("Failed create path %s for export sounds", resource_folder); + eina_stringshare_del(resource_folder); + eina_lock_release(&ftd->mutex); + ecore_thread_cancel(th); + return; + } + + sounds = edje_edit_sound_samples_list_get(project->global_object); + + snd_total = eina_list_count(sounds); + snd_proc = 0; + Eina_Stringshare *message = eina_stringshare_printf(_("Start sound processing: total %d:"), snd_total); + ecore_thread_feedback(th, message); + + + EINA_LIST_FOREACH(sounds, l, sound_name) + { + sound_file = edje_edit_sound_samplesource_get(project->global_object, sound_name); + snd_proc++; + + message = eina_stringshare_printf(_("sound processing (%d/%d): %s"), snd_proc, snd_total, sound_file); + ecore_thread_feedback(th, message); + + res = (External_Resource*)resource_add(sound_name, RESOURCE_TYPE_SOUND); + res->source = eina_stringshare_printf("%s/%s", resource_folder, sound_file); + resource_insert(&project->sounds, (Resource *)res); + + if (!ecore_file_exists(res->source)) + { + file_dir = ecore_file_dir_get(res->source); + ecore_file_mkpath(file_dir); + free(file_dir); + sound_bin = edje_edit_sound_samplebuffer_get(project->global_object, sound_name); + if (!(f = fopen(res->source, "wb"))) + { + message = eina_stringshare_printf(_("Could not open file: %s"), res->source); + ecore_thread_feedback(th, message); + ERR("Could not open file: %s", res->source); + sleep(2); + continue; + } + if (fwrite(eina_binbuf_string_get(sound_bin), + eina_binbuf_length_get(sound_bin), 1, f) != 1) + ERR("Could not write sound: %s", strerror(errno)); + if (f) fclose(f); + eina_binbuf_free(sound_bin); + } + edje_edit_string_free(sound_file); + } + eina_lock_release(&ftd->mutex); + + edje_edit_string_list_free(sounds); + eina_stringshare_del(resource_folder); + return; +} + +/* --------------- Export fonts ---------------------*/ +void +_font_resources_feedback_job(void *data, Ecore_Thread *th) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + if (!eina_lock_take(&ftd->mutex)) + { + ERR("Failed access data"); + ecore_thread_cancel(th); + return; + } + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + Project *project = (Project *) ptd->project; + External_Resource *res; + Eina_List *fonts; + Eina_Stringshare *resource_folder; + Eet_File *ef; + Eina_List *l; + Eina_Stringshare *font_name, *font_file; + void *font; + FILE *f; + int size, fnt_total, fnt_proc; + + assert(project != NULL); + + resource_folder = eina_stringshare_printf("%s/fonts", project->develop_path); + ecore_file_recursive_rm(resource_folder); + + fonts = edje_edit_fonts_list_get(project->global_object); + + ef = eet_open(project->dev, EET_FILE_MODE_READ); + fnt_total = eina_list_count(fonts); + if (fnt_total == 0) + { + eina_condition_signal(&ftd->condition); + eina_lock_release(&ftd->mutex); + eet_close(ef); + edje_edit_string_list_free(fonts); + eina_stringshare_del(resource_folder); + return; + } + + if (!ecore_file_mkpath(resource_folder)) + { + ERR("Failed create path %s for export fonts", resource_folder); + eina_stringshare_del(resource_folder); + eina_lock_release(&ftd->mutex); + ecore_thread_cancel(th); + return; + } + + fnt_proc = 0; + Eina_Stringshare *message = eina_stringshare_printf(_("Start font processing, total %d:"), fnt_total); + ecore_thread_feedback(th, message); + + EINA_LIST_FOREACH(fonts, l, font_name) + { + font_file = edje_edit_font_path_get(project->global_object, font_name); + fnt_proc++; + message = eina_stringshare_printf(_("font processing (%d/%d): %s"), fnt_proc, fnt_total, font_file); + ecore_thread_feedback(th, message); + + res = (External_Resource *)resource_add(font_file, RESOURCE_TYPE_FONT); + res->source = eina_stringshare_printf("%s/%s", resource_folder, font_file); + resource_insert(&project->fonts, (Resource *)res); + + if (!ecore_file_exists(res->source)) + { + edje_edit_string_free(font_file); + font_file = eina_stringshare_printf("edje/fonts/%s", font_name); + font = eet_read(ef, font_file, &size); + if (!font) continue; + if (!(f = fopen(res->source, "wb"))) + { + message = eina_stringshare_printf(_("Could not open file: %s"), res->source); + ecore_thread_feedback(th, message); + ERR("Could not open file: %s", res->source); + sleep(2); + continue; + } + if (fwrite(font, size, 1, f) != 1) + ERR("Could not write font: %s", strerror(errno)); + if (f) fclose(f); + free(font); + eina_stringshare_del(font_file); + } + } + eet_close(ef); + edje_edit_string_list_free(fonts); + eina_stringshare_del(resource_folder); + eina_lock_release(&ftd->mutex); + return; +} + +/* --------------- Export tones ---------------------*/ +void +_tones_resources_feedback_job(void *data, Ecore_Thread *th) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + if (!eina_lock_take(&ftd->mutex)) + { + ERR("Failed access data"); + ecore_thread_cancel(th); + return; + } + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + Project *project = (Project *) ptd->project; + Eina_List *tones, *l; + Tone_Resource *res; + Eina_Stringshare *name; + int tones_total, tones_proc = 0; + + assert(project != NULL); + + tones = edje_edit_sound_tones_list_get(project->global_object); + tones_total = eina_list_count(tones); + + if (tones_total == 0) + { + eina_lock_release(&ftd->mutex); + edje_edit_string_list_free(tones); + return; + } + + Eina_Stringshare *message = eina_stringshare_printf(_("Start tone processing, total %d:"), tones_total); + ecore_thread_feedback(th, message); + + EINA_LIST_FOREACH(tones, l, name) + { + message = eina_stringshare_printf(_("tone processing (%d/%d): %s"), ++tones_proc, tones_total, name); + ecore_thread_feedback(th, message); + + res = (Tone_Resource *)resource_add(name, RESOURCE_TYPE_TONE); + res->freq = edje_edit_sound_tone_frequency_get(project->global_object, name); + resource_insert(&project->tones, (Resource *)res); + } + eina_lock_release(&ftd->mutex); + edje_edit_string_list_free(tones); + return; +} + +/* --------------- Export colorclasses ---------------------*/ +void +_colorclasses_resources_feedback_job(void *data, Ecore_Thread *th) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + if (!eina_lock_take(&ftd->mutex)) + { + ERR("Failed access data"); + ecore_thread_cancel(th); + return; + } + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + Project *project = (Project *) ptd->project; + Eina_List *colorclasses, *l; + Colorclass_Resource *res; + Eina_Stringshare *name; + int cc_total, cc_proc = 0; + + assert(project != NULL); + + colorclasses = edje_edit_color_classes_list_get(project->global_object); + cc_total = eina_list_count(colorclasses); + + if (cc_total == 0) + { + eina_lock_release(&ftd->mutex); + edje_edit_string_list_free(colorclasses); + return; + } + + Eina_Stringshare *message = eina_stringshare_printf(_("Start colorclass processing, total %d:"), cc_total); + ecore_thread_feedback(th, message); + + EINA_LIST_FOREACH(colorclasses, l, name) + { + message = eina_stringshare_printf(_("colorclass processing (%d/%d): %s"), ++cc_proc, cc_total, name); + ecore_thread_feedback(th, message); + + res = (Colorclass_Resource *)resource_add(name, RESOURCE_TYPE_COLORCLASS); + + if (!edje_edit_color_class_colors_get(project->global_object, name, + &res->color1.r, &res->color1.g, &res->color1.b, &res->color1.a, + &res->color2.r, &res->color2.g, &res->color2.b, &res->color2.a, + &res->color3.r, &res->color3.g, &res->color3.b, &res->color3.a)) + { + eina_stringshare_del(res->name); + resource_free((Resource *)res); + } + else + resource_insert(&project->colorclasses, (Resource *)res); + } + + edje_edit_string_list_free(colorclasses); + eina_lock_release(&ftd->mutex); + return; +} + +/* --------------- Export styles ---------------------*/ +void +_styles_resources_feedback_job(void *data, Ecore_Thread *th) +{ + Feedback_Thread_Data *ftd = (Feedback_Thread_Data *)data; + if (!eina_lock_take(&ftd->mutex)) + { + ERR("Failed access data"); + ecore_thread_cancel(th); + return; + } + Project_Thread *ptd = ecore_thread_global_data_find("ptd"); + Project *project = (Project *) ptd->project; + + Eina_List *styles, *l; + Resource *res; + Eina_Stringshare *name; + int styles_total, styles_proc = 0; + + assert(project != NULL); + + styles = edje_edit_styles_list_get(project->global_object); + styles_total = eina_list_count(styles); + + if (styles_total == 0) + { + eina_lock_release(&ftd->mutex); + edje_edit_string_list_free(styles); + return; + } + + Eina_Stringshare *message = eina_stringshare_printf(_("Start style processing, total %d:"), styles_total); + ecore_thread_feedback(th, message); + + EINA_LIST_FOREACH(styles, l, name) + { + message = eina_stringshare_printf(_("style processing (%d/%d): %s"), ++styles_proc, styles_total, name); + ecore_thread_feedback(th, message); + + res = resource_add(name, RESOURCE_TYPE_STYLE); + resource_insert(&project->styles, res); + } + + eina_lock_release(&ftd->mutex); + edje_edit_string_list_free(styles); + return; +} + diff --git a/src/bin/project_manager/project_manager_import_edj.c b/src/bin/project_manager/project_manager_import_edj.c index f1a0614..03d298a 100644 --- a/src/bin/project_manager/project_manager_import_edj.c +++ b/src/bin/project_manager/project_manager_import_edj.c @@ -67,8 +67,7 @@ _edje_pick_end_cb(void *data, _copy_meta_data_to_pro(); _project_special_group_add(ptd->project); _project_dummy_image_add(ptd->project); - /* Replace ptd->project with ptd */ - _project_open_internal(ptd->project); + _project_open_internal(ptd); ecore_file_unlink(ptd->source_edj); return ECORE_CALLBACK_DONE; @@ -187,8 +186,7 @@ _project_import_edj(void *data) _copy_meta_data_to_pro(); _project_special_group_add(ptd->project); _project_dummy_image_add(ptd->project); - /* Replace ptd->project with ptd */ - _project_open_internal(ptd->project); + _project_open_internal(ptd); msg = eina_stringshare_printf(_("Import finished. Project '%s' created"), ptd->project->name); ptd->func_progress(NULL, msg); diff --git a/src/bin/project_manager/project_manager_open.c b/src/bin/project_manager/project_manager_open.c index d8c14d5..79b7cb1 100644 --- a/src/bin/project_manager/project_manager_open.c +++ b/src/bin/project_manager/project_manager_open.c @@ -36,8 +36,7 @@ void _project_open_end_cb(void *data, Ecore_Thread *th __UNUSED__) { Project_Thread *ptd = (Project_Thread *)data; - /* Will replace with direct ptd pointer */ - _project_open_internal(ptd->project); + _project_open_internal(ptd); } void diff --git a/src/bin/project_manager/project_manager_private.h b/src/bin/project_manager/project_manager_private.h index ae5bb1f..425c5fa 100644 --- a/src/bin/project_manager/project_manager_private.h +++ b/src/bin/project_manager/project_manager_private.h @@ -96,6 +96,11 @@ typedef struct void *data; } Edje_Exe_Data; +typedef struct { + int queue; + Eina_Lock mutex; + Eina_Condition condition; +} Feedback_Thread_Data; /* General funcions */ @@ -117,10 +122,8 @@ void _pm_project_descriptor_shutdown(Project_Thread *ptd); * Create global edje_edit object. * Create and load all resource files. * Load Group tree structure. - * - * @param project - allocated structure that will be filled by valid data. */ -void _project_open_internal(Project *project); +void _project_open_internal(Project_Thread *ptd); /* Try to lock *.pro file for avoid situations when two or more * instances of Eflete works with the same project in the same time. @@ -159,6 +162,22 @@ void _copy_meta_data_to_pro(void); */ Project *_project_files_create(Project_Thread *ptd); +/*------- Group tree load functions ---------*/ +void _gm_group_load_cancel_cb(void *data, Ecore_Thread *th); +void _gm_group_load_end_cb(void *data, Ecore_Thread *th); +void _gm_group_load_feedback_job(void *data, Ecore_Thread *th); + +/*------- Export resources functions --------*/ +void _image_resources_feedback_job(void *data, Ecore_Thread *th); +void _sound_resources_feedback_job(void *data, Ecore_Thread *th); +void _font_resources_feedback_job(void *data, Ecore_Thread *th); +void _tones_resources_feedback_job(void *data, Ecore_Thread *th); +void _colorclasses_resources_feedback_job(void *data, Ecore_Thread *th); +void _styles_resources_feedback_job(void *data, Ecore_Thread *th); +void _resources_export_end_cb(void *data, Ecore_Thread *th); +void _resources_export_feedback_cb(void *data, Ecore_Thread *th, void *msg_data); +void _resources_export_cancel_cb(void *data, Ecore_Thread *th); + /*------- Open Project functions --------*/ void _project_open_cancel_cb(void *data, Ecore_Thread *th); --