@quenty/adorneedata 7.3.0 → 7.4.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
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
|
+
# [7.4.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/adorneedata@7.3.0...@quenty/adorneedata@7.4.0) (2024-05-18)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Add AdorneeData docs and ability to use indirectly ([8df4e84](https://github.com/Quenty/NevermoreEngine/commit/8df4e844c027ec196476306d472c7c8e4625c53f))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [7.3.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/adorneedata@7.2.0...@quenty/adorneedata@7.3.0) (2024-05-09)
|
|
7
18
|
|
|
8
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/adorneedata",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.0",
|
|
4
4
|
"description": "Bridges attributes and serialization",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "a9256cab3584bea4bd32c327d00b9a52f2a3ec95"
|
|
41
41
|
}
|
|
@@ -7,6 +7,67 @@
|
|
|
7
7
|
|
|
8
8
|
Providing all 3
|
|
9
9
|
|
|
10
|
+
## Usage
|
|
11
|
+
Here's how the usage works:
|
|
12
|
+
|
|
13
|
+
```lua
|
|
14
|
+
-- Store data somewhere central
|
|
15
|
+
|
|
16
|
+
return AdorneeData.new({
|
|
17
|
+
EnableCombat = true;
|
|
18
|
+
PunchDamage = 15;
|
|
19
|
+
})
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
You can then use the data to retrieve values
|
|
23
|
+
|
|
24
|
+
```lua
|
|
25
|
+
local data = CombatConfiguration:CreateValue(workspace)
|
|
26
|
+
|
|
27
|
+
-- Can ready any data
|
|
28
|
+
print(data.EnableCombat.Value) --> true
|
|
29
|
+
print(data.PunchDamage.Value) --> 15
|
|
30
|
+
print(data.Value) --> { EnableCombat = true, PunchDamage = true }
|
|
31
|
+
|
|
32
|
+
-- Can write any data
|
|
33
|
+
data.EnableCombat.Value = false
|
|
34
|
+
data.PunchDamage.Value = 15
|
|
35
|
+
data.Value = {
|
|
36
|
+
EnableCombat = false;
|
|
37
|
+
PunchDamage = 150;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
-- Can subscribe to the data
|
|
41
|
+
data.EnableCombat:Observe():Subscribe(print)
|
|
42
|
+
data.PunchDamage:Observe():Subscribe(print)
|
|
43
|
+
data:Observe():Subscribe(print)
|
|
44
|
+
|
|
45
|
+
-- Can also operate without creating a value (although creating value is cheap)
|
|
46
|
+
local punchDamage = CombatConfiguration.PunchDamage:Create(workspace)
|
|
47
|
+
punchDamage.Value = 20
|
|
48
|
+
punchDamage:Observe():Subscribe(print)
|
|
49
|
+
|
|
50
|
+
-- Or like this
|
|
51
|
+
CombatConfiguration.PunchDamage:SetValue(workspace, 25)
|
|
52
|
+
print(CombatConfiguration.PunchDamage:GetValue(workspace))
|
|
53
|
+
CombatConfiguration.PunchDamage:Observe(workspace):Subscribe(print)
|
|
54
|
+
|
|
55
|
+
-- You can also create validated data
|
|
56
|
+
local defaultCombatState = CombatConfiguration:CreateData({
|
|
57
|
+
EnableCombat = true;
|
|
58
|
+
PunchDamage = 15;
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
-- Or validate that the data you're getting is valid
|
|
62
|
+
assert(CombatConfiguration:IsData(defaultCombatState))
|
|
63
|
+
|
|
64
|
+
-- Or read attributes directly
|
|
65
|
+
CombatConfiguration:GetAttributes(workspace))
|
|
66
|
+
|
|
67
|
+
-- Note that this is the same as an attribute
|
|
68
|
+
print(workspace:GetAttribute("EnableCombat")) --> true
|
|
69
|
+
```
|
|
70
|
+
|
|
10
71
|
@class AdorneeData
|
|
11
72
|
]=]
|
|
12
73
|
|
|
@@ -15,6 +76,7 @@ local require = require(script.Parent.loader).load(script)
|
|
|
15
76
|
local AdorneeDataEntry = require("AdorneeDataEntry")
|
|
16
77
|
local AdorneeDataValue = require("AdorneeDataValue")
|
|
17
78
|
local AttributeUtils = require("AttributeUtils")
|
|
79
|
+
local AttributeValue = require("AttributeValue")
|
|
18
80
|
local t = require("t")
|
|
19
81
|
|
|
20
82
|
local AdorneeData = {}
|
|
@@ -49,6 +111,26 @@ function AdorneeData.new(prototype)
|
|
|
49
111
|
return self
|
|
50
112
|
end
|
|
51
113
|
|
|
114
|
+
function AdorneeData:__index(index)
|
|
115
|
+
if AdorneeData[index] then
|
|
116
|
+
return AdorneeData[index]
|
|
117
|
+
elseif type(index) == "string" then
|
|
118
|
+
local found = self._fullPrototype[index]
|
|
119
|
+
if not found then
|
|
120
|
+
error(string.format("[AdorneeData] - Bad index %q is not a known adornee", index))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
if AdorneeDataEntry.isAdorneeDataEntry(found) then
|
|
124
|
+
return found
|
|
125
|
+
else
|
|
126
|
+
-- TODO: Cache this construction
|
|
127
|
+
return AdorneeDataEntry.new(index, function(adornee)
|
|
128
|
+
return AttributeValue.new(adornee, index, found)
|
|
129
|
+
end)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
52
134
|
--[=[
|
|
53
135
|
Returns true if the data is valid data, otherwise returns false and an error.
|
|
54
136
|
|
|
@@ -165,7 +247,7 @@ function AdorneeData:GetAttributes(adornee)
|
|
|
165
247
|
|
|
166
248
|
-- TODO: Avoid additional allocation
|
|
167
249
|
for key, value in pairs(self._valueObjectPrototype) do
|
|
168
|
-
data[key] = value:
|
|
250
|
+
data[key] = value:Create(adornee).Value
|
|
169
251
|
end
|
|
170
252
|
|
|
171
253
|
return self:CreateStrictData(data)
|
|
@@ -203,7 +285,7 @@ function AdorneeData:SetStrictAttributes(adornee, data)
|
|
|
203
285
|
|
|
204
286
|
-- TODO: Avoid additional allocation
|
|
205
287
|
for key, value in pairs(self._valueObjectPrototype) do
|
|
206
|
-
value:
|
|
288
|
+
value:Create(adornee).Value = data[key]
|
|
207
289
|
end
|
|
208
290
|
end
|
|
209
291
|
|
|
@@ -230,7 +312,7 @@ function AdorneeData:InitAttributes(adornee, data)
|
|
|
230
312
|
|
|
231
313
|
-- TODO: Avoid additional allocation
|
|
232
314
|
for key, value in pairs(self._valueObjectPrototype) do
|
|
233
|
-
local valueObject = value:
|
|
315
|
+
local valueObject = value:Create(adornee)
|
|
234
316
|
if valueObject == nil then
|
|
235
317
|
if data[key] ~= nil then
|
|
236
318
|
valueObject.Value = data[key]
|
|
@@ -246,8 +328,9 @@ end
|
|
|
246
328
|
@return function
|
|
247
329
|
]=]
|
|
248
330
|
function AdorneeData:GetStrictTInterface()
|
|
249
|
-
|
|
250
|
-
|
|
331
|
+
local found = rawget(self, "_fullInterface")
|
|
332
|
+
if found then
|
|
333
|
+
return found
|
|
251
334
|
end
|
|
252
335
|
|
|
253
336
|
self._fullInterface = t.strictInterface(self:_getOrCreateTypeInterfaceList())
|
|
@@ -261,8 +344,9 @@ end
|
|
|
261
344
|
@return function
|
|
262
345
|
]=]
|
|
263
346
|
function AdorneeData:GetTInterface()
|
|
264
|
-
|
|
265
|
-
|
|
347
|
+
local found = rawget(self, "_interface")
|
|
348
|
+
if found then
|
|
349
|
+
return found
|
|
266
350
|
end
|
|
267
351
|
|
|
268
352
|
local interfaceList = {}
|
|
@@ -286,8 +370,9 @@ function AdorneeData:IsData(data)
|
|
|
286
370
|
end
|
|
287
371
|
|
|
288
372
|
function AdorneeData:_getOrCreateTypeInterfaceList()
|
|
289
|
-
|
|
290
|
-
|
|
373
|
+
local found = rawget(self, "_typeInterfaceList")
|
|
374
|
+
if found then
|
|
375
|
+
return found
|
|
291
376
|
end
|
|
292
377
|
|
|
293
378
|
local interfaceList = {}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
--[=[
|
|
2
|
+
Declaration for the adornee data value
|
|
3
|
+
|
|
2
4
|
@class AdorneeDataEntry
|
|
3
5
|
]=]
|
|
4
6
|
|
|
@@ -12,6 +14,13 @@ local AdorneeDataEntry = {}
|
|
|
12
14
|
AdorneeDataEntry.ClassName = "AdorneeDataEntry"
|
|
13
15
|
AdorneeDataEntry.__index = AdorneeDataEntry
|
|
14
16
|
|
|
17
|
+
--[=[
|
|
18
|
+
Creates a new adornee data entry
|
|
19
|
+
|
|
20
|
+
@param dataType string
|
|
21
|
+
@param createValueObject (adornee: Instance) -> ValueObject<T>
|
|
22
|
+
@return AdorneeDataEntry<T>
|
|
23
|
+
]=]
|
|
15
24
|
function AdorneeDataEntry.new(dataType, createValueObject)
|
|
16
25
|
assert(type(dataType) == "string", "Bad dataType")
|
|
17
26
|
assert(type(createValueObject) == "function", "Bad createValueObject")
|
|
@@ -31,22 +40,95 @@ function AdorneeDataEntry.new(dataType, createValueObject)
|
|
|
31
40
|
return self
|
|
32
41
|
end
|
|
33
42
|
|
|
43
|
+
--[=[
|
|
44
|
+
Returns true if the implementation is an AdorneeDataEntry
|
|
45
|
+
|
|
46
|
+
@param data any
|
|
47
|
+
@return boolean
|
|
48
|
+
]=]
|
|
34
49
|
function AdorneeDataEntry.isAdorneeDataEntry(data)
|
|
35
50
|
return DuckTypeUtils.isImplementation(AdorneeDataEntry, data)
|
|
36
51
|
end
|
|
37
52
|
|
|
38
|
-
|
|
53
|
+
--[=[
|
|
54
|
+
Creates a value object for the given adornee
|
|
55
|
+
|
|
56
|
+
@param adornee Instance
|
|
57
|
+
@return ValueObject<T>
|
|
58
|
+
]=]
|
|
59
|
+
function AdorneeDataEntry:Create(adornee)
|
|
39
60
|
assert(typeof(adornee) == "Instance", "Bad adornee")
|
|
40
61
|
|
|
41
62
|
return self._createValueObject(adornee)
|
|
42
63
|
end
|
|
43
64
|
|
|
65
|
+
--[=[
|
|
66
|
+
Observes the current value for the adornee
|
|
67
|
+
|
|
68
|
+
@param adornee Instance
|
|
69
|
+
@return Observable<T>
|
|
70
|
+
]=]
|
|
71
|
+
function AdorneeDataEntry:Observe(adornee)
|
|
72
|
+
assert(typeof(adornee) == "Instance", "Bad adornee")
|
|
73
|
+
|
|
74
|
+
local valueObject = self:Create(adornee)
|
|
75
|
+
return valueObject:Observe()
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
--[=[
|
|
79
|
+
Gets the value for the adornee
|
|
80
|
+
|
|
81
|
+
@param adornee Instance
|
|
82
|
+
@return T
|
|
83
|
+
]=]
|
|
84
|
+
function AdorneeDataEntry:GetValue(adornee)
|
|
85
|
+
assert(typeof(adornee) == "Instance", "Bad adornee")
|
|
86
|
+
|
|
87
|
+
local valueObject = self:Create(adornee)
|
|
88
|
+
|
|
89
|
+
return valueObject.Value
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
--[=[
|
|
93
|
+
Sets the value for the adornee
|
|
94
|
+
|
|
95
|
+
@param adornee Instance
|
|
96
|
+
@param value T
|
|
97
|
+
]=]
|
|
98
|
+
function AdorneeDataEntry:SetValue(adornee, value)
|
|
99
|
+
assert(typeof(adornee) == "Instance", "Bad adornee")
|
|
100
|
+
assert(self._strictInterface(value))
|
|
101
|
+
|
|
102
|
+
local valueObject = self:CreateValueObject(adornee)
|
|
103
|
+
valueObject.Value = value
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
--[=[
|
|
107
|
+
Gets the default value
|
|
108
|
+
|
|
109
|
+
@return T
|
|
110
|
+
]=]
|
|
44
111
|
function AdorneeDataEntry:GetDefaultValue()
|
|
45
112
|
return self._defaultValue
|
|
46
113
|
end
|
|
47
114
|
|
|
115
|
+
--[=[
|
|
116
|
+
Gets the estrict interface for the entry
|
|
117
|
+
|
|
118
|
+
@return (value: any) -> (boolean, string)
|
|
119
|
+
]=]
|
|
48
120
|
function AdorneeDataEntry:GetStrictInterface()
|
|
49
121
|
return self._strictInterface
|
|
50
122
|
end
|
|
51
123
|
|
|
124
|
+
--[=[
|
|
125
|
+
Returns true if the item is valid.
|
|
126
|
+
|
|
127
|
+
@param value any
|
|
128
|
+
@return (boolean, string)
|
|
129
|
+
]=]
|
|
130
|
+
function AdorneeDataEntry:IsValid(value)
|
|
131
|
+
return self._strictInterface(value)
|
|
132
|
+
end
|
|
133
|
+
|
|
52
134
|
return AdorneeDataEntry
|
|
@@ -50,7 +50,7 @@ function AdorneeDataValue.new(adornee, prototype)
|
|
|
50
50
|
|
|
51
51
|
for key, value in pairs(prototype) do
|
|
52
52
|
if AdorneeDataEntry.isAdorneeDataEntry(value) then
|
|
53
|
-
self._valueObjects[key] = value:
|
|
53
|
+
self._valueObjects[key] = value:Create(adornee)
|
|
54
54
|
else
|
|
55
55
|
self._valueObjects[key] = AttributeValue.new(adornee, key, value)
|
|
56
56
|
end
|