aboutsummaryrefslogtreecommitdiff
path: root/extension
diff options
context:
space:
mode:
author Hop311 <Hop3114@gmail.com>2023-03-30 15:04:58 +0200
committer GitHub <noreply@github.com>2023-03-30 15:04:58 +0200
commit3384b21177a160f7192a2e4877eea3b29880bf4e (patch)
treedb9c9a37a187e15ef494a700f8afe5d65c3a8b78 /extension
parent8f213935bdea2400b6809f9d5db45dde3416dedc (diff)
Added Localisation (#77)
* Added Localisation * Removed `.gdignore`s. * Localisation dir path and Locale name cleanup * Incomplete entry warnings + README
Diffstat (limited to 'extension')
-rw-r--r--extension/src/LoadLocalisation.cpp111
-rw-r--r--extension/src/LoadLocalisation.hpp29
-rw-r--r--extension/src/register_types.cpp9
3 files changed, 149 insertions, 0 deletions
diff --git a/extension/src/LoadLocalisation.cpp b/extension/src/LoadLocalisation.cpp
new file mode 100644
index 0000000..c95c08b
--- /dev/null
+++ b/extension/src/LoadLocalisation.cpp
@@ -0,0 +1,111 @@
+#include "LoadLocalisation.hpp"
+
+#include <godot_cpp/variant/utility_functions.hpp>
+#include <godot_cpp/classes/file_access.hpp>
+#include <godot_cpp/classes/dir_access.hpp>
+#include <godot_cpp/classes/translation_server.hpp>
+
+using namespace godot;
+using namespace OpenVic2;
+
+LoadLocalisation *LoadLocalisation::singleton = nullptr;
+
+void LoadLocalisation::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load_file", "file_path", "locale"), &LoadLocalisation::load_file);
+ ClassDB::bind_method(D_METHOD("load_locale_dir", "dir_path", "locale"), &LoadLocalisation::load_locale_dir);
+ ClassDB::bind_method(D_METHOD("load_localisation_dir", "dir_path"), &LoadLocalisation::load_localisation_dir);
+}
+
+LoadLocalisation *LoadLocalisation::get_singleton() {
+ return singleton;
+}
+
+LoadLocalisation::LoadLocalisation() {
+ ERR_FAIL_COND(singleton != nullptr);
+ singleton = this;
+}
+
+LoadLocalisation::~LoadLocalisation() {
+ ERR_FAIL_COND(singleton != this);
+ singleton = nullptr;
+}
+
+Error LoadLocalisation::_load_file_into_translation(String const& file_path, Ref<Translation> translation) {
+ Ref<FileAccess> file = FileAccess::open(file_path, FileAccess::ModeFlags::READ);
+ Error err = FileAccess::get_open_error();
+ if (err != OK || file.is_null()) {
+ UtilityFunctions::push_error("Failed to load localisation file: ", file_path);
+ return err == OK ? FAILED : err;
+ }
+ int line_number = 0;
+ while (!file->eof_reached()) {
+ PackedStringArray line = file->get_csv_line();
+ line_number++;
+ if (line.size() < 2 || line[0].is_empty() || line[1].is_empty()) {
+ if (!line[0].is_empty())
+ UtilityFunctions::push_warning("Key \"", line[0], "\" missing value on line ", line_number, " in file: ", file_path);
+ else if (line.size() >= 2 && !line[1].is_empty())
+ UtilityFunctions::push_warning("Value \"", line[1], "\" missing key on line ", line_number, " in file: ", file_path);
+ continue;
+ }
+ translation->add_message(line[0], line[1].c_unescape());
+ }
+ return OK;
+}
+
+Ref<Translation> LoadLocalisation::_get_translation(String const& locale) {
+ TranslationServer *server = TranslationServer::get_singleton();
+ Ref<Translation> translation = server->get_translation_object(locale);
+ if (translation.is_null() || translation->get_locale() != locale) {
+ translation.instantiate();
+ translation->set_locale(locale);
+ server->add_translation(translation);
+ }
+ return translation;
+}
+
+Error LoadLocalisation::load_file(String const& file_path, String const& locale) {
+ return _load_file_into_translation(file_path, _get_translation(locale));
+}
+
+/* REQUIREMENTS
+ * FS-18, FS-24, FS-25
+ */
+Error LoadLocalisation::load_locale_dir(String const& dir_path, String const& locale) {
+ Ref<Translation> translation = _get_translation(locale);
+ if (DirAccess::dir_exists_absolute(dir_path)) {
+ Error err = OK;
+ for (String const& file_name : DirAccess::get_files_at(dir_path)) {
+ if (file_name.get_extension().to_lower() == "csv") {
+ String file_path = dir_path.path_join(file_name);
+ if (_load_file_into_translation(file_path, translation) != OK)
+ err = FAILED;
+ }
+ }
+ return err;
+ }
+ UtilityFunctions::push_error("Locale directory does not exist: ", dir_path);
+ return FAILED;
+}
+
+/* REQUIREMENTS
+ * FS-23
+ */
+Error LoadLocalisation::load_localisation_dir(String const& dir_path) {
+ if (DirAccess::dir_exists_absolute(dir_path)) {
+ TranslationServer *server = TranslationServer::get_singleton();
+ Error err = OK;
+ for (String const& locale_name : DirAccess::get_directories_at(dir_path)) {
+ if (locale_name == server->standardize_locale(locale_name)) {
+ if (load_locale_dir(dir_path.path_join(locale_name), locale_name) != OK)
+ err = FAILED;
+ } else {
+ err = FAILED;
+ UtilityFunctions::push_error("Invalid locale directory name: ", locale_name);
+ }
+ }
+ return err;
+ }
+ UtilityFunctions::push_error("Localisation directory does not exist: ", dir_path);
+ return FAILED;
+}
diff --git a/extension/src/LoadLocalisation.hpp b/extension/src/LoadLocalisation.hpp
new file mode 100644
index 0000000..90f3158
--- /dev/null
+++ b/extension/src/LoadLocalisation.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/classes/translation.hpp>
+
+namespace OpenVic2 {
+ class LoadLocalisation : public godot::Object
+ {
+ GDCLASS(LoadLocalisation, godot::Object)
+
+ static LoadLocalisation *singleton;
+
+ godot::Error _load_file_into_translation(godot::String const& file_path, godot::Ref<godot::Translation> translation);
+ godot::Ref<godot::Translation> _get_translation(godot::String const& locale);
+
+ protected:
+ static void _bind_methods();
+
+ public:
+ static LoadLocalisation *get_singleton();
+
+ LoadLocalisation();
+ ~LoadLocalisation();
+
+ godot::Error load_file(godot::String const& file_path, godot::String const& locale);
+ godot::Error load_locale_dir(godot::String const& dir_path, godot::String const& locale);
+ godot::Error load_localisation_dir(godot::String const& dir_path);
+ };
+}
diff --git a/extension/src/register_types.cpp b/extension/src/register_types.cpp
index aac38b9..d1613a5 100644
--- a/extension/src/register_types.cpp
+++ b/extension/src/register_types.cpp
@@ -8,6 +8,7 @@
#include "TestSingleton.hpp"
#include "Simulation.hpp"
#include "Checksum.hpp"
+#include "LoadLocalisation.hpp"
using namespace godot;
using namespace OpenVic2;
@@ -15,6 +16,7 @@ using namespace OpenVic2;
static TestSingleton* _test_singleton;
static Simulation* _simulation;
static Checksum* _checksum;
+static LoadLocalisation* _load_localisation;
void initialize_openvic2_types(ModuleInitializationLevel p_level)
{
@@ -34,6 +36,10 @@ void initialize_openvic2_types(ModuleInitializationLevel p_level)
_checksum = memnew(Checksum);
Engine::get_singleton()->register_singleton("Checksum", Checksum::get_singleton());
+ ClassDB::register_class<LoadLocalisation>();
+ _load_localisation = memnew(LoadLocalisation);
+ Engine::get_singleton()->register_singleton("LoadLocalisation", LoadLocalisation::get_singleton());
+
}
void uninitialize_openvic2_types(ModuleInitializationLevel p_level) {
@@ -49,6 +55,9 @@ void uninitialize_openvic2_types(ModuleInitializationLevel p_level) {
Engine::get_singleton()->unregister_singleton("Checksum");
memdelete(_checksum);
+
+ Engine::get_singleton()->unregister_singleton("LoadLocalisation");
+ memdelete(_load_localisation);
}
extern "C"