forked from jaildesigner-jailgames/jaildoctors_dilemma
91 lines
2.6 KiB
C++
91 lines
2.6 KiB
C++
#include "core/locale/locale.hpp"
|
|
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
#include "external/fkyaml_node.hpp" // Para fkyaml::node
|
|
#include "game/options.hpp" // Para Options::console
|
|
|
|
// [SINGLETON]
|
|
Locale* Locale::locale_ = nullptr;
|
|
|
|
// [SINGLETON] Crea el objeto con esta función estática
|
|
void Locale::init(const std::string& file_path) {
|
|
Locale::locale_ = new Locale();
|
|
Locale::locale_->loadFromFile(file_path);
|
|
}
|
|
|
|
// [SINGLETON] Destruye el objeto con esta función estática
|
|
void Locale::destroy() {
|
|
delete Locale::locale_;
|
|
Locale::locale_ = nullptr;
|
|
}
|
|
|
|
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
|
|
auto Locale::get() -> Locale* {
|
|
return Locale::locale_;
|
|
}
|
|
|
|
// Devuelve la traducción de la clave o la clave como fallback
|
|
auto Locale::get(const std::string& key) const -> std::string {
|
|
auto it = strings_.find(key);
|
|
if (it != strings_.end()) {
|
|
return it->second;
|
|
}
|
|
|
|
if (Options::console) {
|
|
std::cerr << "Locale: clave no encontrada: " << key << '\n';
|
|
}
|
|
return key;
|
|
}
|
|
|
|
// Aplana un nodo YAML de forma recursiva: {a: {b: "val"}} -> {"a.b" -> "val"}
|
|
void Locale::flatten(const void* node_ptr, const std::string& prefix) {
|
|
const auto& node = *static_cast<const fkyaml::node*>(node_ptr);
|
|
|
|
for (auto itr = node.begin(); itr != node.end(); ++itr) {
|
|
const std::string KEY = prefix.empty()
|
|
? itr.key().get_value<std::string>()
|
|
: prefix + "." + itr.key().get_value<std::string>();
|
|
|
|
const auto& value = itr.value();
|
|
if (value.is_mapping()) {
|
|
flatten(&value, KEY);
|
|
} else if (value.is_string()) {
|
|
strings_[KEY] = value.get_value<std::string>();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Carga las traducciones desde el fichero YAML indicado
|
|
void Locale::loadFromFile(const std::string& file_path) {
|
|
if (file_path.empty()) {
|
|
if (Options::console) {
|
|
std::cerr << "Locale: ruta de fichero vacía, sin traducciones cargadas\n";
|
|
}
|
|
return;
|
|
}
|
|
|
|
std::ifstream file(file_path);
|
|
if (!file.is_open()) {
|
|
if (Options::console) {
|
|
std::cerr << "Locale: no se puede abrir " << file_path << '\n';
|
|
}
|
|
return;
|
|
}
|
|
|
|
try {
|
|
auto yaml = fkyaml::node::deserialize(file);
|
|
flatten(&yaml, "");
|
|
|
|
if (Options::console) {
|
|
std::cout << "Locale: " << strings_.size() << " traducciones cargadas desde " << file_path << '\n';
|
|
}
|
|
} catch (const fkyaml::exception& e) {
|
|
if (Options::console) {
|
|
std::cerr << "Locale: error al parsear YAML: " << e.what() << '\n';
|
|
}
|
|
}
|
|
}
|