@quenty/tie 5.1.1 → 5.1.2-canary.433.80025dc.0
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 +11 -0
- package/package.json +18 -18
- package/src/Shared/Definition/TieDefinition.lua +47 -12
- package/src/Shared/Definition/TieMethodDefinition.lua +16 -1
- package/src/Shared/Definition/TiePropertyDefinition.lua +17 -1
- package/src/Shared/Definition/TieSignalDefinition.lua +17 -1
- package/src/Shared/Definition/Types/TieRealmUtils.lua +60 -0
- package/src/Shared/Definition/Types/TieRealms.lua +16 -0
- package/src/Shared/Implementation/TieImplementation.lua +37 -12
- package/src/Shared/Interface/TieInterface.lua +22 -3
- package/src/Shared/Interface/TieMethodInterfaceUtils.lua +1 -1
- package/src/Shared/Interface/TiePropertyInterface.lua +13 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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
|
+
## [5.1.2-canary.433.80025dc.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/tie@5.1.1...@quenty/tie@5.1.2-canary.433.80025dc.0) (2023-12-14)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Add realm support to tie ([cefc3fc](https://github.com/Quenty/NevermoreEngine/commit/cefc3fcd40287c85bd68e0f3438c15d701560df0))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [5.1.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/tie@5.1.0...@quenty/tie@5.1.1) (2023-10-28)
|
|
7
18
|
|
|
8
19
|
**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": "5.1.
|
|
3
|
+
"version": "5.1.2-canary.433.80025dc.0",
|
|
4
4
|
"description": "Tie allows interfaces to be defined between Lua OOP and Roblox objects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -28,27 +28,27 @@
|
|
|
28
28
|
"Quenty"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@quenty/attributeutils": "
|
|
32
|
-
"@quenty/baseobject": "
|
|
33
|
-
"@quenty/brio": "
|
|
34
|
-
"@quenty/collectionserviceutils": "
|
|
35
|
-
"@quenty/instanceutils": "
|
|
36
|
-
"@quenty/loader": "
|
|
37
|
-
"@quenty/maid": "
|
|
38
|
-
"@quenty/rx": "
|
|
39
|
-
"@quenty/statestack": "
|
|
40
|
-
"@quenty/string": "
|
|
41
|
-
"@quenty/symbol": "
|
|
42
|
-
"@quenty/table": "
|
|
43
|
-
"@quenty/valuebaseutils": "
|
|
44
|
-
"@quenty/valueobject": "
|
|
31
|
+
"@quenty/attributeutils": "9.1.2-canary.433.80025dc.0",
|
|
32
|
+
"@quenty/baseobject": "7.0.1-canary.433.80025dc.0",
|
|
33
|
+
"@quenty/brio": "9.1.2-canary.433.80025dc.0",
|
|
34
|
+
"@quenty/collectionserviceutils": "3.1.2-canary.433.80025dc.0",
|
|
35
|
+
"@quenty/instanceutils": "8.1.2-canary.433.80025dc.0",
|
|
36
|
+
"@quenty/loader": "7.0.1-canary.433.80025dc.0",
|
|
37
|
+
"@quenty/maid": "2.6.0",
|
|
38
|
+
"@quenty/rx": "8.1.2-canary.433.80025dc.0",
|
|
39
|
+
"@quenty/statestack": "9.1.2-canary.433.80025dc.0",
|
|
40
|
+
"@quenty/string": "3.1.0",
|
|
41
|
+
"@quenty/symbol": "2.2.0",
|
|
42
|
+
"@quenty/table": "3.3.1-canary.433.80025dc.0",
|
|
43
|
+
"@quenty/valuebaseutils": "8.1.2-canary.433.80025dc.0",
|
|
44
|
+
"@quenty/valueobject": "8.1.2-canary.433.80025dc.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@quenty/promise": "
|
|
48
|
-
"@quenty/signal": "
|
|
47
|
+
"@quenty/promise": "7.0.1-canary.433.80025dc.0",
|
|
48
|
+
"@quenty/signal": "3.0.1-canary.433.80025dc.0"
|
|
49
49
|
},
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "80025dcd926765b502d322bb84e013b973409d8c"
|
|
54
54
|
}
|
|
@@ -23,6 +23,7 @@ local TieMethodDefinition = require("TieMethodDefinition")
|
|
|
23
23
|
local TiePropertyDefinition = require("TiePropertyDefinition")
|
|
24
24
|
local TieSignalDefinition = require("TieSignalDefinition")
|
|
25
25
|
local ValueObject = require("ValueObject")
|
|
26
|
+
local TieRealms = require("TieRealms")
|
|
26
27
|
|
|
27
28
|
local UNSET_VALUE = Symbol.named("unsetValue")
|
|
28
29
|
|
|
@@ -36,6 +37,8 @@ TieDefinition.Types = Table.readonly({
|
|
|
36
37
|
PROPERTY = Symbol.named("property"); -- will default to nil
|
|
37
38
|
})
|
|
38
39
|
|
|
40
|
+
TieDefinition.Realms = TieRealms
|
|
41
|
+
|
|
39
42
|
function TieDefinition.new(definitionName, members, isSharedDefinition)
|
|
40
43
|
local self = setmetatable({}, TieDefinition)
|
|
41
44
|
|
|
@@ -44,21 +47,35 @@ function TieDefinition.new(definitionName, members, isSharedDefinition)
|
|
|
44
47
|
|
|
45
48
|
self._isSharedDefinition = isSharedDefinition
|
|
46
49
|
|
|
50
|
+
self:_addMembers(members, TieDefinition.Realms.SHARED)
|
|
51
|
+
|
|
52
|
+
return self
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
function TieDefinition:_addMembers(members, realm)
|
|
47
56
|
for memberName, memberTypeOrDefaultValue in pairs(members) do
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
self
|
|
52
|
-
elseif memberTypeOrDefaultValue == TieDefinition.Types.SIGNAL then
|
|
53
|
-
self._memberMap[memberName] = TieSignalDefinition.new(self, memberName)
|
|
54
|
-
elseif memberTypeOrDefaultValue == TieDefinition.Types.PROPERTY then
|
|
55
|
-
self._memberMap[memberName] = TiePropertyDefinition.new(self, memberName, nil)
|
|
57
|
+
if memberName == TieRealms.CLIENT then
|
|
58
|
+
self:_addMembers(memberTypeOrDefaultValue, TieRealms.CLIENT)
|
|
59
|
+
elseif memberName == TieRealms.SERVER then
|
|
60
|
+
self:_addMembers(memberTypeOrDefaultValue, TieRealms.SERVER)
|
|
56
61
|
else
|
|
57
|
-
|
|
62
|
+
assert(type(memberName) == "string", "Bad memberName")
|
|
63
|
+
|
|
64
|
+
self:_addMember(memberName, memberTypeOrDefaultValue, realm)
|
|
58
65
|
end
|
|
59
66
|
end
|
|
67
|
+
end
|
|
60
68
|
|
|
61
|
-
|
|
69
|
+
function TieDefinition:_addMember(memberName, memberTypeOrDefaultValue, realm)
|
|
70
|
+
if memberTypeOrDefaultValue == TieDefinition.Types.METHOD then
|
|
71
|
+
self._memberMap[memberName] = TieMethodDefinition.new(self, memberName, realm)
|
|
72
|
+
elseif memberTypeOrDefaultValue == TieDefinition.Types.SIGNAL then
|
|
73
|
+
self._memberMap[memberName] = TieSignalDefinition.new(self, memberName, realm)
|
|
74
|
+
elseif memberTypeOrDefaultValue == TieDefinition.Types.PROPERTY then
|
|
75
|
+
self._memberMap[memberName] = TiePropertyDefinition.new(self, memberName, nil, realm)
|
|
76
|
+
else
|
|
77
|
+
self._memberMap[memberName] = TiePropertyDefinition.new(self, memberName, memberTypeOrDefaultValue, realm)
|
|
78
|
+
end
|
|
62
79
|
end
|
|
63
80
|
|
|
64
81
|
--[=[
|
|
@@ -348,7 +365,11 @@ function TieDefinition:_observeImplementation(folder)
|
|
|
348
365
|
update()
|
|
349
366
|
end))
|
|
350
367
|
|
|
351
|
-
for memberName, member in pairs(self
|
|
368
|
+
for memberName, member in pairs(self:GetMemberMap()) do
|
|
369
|
+
if not member:IsAllowed() then
|
|
370
|
+
continue
|
|
371
|
+
end
|
|
372
|
+
|
|
352
373
|
if member.ClassName == "TiePropertyDefinition" then
|
|
353
374
|
maid:GiveTask(folder:GetAttributeChangedSignal(memberName):Connect(update))
|
|
354
375
|
end
|
|
@@ -411,6 +432,10 @@ function TieDefinition:GetName(): string
|
|
|
411
432
|
return self._definitionName
|
|
412
433
|
end
|
|
413
434
|
|
|
435
|
+
function TieDefinition:GetContainerNameForServer()
|
|
436
|
+
return self._definitionName
|
|
437
|
+
end
|
|
438
|
+
|
|
414
439
|
function TieDefinition:GetContainerName(): string
|
|
415
440
|
if RunService:IsClient() and not self._isSharedDefinition then
|
|
416
441
|
return self._definitionName .. "Client"
|
|
@@ -423,6 +448,12 @@ function TieDefinition:GetMemberMap()
|
|
|
423
448
|
return self._memberMap
|
|
424
449
|
end
|
|
425
450
|
|
|
451
|
+
--[=[
|
|
452
|
+
Returns true if the folder is an implementation
|
|
453
|
+
|
|
454
|
+
@param folder Folder
|
|
455
|
+
@return boolean
|
|
456
|
+
]=]
|
|
426
457
|
function TieDefinition:IsImplementation(folder)
|
|
427
458
|
local attributes = folder:GetAttributes()
|
|
428
459
|
local children = {}
|
|
@@ -430,7 +461,11 @@ function TieDefinition:IsImplementation(folder)
|
|
|
430
461
|
children[item.Name] = item
|
|
431
462
|
end
|
|
432
463
|
|
|
433
|
-
for memberName, member in pairs(self
|
|
464
|
+
for memberName, member in pairs(self:GetMemberMap()) do
|
|
465
|
+
if not member:IsRequired() then
|
|
466
|
+
continue
|
|
467
|
+
end
|
|
468
|
+
|
|
434
469
|
local found = children[memberName]
|
|
435
470
|
if not found then
|
|
436
471
|
if member.ClassName == "TiePropertyDefinition" then
|
|
@@ -6,20 +6,32 @@ local require = require(script.Parent.loader).load(script)
|
|
|
6
6
|
|
|
7
7
|
local TieMethodImplementation = require("TieMethodImplementation")
|
|
8
8
|
local TieMethodInterfaceUtils = require("TieMethodInterfaceUtils")
|
|
9
|
+
local TieRealmUtils = require("TieRealmUtils")
|
|
9
10
|
|
|
10
11
|
local TieMethodDefinition = {}
|
|
11
12
|
TieMethodDefinition.ClassName = "TieMethodDefinition"
|
|
12
13
|
TieMethodDefinition.__index = TieMethodDefinition
|
|
13
14
|
|
|
14
|
-
function TieMethodDefinition.new(tieDefinition, methodName)
|
|
15
|
+
function TieMethodDefinition.new(tieDefinition, methodName, realm)
|
|
15
16
|
local self = setmetatable({}, TieMethodDefinition)
|
|
16
17
|
|
|
17
18
|
self._tieDefinition = assert(tieDefinition, "No tieDefinition")
|
|
18
19
|
self._methodName = assert(methodName, "No methodName")
|
|
20
|
+
self._tieRealm = assert(realm, "No realm")
|
|
21
|
+
self._isRequired = TieRealmUtils.isRequired(self._tieRealm)
|
|
22
|
+
self._isAllowed = TieRealmUtils.isAllowed(self._tieRealm)
|
|
19
23
|
|
|
20
24
|
return self
|
|
21
25
|
end
|
|
22
26
|
|
|
27
|
+
function TieMethodDefinition:IsRequired()
|
|
28
|
+
return self._isRequired
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
function TieMethodDefinition:IsAllowed()
|
|
32
|
+
return self._isAllowed
|
|
33
|
+
end
|
|
34
|
+
|
|
23
35
|
function TieMethodDefinition:Implement(folder, initialValue, actualSelf)
|
|
24
36
|
assert(typeof(folder) == "Instance", "Bad folder")
|
|
25
37
|
assert(actualSelf, "No actualSelf")
|
|
@@ -34,6 +46,9 @@ function TieMethodDefinition:GetInterface(folder: Folder, aliasSelf)
|
|
|
34
46
|
return TieMethodInterfaceUtils.get(aliasSelf, self._tieDefinition, self, folder, nil)
|
|
35
47
|
end
|
|
36
48
|
|
|
49
|
+
function TieMethodDefinition:GetTieRealm()
|
|
50
|
+
return self._tieRealm
|
|
51
|
+
end
|
|
37
52
|
|
|
38
53
|
function TieMethodDefinition:GetTieDefinition()
|
|
39
54
|
return self._tieDefinition
|
|
@@ -7,17 +7,21 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
7
|
local BaseObject = require("BaseObject")
|
|
8
8
|
local TiePropertyImplementation = require("TiePropertyImplementation")
|
|
9
9
|
local TiePropertyInterface = require("TiePropertyInterface")
|
|
10
|
+
local TieRealmUtils = require("TieRealmUtils")
|
|
10
11
|
|
|
11
12
|
local TiePropertyDefinition = setmetatable({}, BaseObject)
|
|
12
13
|
TiePropertyDefinition.ClassName = "TiePropertyDefinition"
|
|
13
14
|
TiePropertyDefinition.__index = TiePropertyDefinition
|
|
14
15
|
|
|
15
|
-
function TiePropertyDefinition.new(tieDefinition, propertyName: string, defaultValue: any)
|
|
16
|
+
function TiePropertyDefinition.new(tieDefinition, propertyName: string, defaultValue: any, realm)
|
|
16
17
|
local self = setmetatable(BaseObject.new(), TiePropertyDefinition)
|
|
17
18
|
|
|
18
19
|
self._tieDefinition = assert(tieDefinition, "No tieDefinition")
|
|
19
20
|
self._propertyName = assert(propertyName, "No propertyName")
|
|
20
21
|
self._defaultValue = defaultValue
|
|
22
|
+
self._tieRealm = assert(realm, "No realm")
|
|
23
|
+
self._isRequired = TieRealmUtils.isRequired(self._tieRealm)
|
|
24
|
+
self._isAllowed = TieRealmUtils.isAllowed(self._tieRealm)
|
|
21
25
|
|
|
22
26
|
return self
|
|
23
27
|
end
|
|
@@ -30,6 +34,18 @@ function TiePropertyDefinition:GetDefaultValue()
|
|
|
30
34
|
return self._defaultValue
|
|
31
35
|
end
|
|
32
36
|
|
|
37
|
+
function TiePropertyDefinition:IsRequired()
|
|
38
|
+
return self._isRequired
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
function TiePropertyDefinition:IsAllowed()
|
|
42
|
+
return self._isAllowed
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
function TiePropertyDefinition:GetTieRealm()
|
|
46
|
+
return self._tieRealm
|
|
47
|
+
end
|
|
48
|
+
|
|
33
49
|
function TiePropertyDefinition:Implement(folder: Folder, initialValue)
|
|
34
50
|
assert(typeof(folder) == "Instance", "Bad folder")
|
|
35
51
|
|
|
@@ -6,16 +6,20 @@ local require = require(script.Parent.loader).load(script)
|
|
|
6
6
|
|
|
7
7
|
local TieSignalImplementation = require("TieSignalImplementation")
|
|
8
8
|
local TieSignalInterface = require("TieSignalInterface")
|
|
9
|
+
local TieRealmUtils = require("TieRealmUtils")
|
|
9
10
|
|
|
10
11
|
local TieSignalDefinition = {}
|
|
11
12
|
TieSignalDefinition.ClassName = "TieSignalDefinition"
|
|
12
13
|
TieSignalDefinition.__index = TieSignalDefinition
|
|
13
14
|
|
|
14
|
-
function TieSignalDefinition.new(tieDefinition, signalName)
|
|
15
|
+
function TieSignalDefinition.new(tieDefinition, signalName, realm)
|
|
15
16
|
local self = setmetatable({}, TieSignalDefinition)
|
|
16
17
|
|
|
17
18
|
self._tieDefinition = assert(tieDefinition, "No tieDefinition")
|
|
18
19
|
self._signalName = assert(signalName, "No signalName")
|
|
20
|
+
self._tieRealm = assert(realm, "No realm")
|
|
21
|
+
self._isRequired = TieRealmUtils.isRequired(self._tieRealm)
|
|
22
|
+
self._isAllowed = TieRealmUtils.isAllowed(self._tieRealm)
|
|
19
23
|
|
|
20
24
|
return self
|
|
21
25
|
end
|
|
@@ -24,6 +28,18 @@ function TieSignalDefinition:GetTieDefinition()
|
|
|
24
28
|
return self._tieDefinition
|
|
25
29
|
end
|
|
26
30
|
|
|
31
|
+
function TieSignalDefinition:IsRequired()
|
|
32
|
+
return self._isRequired
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
function TieSignalDefinition:IsAllowed()
|
|
36
|
+
return self._isAllowed
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
function TieSignalDefinition:GetTieRealm()
|
|
40
|
+
return self._tieRealm
|
|
41
|
+
end
|
|
42
|
+
|
|
27
43
|
function TieSignalDefinition:Implement(folder, initialValue)
|
|
28
44
|
assert(typeof(folder) == "Instance", "Bad folder")
|
|
29
45
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
--[=[
|
|
2
|
+
@class TieRealmUtils
|
|
3
|
+
]=]
|
|
4
|
+
|
|
5
|
+
local require = require(script.Parent.loader).load(script)
|
|
6
|
+
|
|
7
|
+
local RunService = game:GetService("RunService")
|
|
8
|
+
local TieRealms = require("TieRealms")
|
|
9
|
+
|
|
10
|
+
local TieRealmUtils = {}
|
|
11
|
+
|
|
12
|
+
function TieRealmUtils.isRequired(tieRealm)
|
|
13
|
+
if tieRealm == TieRealms.CLIENT then
|
|
14
|
+
-- Hack: TODO: Maybe we should contextualize the realm throughout all callers.
|
|
15
|
+
-- But otherwise, we'll need to do this
|
|
16
|
+
if not RunService:IsRunning() then
|
|
17
|
+
return false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
return RunService:IsClient()
|
|
21
|
+
elseif tieRealm == TieRealms.SERVER then
|
|
22
|
+
-- Hack: TODO: Maybe we should contextualize the realm throughout all callers.
|
|
23
|
+
-- But otherwise, we'll need to do this
|
|
24
|
+
if not RunService:IsRunning() then
|
|
25
|
+
return false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
return RunService:IsServer()
|
|
29
|
+
elseif tieRealm == TieRealms.SHARED then
|
|
30
|
+
return true
|
|
31
|
+
else
|
|
32
|
+
error("Unknown tieRealm")
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
function TieRealmUtils.isAllowed(tieRealm)
|
|
37
|
+
if tieRealm == TieRealms.CLIENT then
|
|
38
|
+
-- Hack: TODO: Maybe we should contextualize the realm throughout all callers.
|
|
39
|
+
-- But otherwise, we'll need to do this
|
|
40
|
+
if not RunService:IsRunning() then
|
|
41
|
+
return true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
return RunService:IsClient()
|
|
45
|
+
elseif tieRealm == TieRealms.SERVER then
|
|
46
|
+
-- Hack: TODO: Maybe we should contextualize the realm throughout all callers.
|
|
47
|
+
-- But otherwise, we'll need to do this
|
|
48
|
+
if not RunService:IsRunning() then
|
|
49
|
+
return true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
return RunService:IsServer()
|
|
53
|
+
elseif tieRealm == TieRealms.SHARED then
|
|
54
|
+
return true
|
|
55
|
+
else
|
|
56
|
+
error("Unknown tieRealm")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
return TieRealmUtils
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
--[=[
|
|
2
|
+
Realms sort of have to be a first class citizen...
|
|
3
|
+
|
|
4
|
+
@class TieRealms
|
|
5
|
+
]=]
|
|
6
|
+
|
|
7
|
+
local require = require(script.Parent.loader).load(script)
|
|
8
|
+
|
|
9
|
+
local Table = require("Table")
|
|
10
|
+
local Symbol = require("Symbol")
|
|
11
|
+
|
|
12
|
+
return Table.readonly({
|
|
13
|
+
SHARED = Symbol.named("shared");
|
|
14
|
+
CLIENT = Symbol.named("client");
|
|
15
|
+
SERVER = Symbol.named("server");
|
|
16
|
+
})
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
local require = require(script.Parent.loader).load(script)
|
|
10
10
|
|
|
11
11
|
local BaseObject = require("BaseObject")
|
|
12
|
+
local TieRealms = require("TieRealms")
|
|
12
13
|
|
|
13
14
|
local TieImplementation = setmetatable({}, BaseObject)
|
|
14
15
|
TieImplementation.ClassName = "TieImplementation"
|
|
@@ -21,10 +22,8 @@ function TieImplementation.new(tieDefinition, adornee, implementer)
|
|
|
21
22
|
self._adornee = assert(adornee, "No adornee")
|
|
22
23
|
self._actualSelf = implementer or {}
|
|
23
24
|
|
|
24
|
-
self._folder = Instance.new("Folder")
|
|
25
|
-
self._folder.Name = self._definition:GetContainerName()
|
|
25
|
+
self._folder = self._maid:Add(Instance.new("Folder"))
|
|
26
26
|
self._folder.Archivable = false
|
|
27
|
-
self._maid:GiveTask(self._folder)
|
|
28
27
|
|
|
29
28
|
self._memberImplementations = {}
|
|
30
29
|
self._memberMap = self._definition:GetMemberMap()
|
|
@@ -56,8 +55,13 @@ function TieImplementation:__index(index)
|
|
|
56
55
|
end
|
|
57
56
|
|
|
58
57
|
local memberMap = rawget(self, "_memberMap")
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
local memberDefinition = memberMap[index]
|
|
59
|
+
if memberDefinition then
|
|
60
|
+
if memberDefinition:IsAllowed() then
|
|
61
|
+
return memberDefinition:GetInterface(self._folder, self)
|
|
62
|
+
else
|
|
63
|
+
error(string.format("%q is not a valid member", tostring(index)))
|
|
64
|
+
end
|
|
61
65
|
else
|
|
62
66
|
error(string.format("Bad index %q for TieImplementation", tostring(index)))
|
|
63
67
|
end
|
|
@@ -75,30 +79,51 @@ function TieImplementation:__newindex(index, value)
|
|
|
75
79
|
elseif self._memberImplementations[index] then
|
|
76
80
|
self._memberImplementations[index]:SetImplementation(value, self._actualSelf)
|
|
77
81
|
elseif TieImplementation[index] then
|
|
78
|
-
error(("Cannot set %q in TieImplementation"
|
|
82
|
+
error(string.format("Cannot set %q in TieImplementation", tostring(index)))
|
|
79
83
|
else
|
|
80
|
-
error(("Bad index %q for TieImplementation"
|
|
84
|
+
error(string.format("Bad index %q for TieImplementation", tostring(index)))
|
|
81
85
|
end
|
|
82
86
|
end
|
|
83
87
|
|
|
84
88
|
function TieImplementation:_buildMemberImplementations(implementer)
|
|
85
|
-
|
|
89
|
+
local allClientImplemented = true
|
|
90
|
+
|
|
91
|
+
for _, memberDefinition in pairs(self._memberMap) do
|
|
92
|
+
if not memberDefinition:IsAllowed() then
|
|
93
|
+
if memberDefinition:GetTieRealm() == TieRealms.CLIENT then
|
|
94
|
+
allClientImplemented = false
|
|
95
|
+
end
|
|
96
|
+
continue
|
|
97
|
+
end
|
|
98
|
+
|
|
86
99
|
local initialValue
|
|
87
100
|
if implementer then
|
|
88
101
|
local memberName = memberDefinition:GetMemberName()
|
|
89
102
|
initialValue = implementer[memberName]
|
|
90
103
|
if not initialValue then
|
|
91
|
-
|
|
104
|
+
if memberDefinition:IsRequired() then
|
|
105
|
+
error(string.format("Missing member %q on %q", memberName, self._adornee:GetFullName()))
|
|
106
|
+
else
|
|
107
|
+
if memberDefinition:GetTieRealm() == TieRealms.CLIENT then
|
|
108
|
+
allClientImplemented = false
|
|
109
|
+
end
|
|
110
|
+
continue
|
|
111
|
+
end
|
|
92
112
|
end
|
|
93
113
|
else
|
|
94
114
|
initialValue = nil
|
|
95
115
|
end
|
|
96
116
|
|
|
97
|
-
local memberImplementation = memberDefinition:Implement(self._folder, initialValue, self._actualSelf)
|
|
98
|
-
self._maid:GiveTask(memberImplementation)
|
|
99
|
-
|
|
117
|
+
local memberImplementation = self._maid:Add(memberDefinition:Implement(self._folder, initialValue, self._actualSelf))
|
|
100
118
|
self._memberImplementations[memberDefinition:GetMemberName()] = memberImplementation
|
|
101
119
|
end
|
|
120
|
+
|
|
121
|
+
-- Hack to make server objects look like server
|
|
122
|
+
if allClientImplemented then
|
|
123
|
+
self._folder.Name = self._definition:GetContainerName()
|
|
124
|
+
else
|
|
125
|
+
self._folder.Name = self._definition:GetContainerNameForServer()
|
|
126
|
+
end
|
|
102
127
|
end
|
|
103
128
|
|
|
104
129
|
return TieImplementation
|
|
@@ -52,6 +52,25 @@ function TieInterface:IsImplemented()
|
|
|
52
52
|
return definition:HasImplementation(adornee)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
--[=[
|
|
56
|
+
Gets the adornee the tie interface is on if it can be found.
|
|
57
|
+
|
|
58
|
+
@return Instance | nil
|
|
59
|
+
]=]
|
|
60
|
+
function TieInterface:GetTieAdornee()
|
|
61
|
+
local adornee = rawget(self, "_adornee")
|
|
62
|
+
if adornee then
|
|
63
|
+
return adornee
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
local folder = rawget(self, "_folder")
|
|
67
|
+
if folder then
|
|
68
|
+
return folder.Parent
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
return nil
|
|
72
|
+
end
|
|
73
|
+
|
|
55
74
|
--[=[
|
|
56
75
|
@return Observable<boolean>
|
|
57
76
|
]=]
|
|
@@ -74,7 +93,7 @@ end
|
|
|
74
93
|
function TieInterface:__index(index)
|
|
75
94
|
local member = rawget(self, "_memberDefinitionMap")[index]
|
|
76
95
|
local definition = rawget(self, "_definition")
|
|
77
|
-
if member then
|
|
96
|
+
if member and member:IsAllowed() then
|
|
78
97
|
if member.ClassName == "TieMethodDefinition" then
|
|
79
98
|
local adornee = rawget(self, "_adornee")
|
|
80
99
|
local folder = rawget(self, "_folder")
|
|
@@ -91,12 +110,12 @@ function TieInterface:__index(index)
|
|
|
91
110
|
|
|
92
111
|
return TiePropertyInterface.new(folder, adornee, member)
|
|
93
112
|
else
|
|
94
|
-
error(("Unknown member definition %q"
|
|
113
|
+
error(string.format("Unknown member definition %q", tostring(member.ClassName)))
|
|
95
114
|
end
|
|
96
115
|
elseif TieInterface[index] then
|
|
97
116
|
return TieInterface[index]
|
|
98
117
|
else
|
|
99
|
-
error(("Bad %q is not a member of %s"
|
|
118
|
+
error(string.format("Bad %q is not a member of %s", tostring(index), definition:GetContainerName()))
|
|
100
119
|
end
|
|
101
120
|
end
|
|
102
121
|
|
|
@@ -33,7 +33,7 @@ function TieMethodInterfaceUtils.get(aliasSelf, definition, member, folder, ador
|
|
|
33
33
|
|
|
34
34
|
local bindableFunction = folder:FindFirstChild(member:GetMemberName())
|
|
35
35
|
if not bindableFunction then
|
|
36
|
-
error("No bindableFunction")
|
|
36
|
+
error(string.format("No bindableFunction implemented for %s on %q", member:GetMemberName(), folder:GetFullName()))
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
return TieUtils.decode(bindableFunction:Invoke(TieUtils.encode(...)))
|
|
@@ -39,6 +39,19 @@ function TiePropertyInterface.new(folder, adornee, memberDefinition)
|
|
|
39
39
|
return self
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
function TiePropertyInterface:ObserveBrio(predicate)
|
|
43
|
+
return self:_observeValueBaseBrio():Pipe({
|
|
44
|
+
RxBrioUtils.switchMapBrio(function(valueBase)
|
|
45
|
+
if typeof(valueBase) == "Instance" then
|
|
46
|
+
return RxInstanceUtils.observePropertyBrio(valueBase, "Value", predicate)
|
|
47
|
+
else
|
|
48
|
+
-- TODO: Maybe don't assumet his exists and use a helper method instead.
|
|
49
|
+
return valueBase:ObserveBrio(predicate)
|
|
50
|
+
end
|
|
51
|
+
end);
|
|
52
|
+
})
|
|
53
|
+
end
|
|
54
|
+
|
|
42
55
|
function TiePropertyInterface:Observe()
|
|
43
56
|
return self:_observeValueBaseBrio():Pipe({
|
|
44
57
|
Rx.switchMap(function(brio)
|