@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.0",
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": "3fd5cdca3128bf34c8d9dfae1e92d62533b6e6f5"
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:CreateValueObject(adornee).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:CreateValueObject(adornee).Value = data[key]
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:CreateValueObject(adornee)
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
- if self._fullInterface then
250
- return self._fullInterface
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
- if self._interface then
265
- return self._interface
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
- if self._typeInterfaceList then
290
- return self._typeInterfaceList
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
- function AdorneeDataEntry:CreateValueObject(adornee)
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:CreateValueObject(adornee)
53
+ self._valueObjects[key] = value:Create(adornee)
54
54
  else
55
55
  self._valueObjects[key] = AttributeValue.new(adornee, key, value)
56
56
  end