Update lang handle (auto update when lang changed)

This commit is contained in:
Qwreey 2023-02-18 16:07:38 +09:00
parent 8e4f69827a
commit 723d3f9e9c
7 changed files with 166 additions and 93 deletions

View file

@ -0,0 +1,18 @@
# Getting Started
## 머리말
이 페이지는 Quad 모듈을 쉽게 시작할 수 있도록 튜토리얼을 제공하고 있습니다. 이 페이지를 정독해 Quad 모듈의 전반적인 사용법을 파악해보세요!
## 설치
[다음 페이지로 가기](kr/tutorial/1_install)
## 목차
[1. 설치하기](kr/tutorial/1_install)
[2. 시작하기](kr/tutorial/2_starting)

View file

75
src/exports.lua Normal file
View file

@ -0,0 +1,75 @@
---@class quad
local module = {}
-- TODO: outside ui building
-- if not Instance then
-- print("Instance is not exist, Using custom Instance and print result as string . . .")
-- end
local require = require(script.Parent.libs.require)
local style = require "style"
local event = require "event"
local store = require "store"
local class = require "class"
local mount = require "mount"
local signal = require "signal"
local lang = require "lang"
-- submodule
local advancedTween = require "libs.AdvancedTween"
local round = require "libs.round"
local customWarn = require "libs.customWarn"
local IS_TEST = false
local VER = "2.18" .. (IS_TEST and "B" or "")
if IS_TEST then
warn("You are using BETA version of quad now. Many features may change in the future and unstable. AS USING BETA VERSION OF QUAD, YOU SHOULD KNOW IT WILL BUGGY SOMETIME. still on development - you can ignore this message if have no issue. if you have issue on using quad, please report issue on github. VERSION: "..VER)
end
local idSpace = {}
---@return quad_export this
---@return quad_module_round round
---@return quad_module_tween tween
function module.Init(id)
-- return old items
if id then
local this = idSpace[id]
if this then
return this,this.round,this.class,this.mount,this.store,this.event,this.tween
end
end
---@class quad_export
local this = {__type = "quad_module_init"}
this.require = require
this.warn = customWarn or warn
this.Round = type(round) == "table" and round ---@type quad_module_round
this.Tween = type(advancedTween) == "table" and advancedTween ---@type quad_module_tween
this.Signal = signal.init(this) ---@type quad_module_signal
this.Style = style.init(this) ---@type quad_module_style
this.Event = event.init(this) ---@type quad_module_event
this.Store = store.init(this) ---@type quad_module_store
this.Mount = mount.init(this) ---@type quad_module_mount
this.Class = class.init(this) ---@type quad_module_class
this.Lang = lang.init(this) ---@type quad_module_lang
-- save
if id then
idSpace[id] = this
end
return this
end
local function cleanup(space)
-- TODO : Destroy objects
end
function module.Uninit(id)
pcall(cleanup,idSpace[id])
idSpace[id] = nil
end
return module

View file

@ -1,74 +1,3 @@
---@class quad
local module = {}
if not Instance then local types = require(script.types)
print("Instance is not exist, Using custom Instance and print result as string . . .") return require(script.exports)::types.module
end
local IS_TEST = true
local VER = "2.14" .. (IS_TEST and "B" or "")
if IS_TEST then
warn("You are using BETA version of quad now. Many features may change in the future and unstable. AS USING BETA VERSION OF QUAD, YOU SHOULD KNOW IT WILL BUGGY SOMETIME. still on development - you can ignore this message if have no issue. if you have issue on using quad, please report issue on github. VERSION: "..VER)
end
local require = require(script.require)
local style = require "style"
local event = require "event"
local store = require "store"
local class = require "class"
local mount = require "mount"
local signal = require "signal"
local lang = require "lang"
-- submodule
local _,advancedTween = pcall(require,"libs.AdvancedTween")
local _,round = pcall(require,"libs.round")
local _,customWarn = pcall(require,"libs.customWarn")
local idSpace = {}
---@return quad_export this
---@return quad_module_round round
---@return quad_module_tween tween
function module.Init(id)
-- return old items
if id then
local this = idSpace[id]
if this then
return this,this.round,this.class,this.mount,this.store,this.event,this.tween
end
end
---@class quad_export
local this = {__type = "quad_module_init"}
this.require = require
this.warn = customWarn or warn
this.Round = type(round) == "table" and round ---@type quad_module_round
this.Tween = type(advancedTween) == "table" and advancedTween ---@type quad_module_tween
this.Signal = signal.init(this) ---@type quad_module_signal
this.Style = style.init(this) ---@type quad_module_style
this.Event = event.init(this) ---@type quad_module_event
this.Store = store.init(this) ---@type quad_module_store
this.Mount = mount.init(this) ---@type quad_module_mount
this.Class = class.init(this) ---@type quad_module_class
this.Lang = lang.init(this) ---@type quad_module_lang
-- save
if id then
idSpace[id] = this
end
return this
end
local function cleanup(space)
-- TODO : Destroy objects
end
function module.Uninit(id)
pcall(cleanup,idSpace[id])
idSpace[id] = nil
end
return module

View file

@ -60,13 +60,30 @@ function module.init(shared)
["Swedish"] = "sv_se"; ["Swedish"] = "sv_se";
["Arabic"] = "ar_001"; ["Arabic"] = "ar_001";
} }
new.CurrentLocale = game:GetService("LocalizationService").RobloxLocaleId
new.FailedMessage = "<Localization Failed>"
local function GetLocale()
return game:GetService("LocalizationService").RobloxLocaleId
end
local function PcallGetLocale()
local passed,result = pcall(GetLocale)
if passed then return result end
return false
end
local CurrentLocale = PcallGetLocale() or "en_us"
local FailedMessage = "<Localization Failed>"
local weak = {__mode = "v"}
local lang = {} local lang = {}
lang.__index = lang lang.__index = lang
function lang.New(id,handlers) function lang.New(id,handlers)
local this = {handlers=handlers,id=id,store=store.New(),index=1} local this = {
handlers=handlers;
id=id;
store=store.New();
index=1;
registers = setmetatable({},weak);
}
lang[id] = this lang[id] = this
if not handlers[new.Locales.Default] then if not handlers[new.Locales.Default] then
warn(("Localization %s have no Default value, Did you missed '[Lang.Locales.Default] = ...' ? It may make Localization fail on other languages")) warn(("Localization %s have no Default value, Did you missed '[Lang.Locales.Default] = ...' ? It may make Localization fail on other languages"))
@ -115,24 +132,28 @@ function module.init(shared)
function lang:UpdateAll() function lang:UpdateAll()
-- find handler -- find handler
local handler = self.handlers[new.Lang] local handler = self.handlers[CurrentLocale]
if not handler then if not handler then
handler = self.handlers[new.Default] handler = self.handlers[new.Locales.Default]
end end
for index = 1,self.index do for index,register in pairs(self.registers) do
Update(self.store,handler,index,options) if handler then
Update(self.store,handler,index,register.options)
else
self.store[tostring(index)] = FailedMessage
end
end end
end end
function lang:Format(options) function lang:Format(options)
-- find handler -- find handler
local handler = self.handlers[new.Lang] local handler = self.handlers[CurrentLocale]
if not handler then if not handler then
handler = self.handlers[new.Locales.Default] handler = self.handlers[new.Locales.Default]
end end
if not handler then if not handler then
warn(("Langauge handle %s is not found on Localization %s"):format(new.Default,self.id)) warn(("Langauge handle Lang.Locales.Default is not found on Localization %s"):format(self.id))
end end
local index = self.index local index = self.index
self.index = index + 1 self.index = index + 1
@ -140,11 +161,6 @@ function module.init(shared)
-- setup updater -- setup updater
local registerKeep = {} local registerKeep = {}
-- this table will destroyed when parent register was destroyed -- this table will destroyed when parent register was destroyed
-- that means, if some other registerFN was inserted in registerKeep,
-- it will be destroyed when unnecessary
-- maybe better then self.store.__keep for GC
-- it will be not destroyed. anyway; registerKeep will be connected
-- to real instance OR local
for _,option in pairs(options) do for _,option in pairs(options) do
local quadType = PcallGetProperty(option,"__type") local quadType = PcallGetProperty(option,"__type")
-- if it is register, setup updater -- if it is register, setup updater
@ -156,9 +172,10 @@ function module.init(shared)
handler = self.handlers[new.Locales.Default] handler = self.handlers[new.Locales.Default]
end end
if not handler then if not handler then
self.store[tostring(index)] = new.FailedMessage self.store[tostring(index)] = FailedMessage
else
Update(self.store,handler,index,options)
end end
Update(self.store,handler,index,options)
-- !HOLD IT SELF TO PREVENT THIS REGISTER BEGIN REMOVED FROM MEMORY -- !HOLD IT SELF TO PREVENT THIS REGISTER BEGIN REMOVED FROM MEMORY
end end
option:Register(regFn) option:Register(regFn)
@ -170,13 +187,16 @@ function module.init(shared)
if handler then if handler then
Update(self.store,handler,index,options) Update(self.store,handler,index,options)
else else
self.store[tostring(index)] = new.FailedMessage self.store[tostring(index)] = FailedMessage
end end
-- return resiter -- return resiter
local register = self.store(tostring(index)) local register = self.store(tostring(index))
register.registerKeep = registerKeep register.registerKeep = registerKeep
register.__rtype = "LangUpdater" register.__rtype = "LangUpdater"
register.index = index
register.options = options
self.registers[index] = register
return register return register
end end
@ -184,6 +204,12 @@ function module.init(shared)
return lang.New(id,handlers) return lang.New(id,handlers)
end end
function new.Update()
for _,this in pairs(lang) do
this:UpdateAll()
end
end
setmetatable(new,{ setmetatable(new,{
__call = function(_,id) __call = function(_,id)
return function (options) return function (options)
@ -194,6 +220,27 @@ function module.init(shared)
return data:Format(options) return data:Format(options)
end end
end; end;
__index = function (self,key)
if key == "CurrentLocale" then
return CurrentLocale
end
if key == "FailedMessage" then
return FailedMessage
end
end;
__newindex = function (self,key,value)
if key == "CurrentLocale" then
CurrentLocale = value
new.Update()
return
end
if key == "FailedMessage" then
FailedMessage = value
new.Update()
return
end
rawset(self,key,value)
end
}) })
return new return new

View file

@ -9,7 +9,7 @@ return function (query)
local typeQuery = type(query) local typeQuery = type(query)
if typeQuery == "string" then if typeQuery == "string" then
local object = script.Parent local object = script.Parent.Parent
query = query:gsub("/",".") query = query:gsub("/",".")
-- local index = 0 -- local index = 0
query:gsub("[^%.]+",function (this) query:gsub("[^%.]+",function (this)
@ -21,7 +21,7 @@ return function (query)
object = object[this] object = object[this]
if not object then if not object then
object = lastObject.libs object = lastObject.libs
error(("[Quad] (require) object %s was not found from this worktree, require failed"):format(query)) return false,("[Quad] (require) object %s was not found from this worktree, require failed"):format(query)
end end
end) end)
return require(object) return require(object)

View file

@ -54,6 +54,9 @@ function module.init()
local Global = Store.GetStore "global" local Global = Store.GetStore "global"
local TweenTest = Class(script.tween) local TweenTest = Class(script.tween)
local LangTest = Class(script.lang)
Signal.
SetTheme(Global) SetTheme(Global)
@ -62,7 +65,8 @@ function module.init()
Size = UDim2.fromOffset(400,640); Size = UDim2.fromOffset(400,640);
Position = UDim2.fromScale(0.5,0.5); Position = UDim2.fromScale(0.5,0.5);
AnchorPoint = Vector2.new(0.5,0.5); AnchorPoint = Vector2.new(0.5,0.5);
TweenTest{}; -- TweenTest{};
LangTest{};
} }
} }
Mount(game.StarterGui,Store.GetObject "MainGui") Mount(game.StarterGui,Store.GetObject "MainGui")