Files
jdd_opendingux/source/core/locale/locale.cpp

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::instance = nullptr;
// [SINGLETON] Crea el objeto con esta función estática
void Locale::init(const std::string& file_path) {
Locale::instance = new Locale();
Locale::instance->loadFromFile(file_path);
}
// [SINGLETON] Destruye el objeto con esta función estática
void Locale::destroy() {
delete Locale::instance;
Locale::instance = nullptr;
}
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
auto Locale::get() -> Locale* {
return Locale::instance;
}
// 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';
}
}
}