Register - 값 변경 연동¶
읽기 전...
모듈 설정시 .Init()
처럼 QuadId 란을 비워두는 경우 Store.GetStore
가 코드를 넘어 공유되지 않습니다
하지만 .Init("Project1")
처럼 아이디를 부여하는 경우 다른 모듈, 로컬스크립트가 접근하더라도 같은 QuadId 를 가졌다면 Store.GetStore
는 공유됩니다
레지스터¶
레지스터는 한 값이 변경될 때, 그 값을 사용한 곳이 업데이트 될 수 있도록 만들어주는 Quad 의 주요 기술입니다. 추후 설명될 Class.Extend
와도 같이 사용됩니다.
레지스터는 이러한 시나리오에서 사용될 수 있습니다.
- UI 의 여러 오브젝트를 한번에 페이드 아웃 혹은 페이드 인 시키는 경우.
- 가변 크기의 UI 를 업데이트 시키는 경우.
- 여러 오브젝트들을 한꺼번에 트윈시키는 경우.
- 다크테마/화이트테마 변경할 수 있게 만드는 경우.
이외에도 레지스터의 활용 방법은 무궁무진합니다. 레지스터의 사용법은 다음과 같습니다.
1 2 3 4 5 |
|
주의
구현의 복잡성의 이유로 레지스터는 오브젝트 생성시에만 등록할 수 있습니다.
1 2 |
|
1 2 3 4 |
|
- 스토어를 생성함.
- 기본 값을 설정함.
- 스토어를 호출해 레지스터를 얻어 등록함.
예시 코드로 정확하게 확인해 볼 수 있습니다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
레지스터 메소드¶
레지스터에는 여러가지 메소드가 담겨있습니다. 이 메소드를 사용하면 레지스터를 보다 더 다양하게 활용할 수 있습니다.
register
특수 메소드가 적용되는 순서는 다음과 같습니다.
:Add(value:any)->register
값에 더하기를 취합니다. 음수형태가 제공되는 경우 빼기 처럼 작동합니다.
number
,Udim
,UDim2
,Color3
,Vector2
등 더할 수 있는 모든것을 사용할 수 있습니다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21-- 용법 local ScreenGUI = script.Parent local Quad = require(path.to.module).Init() local Store = Quad.Store local Class = Quad.Class local Mount = Quad.Mount local Frame = Class "Frame" local myStore = Store.GetStore("myStore") myStore.pos = UDim2.fromOffset(100,0) Frame "mainFrame" { Position = myStore "pos":Add(UDim2.fromOffset(0,100)); } Mount(ScreenGUI, Store.GetObject("mainFrame")) while true do myStore.pos = myStore.pos + UDim2.fromOffset(10,0) task.wait(2) end
주의
구조의 복잡성을 피하고자, 여러번 호출시 가장 마지막 호출된 것만 사용됩니다
:With((store:valueStore, newValue:any, key:string)->())->register
함수 또는 테이블에서 값을 가져옵니다. Add 보다 나중에 수행됩니다.
첫번째 값에는 편의상 스토어 값이 제공되며, 새로운 값과, 바뀐 값에 대한 키가 제공됩니다
1 2 3myStore "size":With(function (_,value) return value * 2 end)
width
값에 맞춰 자동으로 UI 가 업데이트되도록 만듭니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53local ScreenGUI = script.Parent local Quad = require(path.to.module).Init() local Store = Quad.Store local Class = Quad.Class local Mount = Quad.Mount local Frame = Class "Frame" local myStore = Store.GetStore("myStore") myStore.topbarSize = 60 myStore.width = 200 -- 레지스터를 변수로 두고 사용합니다 local listItemSize = myStore "width":With(function() return UDim2.fromOffset(myStore.width,60) end) Frame "mainFrame" { Class "UIListLayout" { SortOrder = Enum.SortOrder.LayoutOrder }; -- 사이즈가 width 에 맞게 업데이트됩니다 Size = myStore "width":With(function () return UDim.fromOffset(store.width,400) end); Frame "Topbar" { LayoutOrder = 1; BackgroundColor3 = Color3.fromRGB(255,0,0); -- 이렇게 여러 값을 묶어서 두 값이 변경됨, 혹은 그이상을 -- 만들 수 있습니다. Size = myStore "topbarSize,width":With(function() return UDim2.fromOffset(myStore.width,myStore.topbarSize) end); } Frame "ListItem" { LayoutOrder = 2; BackgroundColor3 = Color3.fromRGB(0,255,0); Size = listItemSize; }; Frame "ListItem" { LayoutOrder = 3; BackgroundColor3 = Color3.fromRGB(0,0,255); Size = listItemSize; }; } Mount(ScreenGUI, Store.GetObject("mainFrame")) -- width 값을 변경해보세요 while true do myStore.width = myStore.width + 10 task.wait(1) end
colors
테이블 안에 있는 색깔들을 돌아가며 보여줍니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31local ScreenGUI = script.Parent local Quad = require(path.to.module).Init() local Store = Quad.Store local Class = Quad.Class local Mount = Quad.Mount local Frame = Class "Frame" local myStore = Store.GetStore("myStore") local colors = { Color3.fromRGB(255,255,255); Color3.fromRGB(255,255,0); Color3.fromRGB(0,255,255); Color3.fromRGB(255,0,255); Color3.fromRGB(255,0,0); Color3.fromRGB(0,255,0); Color3.fromRGB(0,0,255); } myStore.color = 1 Frame "mainFrame" { Size = UDim2.fromOffset(200,200); -- colors 에서 인덱싱해 값을 가져옵니다 BackgroundColor3 = myStore "color":With(colors); } Mount(ScreenGUI, Store.GetObject("mainFrame")) -- 인덱스를 순회합니다 while task.wait(1) do myStore.color = (i-1)%(#colors)+2 end
주의
구조의 복잡성을 피하고자, 여러번 호출시 가장 마지막 호출된 것만 사용됩니다
:Tween(options:TweenOptions)->register
트윈을 이용해 변경사항을 적용합니다(처음 오브젝트 생성시에는 적용되지 않음) 옵션은 Tween 문서에 나와있는 옵션과 같습니다.
1 2-- Tween 옵션을 넣을 수 있습니다 myStore "size":Tween{ Time = 2 }
프레임을 한꺼번에 움직입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47local ScreenGUI = script.Parent local Quad = require(path.to.module).Init() local Store = Quad.Store local Class = Quad.Class local Mount = Quad.Mount local Style = Quad.Style local Frame = Class "Frame" local myStore = Store.GetStore("myStore") myStore.pos = UDim2.fromOffset(50,0) Style "TweenFrame" { Size = UDim2.fromOffset(50,50); BackgroundColor3 = Color3.fromRGB(255,100,255); } Frame "mainFrame" { BackgroundColor3 = Color3.fromRGB(255,255,255); Size = UDim2.fromOffset(500,500); Frame "TweenFrame" { Position = myStore "pos":Tween{Time = 2}; }; Frame "TweenFrame" { Position = myStore "pos" :Add(UDim2.fromOffset(0,100)) :Tween{Time = 2}; }; Frame "TweenFrame" { Position = myStore "pos" :Add(UDim2.fromOffset(0,200)) :Tween{Time = 2}; }; Frame "TweenFrame" { Position = myStore "pos" :Add(UDim2.fromOffset(0,300)) :Tween{Time = 2}; } } Mount(ScreenGUI, Store.GetObject("mainFrame")) local on = false while true do on = not on myStore.pos = on and UDim2.fromOffset(400,0) or UDim2.fromOffset(50,0) task.wait(1.5) -- 트윈은 덮어 쓸 수 있습니다 -- 따라서 2 초인 길이보다 더 빨리 바꿔도 오류가 일어나지 않습니다 end
주의
구조의 복잡성을 피하고자, 여러번 호출시 가장 마지막 호출된 것만 사용됩니다
:Default(value:any)->register
기본값을 정합니다. 만약 값이
nil
인 경우 이 값을 사용하게 됩니다. Add 나 With 등 다른것에 영향받지 않습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21-- 용법 local ScreenGUI = script.Parent local Quad = require(path.to.module).Init() local Store = Quad.Store local Class = Quad.Class local Mount = Quad.Mount local Frame = Class "Frame" local myStore = Store.GetStore("myStore") Frame "mainFrame" { Size = UDim2.fromOffset(200,200); -- color 값이 없으므로 Default 안의 값이 사용됩니다. BackgroundColor3 = myStore "color" :Default(Color3.fromRGB(255,0,0)); } Mount(ScreenGUI, Store.GetObject("mainFrame")) task.wait(5) myStore.color = Color3.fromRGB(0,255,0)
주의
- 처음 오브젝트가 생성될 때에만 이 값이 사용됩니다.
- 구조의 복잡성을 피하고자, 여러번 호출시 가장 마지막 호출된 것만 사용됩니다.
:Register(<INPUT>(store:valueStore, newValue:any, key:string)->())->INPUT
레지스터에 함수를 등록합니다. 값이 변경되면 함수가 실행됩니다. 첫번째 값에는 편의상 스토어 값이 제공되며, 새로운 값과, 바뀐 값에 대한 키가 제공됩니다
newValue
에는:Add
,:With
,:Tween
,:Default
가 따로 계산되지 않으며, 설정된 값을 아무 가공 없이 제공합니다
1 2 3 4 5 6 7 8 9myStore.test = 1 -- 반환 값은 입력으로 넣은 함수입니다. !꼭 저장해야합니다 -- :Register 는 함수가 사라지지 않도록 값을 유지하지 않습니다 -- 만약 버릴 경우 일정 시간 뒤 연결이 끊어질 수 있습니다 local func = myStore "test":Register(function(_,newValue) -- 값 변경시 출력됩니다 print(newValue) end) myStore.test = 2
myStore.test1
,myStore.test2
가 변화하면 print 함수를 실행합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13local Quad = require(path.to.module).Init() local Store = Quad.Store local myStore = Store.GetStore("myStore") myStore.test1 = 1 myStore.test2 = "Hello" local func = myStore "test1,test2":Register(function() print(myStore.test1,myStore.test2) end) myStore.test1 = 2
주의
Register 안에 들어간 함수는 GC 안정성을 위해서 약한 참조로 저장됩니다. 따라서 함수를 저장해야합니다.
:Observe((newValue:any)->())
:Register
의 간소화 버전입니다.:Register
와 다르게 자동적으로 들어간 함수를 GC 로 부터 보호하기 때문에 들어간 함수를 따로 저장 할 필요가 없으며, 인자는newValue
하나만 주어집니다.
newValue
는:Add
,:With
,:Tween
,:Default
가 계산된 상태로 제공됩니다.
1 2 3 4 5 6myStore.test = 1 myStore "test":Add(1):Observe(function(_,newValue) -- 값 변경시 출력됩니다 print(newValue) end) myStore.test = 2