diff --git a/scripts/Locales/enUS.lua b/scripts/Locales/enUS.lua deleted file mode 100644 index 2a61ba0..0000000 --- a/scripts/Locales/enUS.lua +++ /dev/null @@ -1,10 +0,0 @@ -local Tinkr, Bastion = ... - -if not Bastion.Locale.ShouldLoad("enUS") then return end - -local L = {} - -L["Tinkr"] = "Tinkr" -L["Bastion"] = "Bastion" - -Bastion.Locale.SetTable(L) diff --git a/scripts/Locales/enUS/enUS.lua b/scripts/Locales/enUS/enUS.lua new file mode 100644 index 0000000..a153359 --- /dev/null +++ b/scripts/Locales/enUS/enUS.lua @@ -0,0 +1,7 @@ +local Tinkr, Bastion = ... + +local L = Bastion.Locale:NewLocale("Bastion", "enUS", true) + +L["Tinkr"] = true +L["Bastion"] = true + diff --git a/src/Locale/Locale.lua b/src/Locale/Locale.lua index 626ee40..9026885 100644 --- a/src/Locale/Locale.lua +++ b/src/Locale/Locale.lua @@ -4,38 +4,89 @@ local Locale = {} Locale.__index = Locale local private = { + gameLocale = GetLocale(), locale = nil, tbl = nil, hasNoLocaleTable = false } -private.locale = GetLocale() - -function Locale.GetTable() - assert(private.tbl) - return private.tbl +if private.gameLocale == "enGB" then + private.gameLocale = "enUS" end -function Locale.ShouldLoad(locale) - assert(private.locale) - return locale == private.locale +Locale.apps = {} +Locale.appnames = {} + +local readmeta = { + __index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key + rawset(self, key, key) -- only need to see the warning once, really + Bastion:Debug("Bastion Locale: " .. tostring(Locale.appnames[self]) .. ": Missing entry for '"..tostring(key).."'") + return key + end +} + +-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys +local readmetasilent = { + __index = function(self, key) -- requesting totally unknown entries: return key + rawset(self, key, key) -- only need to invoke this function once + return key + end +} + + +local registering + +local assertfalse = function() assert(false) end + +local writeproxy = setmetatable({}, { + __newindex = function(self, key, value) + rawset(registering, key, value == true and key or value) + end, + __index = assertfalse +}) + +local writedefaultproxy = setmetatable({}, { + __newindex = function(self, key, value) + rawset(registering, key, value == true and key or value) + end, + __index = assertfalse +}) + +function Locale:NewLocale(application, locale, isDefault, silent) + local activeGameLocale = GAME_LOCALE or private.gameLocale + local app = Locale.apps[application] + if silent and app and getmetatable(app) ~= readmetasilent then + Bastion:Debug("Usage: NewLocale(locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered") + end + + if not app then + if silent == "raw" then + app = {} + else + app = setmetatable({}, silent and readmetasilent or readmeta) + end + Locale.apps[application] = app + Locale.appnames[app] = application + end + if locale ~= activeGameLocale and not isDefault then + return + end + registering = app + if isDefault then + return writedefaultproxy + else + return writeproxy + end end -function Locale.SetTable(tbl) - private.tbl = setmetatable(tbl, { - __index = function(t, k) - local v = tostring(k) - if not private.hasNoLocaleTable then - error(string.format("Locale string does not exist: \"%s\"", v)) - end - rawset(t, k, v) - return v - end, - __newindex = function() - error("Cannot write to the locale table") - end, - }) +function Locale:GetLocale(application, silent) + if not silent and not Locale.apps[application] then + Bastion:Debug("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'") + end + return Locale.apps[application] or {} end + + return Locale diff --git a/src/_bastion.lua b/src/_bastion.lua index d5da534..675e78c 100644 --- a/src/_bastion.lua +++ b/src/_bastion.lua @@ -61,10 +61,9 @@ Bastion.Globals = {} ---@type Locale Bastion.Locale = Bastion.require("Locale") +Bastion:Require("~/scripts/Locales/enUS/enUS") Load("@Locales/") --- Bastion.Locales = {} --- Bastion.Locales.enUS = Bastion:Require("@Locales/enUS") -local L = Bastion.Locale.GetTable() +local L = Bastion.Locale:GetLocale("Bastion", true) Bastion.Globals.L = L ---@type Environment Bastion.Environment = Bastion.require("Environment")