UNPKG

@senspark/ee

Version:

utility library for cocos creator

172 lines (153 loc) 5.52 kB
import assert = require('assert'); import * as Polyglot from 'node-polyglot'; import { ObserverManager } from './ObserverManager'; import { ProfileManager } from './ProfileManager'; type Observer = () => void; export class LanguageManager extends ObserverManager<Observer> { private static sharedInstance?: LanguageManager; /** Gets the singleton. */ public static getInstance(): LanguageManager { return this.sharedInstance || (this.sharedInstance = new this()); } /** * Current config directory. * Actually UUID in editor mode and relative path in release mode. */ private configDir?: string; /** Current active language. */ private currentLanguage?: string; private configs: { [index: string]: { [key: string]: string | undefined } | undefined }; /** Wrappee i18n manager. */ private polyglot: Polyglot; private constructor() { super(); // Hide construction. this.configs = {}; this.polyglot = new Polyglot(); const profile = ProfileManager.getInstance(); this.currentLanguage = profile.loadData('current_language'); this.configDir = profile.loadData('config_dir'); this.updateConfigs(); } /** * Gets all available languages. * @return Array of language names. */ public getLanguages(): string[] { return Object.keys(this.configs); } /** * Gets the config dir. * Used in editor only. */ public getConfigDir(): string | undefined { return this.configDir; } /** * Sets the config directory. * @param path The directory path. */ public setConfigDir(path: string): void { this.configDir = path; if (CC_EDITOR) { const profile = ProfileManager.getInstance(); profile.saveData('config_dir', this.configDir); } this.updateConfigs(); this.updateLanguage(); } /** Clears the language directory. */ public resetConfigDir(): void { this.configDir = undefined; if (CC_EDITOR) { const profile = ProfileManager.getInstance(); profile.saveData('config_dir', this.configDir); } this.updateConfigs(); } private updateConfigs(): void { this.configs = {}; if (this.configDir === undefined) { this.updateLanguage(); return; } if (CC_EDITOR) { Editor.assetdb.queryUrlByUuid(this.configDir, (err, url) => { const pattern = url + '/*.json'; const type = (cc.ENGINE_VERSION >= '2' ? 'json' : 'text'); Editor.assetdb.queryAssets(pattern, type, (err2, result) => { result.forEach((item: any) => { import(item.path).then(config => { const language = this.parseLanguage(item.path); this.configs[language] = config; this.updateLanguage(); }); }); }); }); } else { cc.loader.loadResDir(this.configDir, (err: any, results: any[], urls: string[]) => { for (let i = 0; i < urls.length; ++i) { const path = urls[i] + '.json'; // Suffixed with .json for regex matching. const content = results[i]; const language = this.parseLanguage(path); if (cc.ENGINE_VERSION >= '2') { this.configs[language] = content.json; } else { this.configs[language] = content; } this.updateLanguage(); } }); } } private updateLanguage(): void { this.polyglot.clear(); if (this.currentLanguage !== undefined) { const config = this.configs[this.currentLanguage]; if (config !== undefined) { this.polyglot.extend(config); } } this.dispatch(observer => observer()); } /** Gets the active language. */ public getCurrentLanguage(): string | undefined { return this.currentLanguage; } /** Sets the active language. */ public setCurrentLanguage(language: string | undefined): void { this.currentLanguage = language; if (CC_EDITOR) { const profile = ProfileManager.getInstance(); profile.saveData('current_language', language); } this.updateLanguage(); } /** Gets the language format in the current language. */ public getFormat(key: string): string | undefined { if (this.currentLanguage === undefined) { return undefined; } const config = this.configs[this.currentLanguage]; if (config === undefined) { return undefined; } return config[key]; } public parseFormat(key: string, options?: Polyglot.InterpolationOptions): string | undefined { if (this.polyglot.has(key)) { return this.polyglot.t(key, options!); } return undefined; } /** Detects language for the config path. */ private parseLanguage(path: string): string { const regex = /\/(\w+)\.\w+$/g; const match = regex.exec(path); if (match === null) { return ''; } return match[1]; } }