UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

99 lines (71 loc) 2.61 kB
import { array_get_index_in_range } from "../collection/array/array_get_index_in_range.js"; import { assert } from "../assert.js"; const resolve_chain = []; export class LocalizationEngine { /** * * @type {Object<LocaleDataset>} */ #locales = {}; /** * * @type {Object<LanguageMetadata>} */ #languages = {}; /** * * @param {string} key * @param {LocaleDataset} dataset */ setLocaleDataset(key, dataset) { assert.isString(key, 'key'); assert.defined(dataset, 'dataset'); this.#locales[key] = dataset; } /** * * @param {LanguageMetadata} metadata */ addLanguageMetadata(metadata) { assert.defined(metadata, 'metadata'); this.#languages[metadata.locale] = metadata; } /** * * Resolves language and fragment key to a localized value, follows fallback links of known languages when no value found in requested language * * @param {string} language_key Locale key * @param {string} fragment_key Object key * @returns {Object|string|undefined} */ resolve(language_key, fragment_key) { resolve_chain[0] = language_key; let resolve_cursor = 0; let resolve_chain_end = 1; while (resolve_cursor < resolve_chain_end) { const lang = resolve_chain[resolve_cursor++]; const locale = this.#locales[lang]; if (locale !== undefined && locale[fragment_key] !== undefined) { // found a hit return locale[fragment_key]; } else { // see if there's a fallback locale const metadata = this.#languages[lang]; if (metadata !== undefined) { const fallbacks = metadata.fallback_languages; const fallback_count = fallbacks.length; for (let i = 0; i < fallback_count; i++) { const fallback = fallbacks[i]; if (array_get_index_in_range(resolve_chain, fallback, 0, resolve_chain_end) !== -1) { // circular dependency, that language was already attempted continue; } resolve_chain[resolve_chain_end++] = fallback; } } } } // chain exhausted, no result found return undefined; } }