@quenty/tie 10.9.0 → 10.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/package.json +18 -17
- package/src/Shared/Members/Properties/TiePropertyInterface.lua +39 -46
- package/src/Shared/TieDefinition.lua +52 -9
- package/src/Shared/TieImplementation.lua +1 -1
- package/src/Shared/Members/Properties/TiePropertyChangedSignalConnection.lua +0 -44
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,31 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [10.10.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/tie@10.10.0...@quenty/tie@10.10.1) (2024-10-04)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @quenty/tie
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [10.10.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/tie@10.9.0...@quenty/tie@10.10.0) (2024-10-04)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* Use configuration instead of folder. While this forces a datamodel event to fire, it means we scan less classes on the client, and it's easier to see in the explorer ([06a342f](https://github.com/Quenty/NevermoreEngine/commit/06a342f5726282c46174ddec3dc7f54eeb768c46))
|
|
20
|
+
* Use RxSignal for the TiePropertyInterface ([5ea04b8](https://github.com/Quenty/NevermoreEngine/commit/5ea04b85402e994f13a81a9b32e5971e1a262eb5))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Performance Improvements
|
|
24
|
+
|
|
25
|
+
* TieImplementation uses Folder on client instead of camera, which results in a memory improvement ([bc55d76](https://github.com/Quenty/NevermoreEngine/commit/bc55d76fd296c8923e47c3830145c8e75d8a7b69))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
6
31
|
# [10.9.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/tie@10.8.0...@quenty/tie@10.9.0) (2024-09-25)
|
|
7
32
|
|
|
8
33
|
**Note:** Version bump only for package @quenty/tie
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/tie",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.10.1",
|
|
4
4
|
"description": "Tie allows interfaces to be defined between Lua OOP and Roblox objects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -28,28 +28,29 @@
|
|
|
28
28
|
"Quenty"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@quenty/attributeutils": "^14.
|
|
32
|
-
"@quenty/baseobject": "^10.
|
|
33
|
-
"@quenty/brio": "^14.
|
|
34
|
-
"@quenty/collectionserviceutils": "^8.
|
|
35
|
-
"@quenty/instanceutils": "^13.
|
|
36
|
-
"@quenty/loader": "^10.
|
|
37
|
-
"@quenty/maid": "^3.
|
|
38
|
-
"@quenty/rx": "^13.
|
|
39
|
-
"@quenty/
|
|
31
|
+
"@quenty/attributeutils": "^14.8.1",
|
|
32
|
+
"@quenty/baseobject": "^10.6.0",
|
|
33
|
+
"@quenty/brio": "^14.8.1",
|
|
34
|
+
"@quenty/collectionserviceutils": "^8.8.1",
|
|
35
|
+
"@quenty/instanceutils": "^13.8.1",
|
|
36
|
+
"@quenty/loader": "^10.6.0",
|
|
37
|
+
"@quenty/maid": "^3.4.0",
|
|
38
|
+
"@quenty/rx": "^13.8.0",
|
|
39
|
+
"@quenty/rxsignal": "^7.8.0",
|
|
40
|
+
"@quenty/statestack": "^14.9.1",
|
|
40
41
|
"@quenty/string": "^3.3.0",
|
|
41
|
-
"@quenty/symbol": "^3.
|
|
42
|
+
"@quenty/symbol": "^3.2.0",
|
|
42
43
|
"@quenty/table": "^3.5.0",
|
|
43
|
-
"@quenty/tuple": "^1.
|
|
44
|
-
"@quenty/valuebaseutils": "^13.
|
|
45
|
-
"@quenty/valueobject": "^13.
|
|
44
|
+
"@quenty/tuple": "^1.3.0",
|
|
45
|
+
"@quenty/valuebaseutils": "^13.8.1",
|
|
46
|
+
"@quenty/valueobject": "^13.8.1"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
|
-
"@quenty/promise": "^10.
|
|
49
|
-
"@quenty/signal": "^7.
|
|
49
|
+
"@quenty/promise": "^10.6.0",
|
|
50
|
+
"@quenty/signal": "^7.7.0"
|
|
50
51
|
},
|
|
51
52
|
"publishConfig": {
|
|
52
53
|
"access": "public"
|
|
53
54
|
},
|
|
54
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "539802fea720a92f81ad48d6d5579605d8844d0a"
|
|
55
56
|
}
|
|
@@ -11,14 +11,13 @@ local Observable = require("Observable")
|
|
|
11
11
|
local Rx = require("Rx")
|
|
12
12
|
local RxBrioUtils = require("RxBrioUtils")
|
|
13
13
|
local RxInstanceUtils = require("RxInstanceUtils")
|
|
14
|
+
local RxSignal = require("RxSignal")
|
|
14
15
|
local String = require("String")
|
|
15
16
|
local Symbol = require("Symbol")
|
|
16
|
-
local
|
|
17
|
+
local TieMemberInterface = require("TieMemberInterface")
|
|
17
18
|
local TiePropertyImplementationUtils = require("TiePropertyImplementationUtils")
|
|
18
19
|
local TieUtils = require("TieUtils")
|
|
19
20
|
local ValueBaseUtils = require("ValueBaseUtils")
|
|
20
|
-
local ValueObject = require("ValueObject")
|
|
21
|
-
local TieMemberInterface = require("TieMemberInterface")
|
|
22
21
|
|
|
23
22
|
local UNSET_VALUE = Symbol.named("unsetValue")
|
|
24
23
|
|
|
@@ -48,18 +47,22 @@ end
|
|
|
48
47
|
function TiePropertyInterface:Observe()
|
|
49
48
|
return self:_observeValueBaseBrio():Pipe({
|
|
50
49
|
Rx.switchMap(function(brio)
|
|
51
|
-
if brio:IsDead() then
|
|
52
|
-
return Rx.of(nil)
|
|
53
|
-
end
|
|
54
|
-
local valueBase = brio:GetValue()
|
|
55
|
-
if not valueBase then
|
|
56
|
-
return Rx.of(nil)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
50
|
return Observable.new(function(sub)
|
|
60
|
-
|
|
51
|
+
if brio:IsDead() then
|
|
52
|
+
sub:Fire(nil)
|
|
53
|
+
sub:Complete()
|
|
54
|
+
return
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
local valueBase = brio:GetValue()
|
|
58
|
+
if not valueBase then
|
|
59
|
+
sub:Fire(nil)
|
|
60
|
+
sub:Complete()
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
local maid = brio:ToMaid()
|
|
61
65
|
|
|
62
|
-
sub:Fire(valueBase.Value)
|
|
63
66
|
maid:GiveTask(valueBase.Changed:Connect(function()
|
|
64
67
|
sub:Fire(valueBase.Value)
|
|
65
68
|
end))
|
|
@@ -70,6 +73,8 @@ function TiePropertyInterface:Observe()
|
|
|
70
73
|
end
|
|
71
74
|
end))
|
|
72
75
|
|
|
76
|
+
sub:Fire(valueBase.Value)
|
|
77
|
+
|
|
73
78
|
return maid
|
|
74
79
|
end)
|
|
75
80
|
end);
|
|
@@ -119,21 +124,9 @@ function TiePropertyInterface:_getFullName()
|
|
|
119
124
|
end
|
|
120
125
|
|
|
121
126
|
function TiePropertyInterface:_getChangedEvent()
|
|
122
|
-
return {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return TiePropertyChangedSignalConnection.new(function(connMaid)
|
|
126
|
-
local valueObject = connMaid:Add(ValueObject.new(nil) )
|
|
127
|
-
|
|
128
|
-
connMaid:GiveTask(self:Observe():Subscribe(function(value)
|
|
129
|
-
valueObject.Value = value
|
|
130
|
-
end))
|
|
131
|
-
|
|
132
|
-
-- After observing, so we can emit only changes.
|
|
133
|
-
connMaid:GiveTask(valueObject.Changed:Connect(callback))
|
|
134
|
-
end)
|
|
135
|
-
end;
|
|
136
|
-
}
|
|
127
|
+
return RxSignal.new(self:Observe():Pipe({
|
|
128
|
+
Rx.skip(1)
|
|
129
|
+
}))
|
|
137
130
|
end
|
|
138
131
|
|
|
139
132
|
local IMPLEMENTATION_TYPES = {
|
|
@@ -196,29 +189,29 @@ function TiePropertyInterface:_observeFromImplParent(implParent)
|
|
|
196
189
|
end
|
|
197
190
|
end
|
|
198
191
|
|
|
199
|
-
-- Subscribe to named children
|
|
200
|
-
topMaid:GiveTask(RxInstanceUtils.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
local innerMaid = brio:ToMaid()
|
|
207
|
-
local child = brio:GetValue()
|
|
192
|
+
-- Subscribe to named children, assuming no name changes...
|
|
193
|
+
topMaid:GiveTask(RxInstanceUtils.observeChildrenBrio(implParent, function(value)
|
|
194
|
+
return value.Name == memberName
|
|
195
|
+
end):Subscribe(function(brio)
|
|
196
|
+
if brio:IsDead() then
|
|
197
|
+
return
|
|
198
|
+
end
|
|
208
199
|
|
|
209
|
-
|
|
210
|
-
local index = table.find(validNamedChildren, child)
|
|
200
|
+
local innerMaid, child = brio:ToMaidAndValue()
|
|
211
201
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
end
|
|
202
|
+
innerMaid:GiveTask(function()
|
|
203
|
+
local index = table.find(validNamedChildren, child)
|
|
215
204
|
|
|
216
|
-
|
|
217
|
-
|
|
205
|
+
if index then
|
|
206
|
+
table.remove(validNamedChildren, index)
|
|
207
|
+
end
|
|
218
208
|
|
|
219
|
-
table.insert(validNamedChildren, child)
|
|
220
209
|
update()
|
|
221
|
-
end)
|
|
210
|
+
end)
|
|
211
|
+
|
|
212
|
+
table.insert(validNamedChildren, child)
|
|
213
|
+
update()
|
|
214
|
+
end))
|
|
222
215
|
|
|
223
216
|
topMaid:GiveTask(implParent:GetAttributeChangedSignal(memberName):Connect(update))
|
|
224
217
|
update()
|
|
@@ -89,6 +89,7 @@ function TieDefinition.new(definitionName, members)
|
|
|
89
89
|
local self = setmetatable({}, TieDefinition)
|
|
90
90
|
|
|
91
91
|
self._definitionName = assert(definitionName, "No definitionName")
|
|
92
|
+
self._validContainerNameSetWeakCache = setmetatable({}, {__mode = "kv"})
|
|
92
93
|
self._memberMap = {}
|
|
93
94
|
self._defaultTieRealm = TieRealms.SHARED
|
|
94
95
|
|
|
@@ -156,8 +157,41 @@ function TieDefinition:GetImplementations(adornee: Instance, tieRealm)
|
|
|
156
157
|
return implementations
|
|
157
158
|
end
|
|
158
159
|
|
|
159
|
-
function TieDefinition:
|
|
160
|
-
|
|
160
|
+
function TieDefinition:GetNewImplClass(tieRealm)
|
|
161
|
+
assert(TieRealmUtils.isTieRealm(tieRealm), "Bad tieRealm")
|
|
162
|
+
|
|
163
|
+
if tieRealm == TieRealms.CLIENT then
|
|
164
|
+
return "Configuration"
|
|
165
|
+
else
|
|
166
|
+
return "Camera"
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
local IMPL_CLIENT_SET = table.freeze({
|
|
171
|
+
["Configuration"] = true;
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
local IMPL_SERVER_SET = table.freeze({
|
|
175
|
+
["Camera"] = true;
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
local IMPL_SHARED_SET = table.freeze({
|
|
179
|
+
["Camera"] = true;
|
|
180
|
+
["Configuration"] = true;
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
function TieDefinition:GetImplClassSet(tieRealm)
|
|
184
|
+
|
|
185
|
+
if tieRealm == TieRealms.CLIENT then
|
|
186
|
+
-- Shared implements both...
|
|
187
|
+
return IMPL_CLIENT_SET
|
|
188
|
+
elseif tieRealm == TieRealms.SERVER then
|
|
189
|
+
return IMPL_SERVER_SET
|
|
190
|
+
elseif tieRealm == TieRealms.SHARED then
|
|
191
|
+
return IMPL_SHARED_SET
|
|
192
|
+
else
|
|
193
|
+
error("Unknwon tieRealm")
|
|
194
|
+
end
|
|
161
195
|
end
|
|
162
196
|
|
|
163
197
|
function TieDefinition:GetImplementationParents(adornee, tieRealm)
|
|
@@ -464,10 +498,11 @@ function TieDefinition:ObserveValidContainerChildrenBrio(adornee, tieRealm)
|
|
|
464
498
|
assert(TieRealmUtils.isTieRealm(tieRealm), "Bad tieRealm")
|
|
465
499
|
|
|
466
500
|
local validContainerNameSet = self:GetValidContainerNameSet(tieRealm)
|
|
501
|
+
local validImplClassSet = self:GetImplClassSet(tieRealm)
|
|
467
502
|
|
|
468
503
|
return RxInstanceUtils.observeChildrenBrio(adornee, function(value)
|
|
469
504
|
-- Just assume our name doesn't change
|
|
470
|
-
return value
|
|
505
|
+
return validImplClassSet[value.ClassName] and validContainerNameSet[value.Name] and true or false
|
|
471
506
|
end)
|
|
472
507
|
end
|
|
473
508
|
|
|
@@ -597,26 +632,34 @@ end
|
|
|
597
632
|
]=]
|
|
598
633
|
function TieDefinition:GetValidContainerNameSet(tieRealm)
|
|
599
634
|
-- TODO: Still generate unique datamodel key here?
|
|
635
|
+
if self._validContainerNameSetWeakCache[tieRealm] then
|
|
636
|
+
return self._validContainerNameSetWeakCache[tieRealm]
|
|
637
|
+
end
|
|
600
638
|
|
|
601
639
|
if tieRealm == TieRealms.CLIENT then
|
|
602
640
|
-- Shared implements both...
|
|
603
|
-
|
|
641
|
+
self._validContainerNameSetWeakCache[tieRealm] = table.freeze({
|
|
604
642
|
[self._definitionName .. "Client"] = true;
|
|
605
643
|
[self._definitionName .. "Shared"] = true;
|
|
606
|
-
}
|
|
644
|
+
})
|
|
645
|
+
return self._validContainerNameSetWeakCache[tieRealm]
|
|
607
646
|
elseif tieRealm == TieRealms.SERVER then
|
|
608
|
-
|
|
647
|
+
self._validContainerNameSetWeakCache[tieRealm] = table.freeze({
|
|
609
648
|
[self._definitionName] = true;
|
|
610
649
|
[self._definitionName .. "Shared"] = true;
|
|
611
|
-
}
|
|
650
|
+
})
|
|
651
|
+
return self._validContainerNameSetWeakCache[tieRealm]
|
|
612
652
|
elseif tieRealm == TieRealms.SHARED then
|
|
613
653
|
-- Technically on the implementation shared is very strict,
|
|
614
654
|
-- but we allow any calls here for discovery
|
|
615
|
-
|
|
655
|
+
self._validContainerNameSetWeakCache[tieRealm] = table.freeze({
|
|
616
656
|
[self._definitionName] = true;
|
|
617
657
|
[self._definitionName .. "Client"] = true;
|
|
618
658
|
[self._definitionName .. "Shared"] = true;
|
|
619
|
-
}
|
|
659
|
+
})
|
|
660
|
+
return self._validContainerNameSetWeakCache[tieRealm]
|
|
661
|
+
else
|
|
662
|
+
error("Unknwon tieRealm")
|
|
620
663
|
end
|
|
621
664
|
end
|
|
622
665
|
|
|
@@ -27,7 +27,7 @@ function TieImplementation.new(tieDefinition, adornee, implementer, implementati
|
|
|
27
27
|
self._actualSelf = implementer or {}
|
|
28
28
|
self._implementationTieRealm = assert(implementationTieRealm, "Bad implementationTieRealm")
|
|
29
29
|
|
|
30
|
-
self._implParent = self._maid:Add(Instance.new(tieDefinition:
|
|
30
|
+
self._implParent = self._maid:Add(Instance.new(tieDefinition:GetNewImplClass(implementationTieRealm)))
|
|
31
31
|
self._implParent.Archivable = false
|
|
32
32
|
|
|
33
33
|
self._memberImplementations = {}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
--[=[
|
|
2
|
-
@class TiePropertyChangedSignalConnection
|
|
3
|
-
]=]
|
|
4
|
-
|
|
5
|
-
local require = require(script.Parent.loader).load(script)
|
|
6
|
-
|
|
7
|
-
local Maid = require("Maid")
|
|
8
|
-
|
|
9
|
-
local TiePropertyChangedSignalConnection = {}
|
|
10
|
-
TiePropertyChangedSignalConnection.ClassName = "TiePropertyChangedSignalConnection"
|
|
11
|
-
TiePropertyChangedSignalConnection.__index = TiePropertyChangedSignalConnection
|
|
12
|
-
|
|
13
|
-
function TiePropertyChangedSignalConnection.new(connect)
|
|
14
|
-
local self = setmetatable({}, TiePropertyChangedSignalConnection)
|
|
15
|
-
|
|
16
|
-
self._maid = Maid.new()
|
|
17
|
-
|
|
18
|
-
self._connected = true
|
|
19
|
-
connect(self._maid)
|
|
20
|
-
|
|
21
|
-
return self
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
function TiePropertyChangedSignalConnection:Disconnect()
|
|
25
|
-
self:Destroy()
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
function TiePropertyChangedSignalConnection:__index(index)
|
|
29
|
-
if index == "IsConnected" then
|
|
30
|
-
return self._connected
|
|
31
|
-
elseif TiePropertyChangedSignalConnection[index] then
|
|
32
|
-
return TiePropertyChangedSignalConnection[index]
|
|
33
|
-
else
|
|
34
|
-
error(string.format("Bad index %q for TiePropertyChangedSignalConnection", tostring(index)))
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
function TiePropertyChangedSignalConnection:Destroy()
|
|
39
|
-
self._connected = false
|
|
40
|
-
self._maid:DoCleaning()
|
|
41
|
-
-- Avoid setting the metatable so calling methods is always valid
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
return TiePropertyChangedSignalConnection
|