summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2017-06-28 17:00:18 -0300
committerJuan Linietsky <reduzio@gmail.com>2017-06-28 17:01:35 -0300
commitdb3b05d2893dcaddeb3bcb10b845ff150eb50895 (patch)
treee19d761357300ba03360593e3cbdda01e87f215e /core
parent9e54e1f34f7ee0b100b45fa2388f25096eb90670 (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.cpp7
-rw-r--r--core/io/resource_format_binary.h2
-rw-r--r--core/io/resource_loader.cpp159
-rw-r--r--core/io/resource_loader.h14
-rw-r--r--core/resource.cpp32
-rw-r--r--core/resource.h7
-rw-r--r--core/translation.cpp6
-rw-r--r--core/variant_op.cpp2
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;