diff options
author | Hop311 <Hop3114@gmail.com> | 2023-03-30 15:04:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-30 15:04:58 +0200 |
commit | 3384b21177a160f7192a2e4877eea3b29880bf4e (patch) | |
tree | db9c9a37a187e15ef494a700f8afe5d65c3a8b78 /extension | |
parent | 8f213935bdea2400b6809f9d5db45dde3416dedc (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.cpp | 111 | ||||
-rw-r--r-- | extension/src/LoadLocalisation.hpp | 29 | ||||
-rw-r--r-- | extension/src/register_types.cpp | 9 |
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" |