diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-06-28 17:00:18 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-06-28 17:01:35 -0300 |
commit | db3b05d2893dcaddeb3bcb10b845ff150eb50895 (patch) | |
tree | e19d761357300ba03360593e3cbdda01e87f215e /core | |
parent | 9e54e1f34f7ee0b100b45fa2388f25096eb90670 (diff) |
Reworked translation system
-Label and Button reload translation on the fly
-Resources are loaded and reload depending on locale
Diffstat (limited to 'core')
-rw-r--r-- | core/io/resource_format_binary.cpp | 7 | ||||
-rw-r--r-- | core/io/resource_format_binary.h | 2 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 159 | ||||
-rw-r--r-- | core/io/resource_loader.h | 14 | ||||
-rw-r--r-- | core/resource.cpp | 32 | ||||
-rw-r--r-- | core/resource.h | 7 | ||||
-rw-r--r-- | core/translation.cpp | 6 | ||||
-rw-r--r-- | core/variant_op.cpp | 2 |
8 files changed, 201 insertions, 28 deletions
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 0373176cd2..b474c2e078 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -689,6 +689,7 @@ Error ResourceInteractiveLoaderBinary::poll() { f->close(); resource = res; + resource->set_as_translation_remapped(translation_remapped); error = ERR_FILE_EOF; } else { @@ -706,6 +707,11 @@ int ResourceInteractiveLoaderBinary::get_stage_count() const { return external_resources.size() + internal_resources.size(); } +void ResourceInteractiveLoaderBinary::set_translation_remapped(bool p_remapped) { + + translation_remapped = p_remapped; +} + static void save_ustring(FileAccess *f, const String &p_string) { CharString utf8 = p_string.utf8(); @@ -920,6 +926,7 @@ ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() { endian_swap = false; use_real64 = false; error = OK; + translation_remapped = false; } ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() { diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 59b9d66d8f..5da5a0fc37 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -36,6 +36,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader { + bool translation_remapped; String local_path; String res_path; String type; @@ -87,6 +88,7 @@ public: virtual Error poll(); virtual int get_stage() const; virtual int get_stage_count() const; + virtual void set_translation_remapped(bool p_remapped); void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; } void open(FileAccess *p_f); diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 234d71cb68..bb7be38413 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -29,10 +29,12 @@ /*************************************************************************/ #include "resource_loader.h" #include "global_config.h" +#include "io/resource_import.h" #include "os/file_access.h" #include "os/os.h" #include "path_remap.h" #include "print_string.h" +#include "translation.h" ResourceFormatLoader *ResourceLoader::loader[MAX_LOADERS]; int ResourceLoader::loader_count = 0; @@ -102,6 +104,7 @@ public: virtual Error poll() { return ERR_FILE_EOF; } virtual int get_stage() const { return 1; } virtual int get_stage_count() const { return 1; } + virtual void set_translation_remapped(bool p_remapped) { resource->set_as_translation_remapped(p_remapped); } ResourceInteractiveLoaderDefault() {} }; @@ -165,38 +168,45 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p else local_path = GlobalConfig::get_singleton()->localize_path(p_path); - ERR_FAIL_COND_V(local_path == "", RES()); + bool xl_remapped = false; + String path = _path_remap(local_path, &xl_remapped); - if (!p_no_cache && ResourceCache::has(local_path)) { + ERR_FAIL_COND_V(path == "", RES()); + + if (!p_no_cache && ResourceCache::has(path)) { if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path + " (cached)"); + print_line("load resource: " + path + " (cached)"); - return RES(ResourceCache::get(local_path)); + return RES(ResourceCache::get(path)); } if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path); + print_line("load resource: " + path); bool found = false; // Try all loaders and pick the first match for the type hint for (int i = 0; i < loader_count; i++) { - if (!loader[i]->recognize_path(local_path, p_type_hint)) { + if (!loader[i]->recognize_path(path, p_type_hint)) { continue; } found = true; - RES res = loader[i]->load(local_path, local_path, r_error); + RES res = loader[i]->load(path, path, r_error); if (res.is_null()) { continue; } if (!p_no_cache) res->set_path(local_path); + + if (xl_remapped) + res->set_as_translation_remapped(true); + #ifdef TOOLS_ENABLED res->set_edited(false); if (timestamp_on_load) { - uint64_t mt = FileAccess::get_modified_time(local_path); + uint64_t mt = FileAccess::get_modified_time(path); //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt); res->set_last_modified_time(mt); } @@ -206,9 +216,9 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p } if (found) { - ERR_EXPLAIN("Failed loading resource: " + p_path); + ERR_EXPLAIN("Failed loading resource: " + path); } else { - ERR_EXPLAIN("No loader found for resource: " + p_path); + ERR_EXPLAIN("No loader found for resource: " + path); } ERR_FAIL_V(RES()); return RES(); @@ -225,14 +235,17 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ else local_path = GlobalConfig::get_singleton()->localize_path(p_path); - ERR_FAIL_COND_V(local_path == "", Ref<ResourceInteractiveLoader>()); + bool xl_remapped = false; + String path = _path_remap(local_path, &xl_remapped); + + ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>()); - if (!p_no_cache && ResourceCache::has(local_path)) { + if (!p_no_cache && ResourceCache::has(path)) { if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path + " (cached)"); + print_line("load resource: " + path + " (cached)"); - Ref<Resource> res_cached = ResourceCache::get(local_path); + Ref<Resource> res_cached = ResourceCache::get(path); Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); ril->resource = res_cached; @@ -246,22 +259,24 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ for (int i = 0; i < loader_count; i++) { - if (!loader[i]->recognize_path(local_path, p_type_hint)) + if (!loader[i]->recognize_path(path, p_type_hint)) continue; found = true; - Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(local_path, r_error); + Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, r_error); if (ril.is_null()) continue; if (!p_no_cache) ril->set_local_path(local_path); + if (xl_remapped) + ril->set_translation_remapped(true); return ril; } if (found) { - ERR_EXPLAIN("Failed loading resource: " + p_path); + ERR_EXPLAIN("Failed loading resource: " + path); } else { - ERR_EXPLAIN("No loader found for resource: " + p_path); + ERR_EXPLAIN("No loader found for resource: " + path); } ERR_FAIL_V(Ref<ResourceInteractiveLoader>()); return Ref<ResourceInteractiveLoader>(); @@ -283,11 +298,13 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { + String path = _path_remap(p_path); + String local_path; - if (p_path.is_rel_path()) - local_path = "res://" + p_path; + if (path.is_rel_path()) + local_path = "res://" + path; else - local_path = GlobalConfig::get_singleton()->localize_path(p_path); + local_path = GlobalConfig::get_singleton()->localize_path(path); for (int i = 0; i < loader_count; i++) { @@ -304,11 +321,13 @@ void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_depe Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) { + String path = _path_remap(p_path); + String local_path; - if (p_path.is_rel_path()) - local_path = "res://" + p_path; + if (path.is_rel_path()) + local_path = "res://" + path; else - local_path = GlobalConfig::get_singleton()->localize_path(p_path); + local_path = GlobalConfig::get_singleton()->localize_path(path); for (int i = 0; i < loader_count; i++) { @@ -342,6 +361,95 @@ String ResourceLoader::get_resource_type(const String &p_path) { return ""; } + +String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) { + + if (translation_remaps.has(p_path)) { + + Vector<String> &v = *translation_remaps.getptr(p_path); + String locale = TranslationServer::get_singleton()->get_locale(); + if (r_translation_remapped) { + *r_translation_remapped = true; + } + for (int i = 0; i < v.size(); i++) { + + int split = v[i].find_last(":"); + if (split == -1) + continue; + String l = v[i].right(split + 1).strip_edges(); + if (l == String()) + continue; + + if (l.begins_with(locale)) { + return v[i].left(split); + } + } + } + + return p_path; +} + +String ResourceLoader::import_remap(const String &p_path) { + + if (ResourceFormatImporter::get_singleton()->recognize_path(p_path)) { + + return ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_path); + } + + return p_path; +} + +String ResourceLoader::path_remap(const String &p_path) { + return _path_remap(p_path); +} + +void ResourceLoader::reload_translation_remaps() { + + if (ResourceCache::lock) { + ResourceCache::lock->read_lock(); + } + + List<Resource *> to_reload; + SelfList<Resource> *E = remapped_list.first(); + + while (E) { + to_reload.push_back(E->self()); + E = E->next(); + } + + if (ResourceCache::lock) { + ResourceCache::lock->read_unlock(); + } + + //now just make sure to not delete any of these resources while changing locale.. + while (to_reload.front()) { + to_reload.front()->get()->reload_from_file(); + to_reload.pop_front(); + } +} + +void ResourceLoader::load_translation_remaps() { + + Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps"); + List<Variant> keys; + remaps.get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + + Array langs = remaps[E->get()]; + Vector<String> lang_remaps; + lang_remaps.resize(langs.size()); + for (int i = 0; i < langs.size(); i++) { + lang_remaps[i] = langs[i]; + } + + translation_remaps[String(E->get())] = lang_remaps; + } +} + +void ResourceLoader::clear_translation_remaps() { + translation_remaps.clear(); +} + ResourceLoadErrorNotify ResourceLoader::err_notify = NULL; void *ResourceLoader::err_notify_ud = NULL; @@ -350,3 +458,6 @@ void *ResourceLoader::dep_err_notify_ud = NULL; bool ResourceLoader::abort_on_missing_resource = true; bool ResourceLoader::timestamp_on_load = false; + +SelfList<Resource>::List ResourceLoader::remapped_list; +HashMap<String, Vector<String> > ResourceLoader::translation_remaps; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 54b62f6916..e6687800d7 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -49,6 +49,7 @@ public: virtual Error poll() = 0; virtual int get_stage() const = 0; virtual int get_stage_count() const = 0; + virtual void set_translation_remapped(bool p_remapped) = 0; virtual Error wait(); ResourceInteractiveLoader() {} @@ -87,6 +88,12 @@ class ResourceLoader { static void *dep_err_notify_ud; static DependencyErrorNotify dep_err_notify; static bool abort_on_missing_resource; + static HashMap<String, Vector<String> > translation_remaps; + + static String _path_remap(const String &p_path, bool *r_translation_remapped = NULL); + friend class Resource; + + static SelfList<Resource>::List remapped_list; public: static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL); @@ -118,6 +125,13 @@ public: static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource = p_abort; } static bool get_abort_on_missing_resources() { return abort_on_missing_resource; } + + static String path_remap(const String &p_path); + static String import_remap(const String &p_path); + + static void reload_translation_remaps(); + static void load_translation_remaps(); + static void clear_translation_remaps(); }; #endif diff --git a/core/resource.cpp b/core/resource.cpp index 559d4c1201..a7a5498ef6 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -31,9 +31,9 @@ #include "core_string_names.h" #include "io/resource_loader.h" +#include "io/resource_loader.h" #include "os/file_access.h" #include "script_language.h" - #include <stdio.h> void Resource::emit_changed() { @@ -127,7 +127,7 @@ void Resource::reload_from_file() { if (!path.is_resource_file()) return; - Ref<Resource> s = ResourceLoader::load(path, get_class(), true); + Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), true); if (!s.is_valid()) return; @@ -302,6 +302,31 @@ void Resource::setup_local_to_scene() { Node *(*Resource::_get_local_scene_func)() = NULL; +void Resource::set_as_translation_remapped(bool p_remapped) { + + if (remapped_list.in_list() == p_remapped) + return; + + if (ResourceCache::lock) { + ResourceCache::lock->write_lock(); + } + + if (p_remapped) { + ResourceLoader::remapped_list.add(&remapped_list); + } else { + ResourceLoader::remapped_list.remove(&remapped_list); + } + + if (ResourceCache::lock) { + ResourceCache::lock->write_unlock(); + } +} + +bool Resource::is_translation_remapped() const { + + return remapped_list.in_list(); +} + void Resource::_bind_methods() { ClassDB::bind_method(D_METHOD("set_path", "path"), &Resource::_set_path); @@ -325,7 +350,8 @@ void Resource::_bind_methods() { BIND_VMETHOD(MethodInfo("_setup_local_to_scene")); } -Resource::Resource() { +Resource::Resource() + : remapped_list(this) { #ifdef TOOLS_ENABLED last_modified_time = 0; diff --git a/core/resource.h b/core/resource.h index 903edeff52..5a4e45da36 100644 --- a/core/resource.h +++ b/core/resource.h @@ -35,6 +35,7 @@ #include "ref_ptr.h" #include "reference.h" #include "safe_refcount.h" +#include "self_list.h" /** @author Juan Linietsky <reduzio@gmail.com> @@ -74,6 +75,8 @@ class Resource : public Reference { friend class SceneState; Node *local_scene; + SelfList<Resource> remapped_list; + protected: void emit_changed(); @@ -127,6 +130,9 @@ public: #endif + void set_as_translation_remapped(bool p_remapped); + bool is_translation_remapped() const; + virtual RID get_rid() const; // some resources may offer conversion to RID Resource(); @@ -137,6 +143,7 @@ typedef Ref<Resource> RES; class ResourceCache { friend class Resource; + friend class ResourceLoader; //need the lock static RWLock *lock; static HashMap<String, Resource *> resources; friend void unregister_core_types(); diff --git a/core/translation.cpp b/core/translation.cpp index bd670167f9..72231ef295 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -870,6 +870,10 @@ void Translation::set_locale(const String &p_locale) { } else { locale = univ_locale; } + + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); + } } void Translation::add_message(const StringName &p_src_text, const StringName &p_xlated_text) { @@ -945,6 +949,8 @@ void TranslationServer::set_locale(const String &p_locale) { if (OS::get_singleton()->get_main_loop()) { OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); } + + ResourceLoader::reload_translation_remaps(); } String TranslationServer::get_locale() const { diff --git a/core/variant_op.cpp b/core/variant_op.cpp index a463a5a23f..c4dee5c8a4 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -2148,7 +2148,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { } break; // 10 case RECT3: { - p_list->push_back(PropertyInfo(Variant::VECTOR3, "pos")); + p_list->push_back(PropertyInfo(Variant::VECTOR3, "position")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "size")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "end")); } break; |