@quenty/binder 4.4.1-canary.8533eea.0 → 4.5.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 CHANGED
@@ -3,12 +3,20 @@
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
- ## [4.4.1-canary.8533eea.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@4.4.0...@quenty/binder@4.4.1-canary.8533eea.0) (2021-12-18)
6
+ ## [4.5.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@4.5.0...@quenty/binder@4.5.1) (2021-12-30)
7
+
8
+ **Note:** Version bump only for package @quenty/binder
9
+
10
+
11
+
12
+
13
+
14
+ # [4.5.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@4.4.0...@quenty/binder@4.5.0) (2021-12-18)
7
15
 
8
16
 
9
17
  ### Bug Fixes
10
18
 
11
- * Binder was not deconstructing correctly on cleanup ([3cd1847](https://github.com/Quenty/NevermoreEngine/commit/3cd1847ccc7100cdc14ed77242f47e46a061da56))
19
+ * Binder was not deconstructing correctly on cleanup ([b6cd547](https://github.com/Quenty/NevermoreEngine/commit/b6cd54746457afe180ddda2f4d41731b29c144a5))
12
20
 
13
21
 
14
22
 
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  ## Binder
2
2
  <div align="center">
3
- <a href="http://quenty.github.io/api/">
4
- <img src="https://img.shields.io/badge/docs-website-green.svg" alt="Documentation" />
3
+ <a href="http://quenty.github.io/NevermoreEngine/">
4
+ <img src="https://github.com/Quenty/NevermoreEngine/actions/workflows/docs.yml/badge.svg" alt="Documentation status" />
5
5
  </a>
6
6
  <a href="https://discord.gg/mhtGUS8">
7
- <img src="https://img.shields.io/badge/discord-nevermore-blue.svg" alt="Discord" />
7
+ <img src="https://img.shields.io/discord/385151591524597761?color=5865F2&label=discord&logo=discord&logoColor=white" alt="Discord" />
8
8
  </a>
9
9
  <a href="https://github.com/Quenty/NevermoreEngine/actions">
10
10
  <img src="https://github.com/Quenty/NevermoreEngine/actions/workflows/build.yml/badge.svg" alt="Build and release status" />
@@ -13,109 +13,9 @@
13
13
 
14
14
  Binders bind a class to Roblox Instance
15
15
 
16
+ <div align="center"><a href="https://quenty.github.io/NevermoreEngine/api/Binder">View docs →</a></div>
17
+
16
18
  ## Installation
17
19
  ```
18
20
  npm install @quenty/binder --save
19
- ```
20
-
21
- ## Usage
22
-
23
- ```lua
24
- -- Setup a class!
25
- local MyClass = {}
26
- MyClass.__index = MyClass
27
-
28
- function MyClass.new(robloxInstance)
29
- print("New tagged instance of ", robloxInstance)
30
- return setmetatable({}, MyClass)
31
- end
32
-
33
- function MyClass:Destroy()
34
- print("Cleaning up")
35
- setmetatable(self, nil)
36
- end
37
-
38
- -- bind to every instance with tag of "TagName"!
39
- local binder = Binder.new("TagName", MyClass)
40
- binder:Start() -- listens for new instances and connects events
41
- ```
42
-
43
- ## API
44
-
45
- ### `Binder.new(tagName, constructor)`
46
- Creates a new binder object.
47
-
48
- ### `Binder.isBinder(value)`
49
- Retrieves whether or not its a binder
50
-
51
- ### `Binder:Start()`
52
- Listens for new instances and connects to the GetInstanceAddedSignal() and removed signal!
53
-
54
- ### `Binder:GetTag()`
55
- Returns the tag name that the binder has
56
-
57
- ### `Binder:GetConstructor()`
58
- Returns whatever was set for the construtor. Used for meta-analysis of the binder, such as extracting new
59
-
60
- ### `Binder:ObserveInstance(inst, callback)`
61
- Fired when added, and then after removal, but before destroy!
62
-
63
- ### `Binder:GetClassAddedSignal()`
64
- Returns a new signal that will fire whenever a class is bound to the binder
65
-
66
- ### `Binder:GetClassRemovingSignal()`
67
- Returns a new signal that will fire whenever a class is removed from the binder
68
-
69
- ### `Binder:GetAll()`
70
- Returns all of the classes in a new table
71
-
72
- ```lua
73
- local birdBinder = Binder.new("Bird", require("Bird")) -- Load bird into binder
74
-
75
- -- Update every bird every frame
76
- RunService.Stepped:Connect(function()
77
- for _, bird in pairs(birdBinder:GetAll()) do
78
- bird:Update()
79
- end
80
- end)
81
-
82
- ```
83
- ### `Binder:GetAllSet()`
84
- Faster method to get all items in a binder
85
-
86
- NOTE: Do not mutate this set directly
87
-
88
- ```lua
89
- local birdBinder = Binder.new("Bird", require("Bird")) -- Load bird into binder
90
-
91
- -- Update every bird every frame
92
- RunService.Stepped:Connect(function()
93
- for bird, _ in pairs(birdBinder:GetAllSet()) do
94
- bird:Update()
95
- end
96
- end)
97
-
98
- birdBinder:Start()
99
- ```
100
-
101
- ### `Binder:Bind(inst)`
102
- Binds an instance to this binder using collection service and attempts to return it if it's bound properly. See BinderUtils.promiseBoundClass() for a safe way to retrieve it.
103
-
104
- NOTE: Do not assume that a bound object will be retrieved
105
-
106
- ### `Binder:Unbind(inst)`
107
- Unbinds the instance by removing the tag
108
-
109
- ### `Binder:BindClient(inst)`
110
- See :Bind(). Acknowledges the risk of doing this on the client. Using this acknowledges that we're intentionally binding on a safe client object, i.e. one without replication. If another tag is changed on this instance, this tag will be lost/changed.
111
-
112
- ### `Binder:UnbindClient(inst)`
113
- See Unbind(), acknowledges risk of doing this on the client.
114
-
115
- ### `Binder:Get(inst)`
116
- Returns a version of the clas
117
-
118
- ### `Binder:Promise(inst, cancelToken)`
119
-
120
- ### `Binder:Destroy()`
121
- Cleans up all bound classes, and disconnects all events
21
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/binder",
3
- "version": "4.4.1-canary.8533eea.0",
3
+ "version": "4.5.1",
4
4
  "description": "Utility object to Bind a class to Roblox object, and associated helper methods",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -25,18 +25,18 @@
25
25
  "Quenty"
26
26
  ],
27
27
  "dependencies": {
28
- "@quenty/baseobject": "3.2.0",
29
- "@quenty/brio": "3.4.1-canary.8533eea.0",
30
- "@quenty/instanceutils": "3.4.1-canary.8533eea.0",
31
- "@quenty/linkutils": "3.4.1-canary.8533eea.0",
32
- "@quenty/loader": "3.1.1",
33
- "@quenty/maid": "2.0.1",
34
- "@quenty/promise": "3.2.1-canary.8533eea.0",
35
- "@quenty/signal": "2.0.0",
36
- "@quenty/valueobject": "3.4.1-canary.8533eea.0"
28
+ "@quenty/baseobject": "^3.2.1",
29
+ "@quenty/brio": "^3.5.1",
30
+ "@quenty/instanceutils": "^3.5.1",
31
+ "@quenty/linkutils": "^3.5.1",
32
+ "@quenty/loader": "^3.1.2",
33
+ "@quenty/maid": "^2.0.2",
34
+ "@quenty/promise": "^3.3.1",
35
+ "@quenty/signal": "^2.0.1",
36
+ "@quenty/valueobject": "^3.5.1"
37
37
  },
38
38
  "publishConfig": {
39
39
  "access": "public"
40
40
  },
41
- "gitHead": "8533eeade3bf6835c0295785c1c326b9abee3222"
41
+ "gitHead": "d146c77d0a8e452824de0ab0b4b03ba0370bcc1b"
42
42
  }
@@ -1,5 +1,28 @@
1
- --- Bind class to Roblox Instance
2
- -- @classmod Binder
1
+ --[=[
2
+ Bind class to Roblox Instance
3
+
4
+ ```lua
5
+ -- Setup a class!
6
+ local MyClass = {}
7
+ MyClass.__index = MyClass
8
+
9
+ function MyClass.new(robloxInstance)
10
+ print("New tagged instance of ", robloxInstance)
11
+ return setmetatable({}, MyClass)
12
+ end
13
+
14
+ function MyClass:Destroy()
15
+ print("Cleaning up")
16
+ setmetatable(self, nil)
17
+ end
18
+
19
+ -- bind to every instance with tag of "TagName"!
20
+ local binder = Binder.new("TagName", MyClass)
21
+ binder:Start() -- listens for new instances and connects events
22
+ ```
23
+
24
+ @class Binder
25
+ ]=]
3
26
 
4
27
  local require = require(script.Parent.loader).load(script)
5
28
 
@@ -10,37 +33,37 @@ local Maid = require("Maid")
10
33
  local MaidTaskUtils = require("MaidTaskUtils")
11
34
  local Signal = require("Signal")
12
35
  local promiseBoundClass = require("promiseBoundClass")
13
- --[[
14
- @usage
15
-
16
- -- Setup a class!
17
- local MyClass = {}
18
- MyClass.__index = MyClass
19
-
20
- function MyClass.new(robloxInstance)
21
- print("New tagged instance of ", robloxInstance)
22
- return setmetatable({}, MyClass)
23
- end
24
-
25
- function MyClass:Destroy()
26
- print("Cleaning up")
27
- setmetatable(self, nil)
28
- end
29
-
30
- -- bind to every instance with tag of "TagName"!
31
- local binder = Binder.new("TagName", MyClass)
32
- binder:Start() -- listens for new instances and connects events
33
- ]]
34
36
 
35
37
  local Binder = {}
36
38
  Binder.__index = Binder
37
39
  Binder.ClassName = "Binder"
38
40
 
39
- --- Creates a new binder object.
40
- -- @constructor Binder.new(tagName, constructor)
41
- -- @param tagName Name of the tag to bind to. This uses CollectionService's tag system
42
- -- @param constructor A constructor to create the new class. Comes in three flavors.
43
- -- @treturn Binder
41
+ --[=[
42
+ Constructor for a binder
43
+ @type BinderContructor (Instance, ...: any) -> T | { new: (Instance, ...: any) } | { Create(self, Instance, ...: any) }
44
+ @within Binder
45
+ ]=]
46
+
47
+ --[=[
48
+ Constructs a new binder object.
49
+
50
+ ```lua
51
+ local binder = Binder.new("Bird", function(inst)
52
+ print("Wow, a new bird!", inst)
53
+
54
+ return {
55
+ Destroy = function()
56
+ print("Uh oh, the bird is gone!")
57
+ end;
58
+ }
59
+ end)
60
+ binder:Start()
61
+ ```
62
+ @param tagName string -- Name of the tag to bind to. This uses CollectionService's tag system
63
+ @param constructor BinderContructor
64
+ @param ... any -- Variable arguments that will be passed into the constructor
65
+ @return Binder<T>
66
+ ]=]
44
67
  function Binder.new(tagName, constructor, ...)
45
68
  local self = setmetatable({}, Binder)
46
69
 
@@ -55,7 +78,7 @@ function Binder.new(tagName, constructor, ...)
55
78
  self._listeners = {} -- [inst] = callback
56
79
  self._args = {...}
57
80
 
58
- delay(5, function()
81
+ task.delay(5, function()
59
82
  if not self._loaded then
60
83
  warn(("Binder %q is not loaded. Call :Start() on it!"):format(self._tagName))
61
84
  end
@@ -64,14 +87,19 @@ function Binder.new(tagName, constructor, ...)
64
87
  return self
65
88
  end
66
89
 
67
- --- Retrieves whether or not its a binder
68
- -- @param value
69
- -- @return true or false, whether or not it is a value
90
+ --[=[
91
+ Retrieves whether or not the given value is a binder.
92
+
93
+ @param value any
94
+ @return boolean true or false, whether or not it is a value
95
+ ]=]
70
96
  function Binder.isBinder(value)
71
97
  return type(value) == "table" and value.ClassName == "Binder"
72
98
  end
73
99
 
74
- --- Listens for new instances and connects to the GetInstanceAddedSignal() and removed signal!
100
+ --[=[
101
+ Listens for new instances and connects to the GetInstanceAddedSignal() and removed signal!
102
+ ]=]
75
103
  function Binder:Start()
76
104
  if self._loaded then
77
105
  return
@@ -90,17 +118,31 @@ function Binder:Start()
90
118
  end))
91
119
  end
92
120
 
93
- -- Returns the tag name that the binder has
121
+ --[=[
122
+ Returns the tag name that the binder has.
123
+ @return string
124
+ ]=]
94
125
  function Binder:GetTag()
95
126
  return self._tagName
96
127
  end
97
128
 
98
- --- Returns whatever was set for the construtor. Used for meta-analysis of the binder, such as extracting new
129
+ --[=[
130
+ Returns whatever was set for the construtor. Used for meta-analysis of
131
+ the binder, such as extracting if parameters are allowed.
132
+
133
+ @return BinderContructor
134
+ ]=]
99
135
  function Binder:GetConstructor()
100
136
  return self._constructor
101
137
  end
102
138
 
103
- -- Fired when added, and then after removal, but before destroy!
139
+ --[=[
140
+ Fired when added, and then after removal, but before destroy!
141
+
142
+ @param inst Instance
143
+ @param callback function
144
+ @return function -- Cleanup function
145
+ ]=]
104
146
  function Binder:ObserveInstance(inst, callback)
105
147
  self._listeners[inst] = self._listeners[inst] or {}
106
148
  self._listeners[inst][callback] = true
@@ -117,19 +159,22 @@ function Binder:ObserveInstance(inst, callback)
117
159
  end
118
160
  end
119
161
 
120
- -- Returns a new signal that will fire whenever a class is bound to the binder
121
- --[[
122
- @usage
162
+ --[=[
163
+ Returns a new signal that will fire whenever a class is bound to the binder
123
164
 
124
- local birdBinder = Binder.new("Bird", require("Bird")) -- Load bird into binder
165
+ ```lua
166
+ local birdBinder = Binder.new("Bird", require("Bird")) -- Load bird into binder
125
167
 
126
- birdBinder:GetClassAddedSignal():Connect(function(bird)
127
- bird:Squack() -- Make the bird squack when it's first spawned
128
- end)
168
+ birdBinder:GetClassAddedSignal():Connect(function(bird)
169
+ bird:Squack() -- Make the bird squack when it's first spawned
170
+ end)
129
171
 
130
- -- Load all birds
131
- birdBinder:Start()
132
- ]]
172
+ -- Load all birds
173
+ birdBinder:Start()
174
+ ```
175
+
176
+ @return Signal<T>
177
+ ]=]
133
178
  function Binder:GetClassAddedSignal()
134
179
  if self._classAddedSignal then
135
180
  return self._classAddedSignal
@@ -140,7 +185,11 @@ function Binder:GetClassAddedSignal()
140
185
  return self._classAddedSignal
141
186
  end
142
187
 
143
- -- Returns a new signal that will fire whenever a class is removing from the binder
188
+ --[=[
189
+ Returns a new signal that will fire whenever a class is removing from the binder.
190
+
191
+ @return Signal<T>
192
+ ]=]
144
193
  function Binder:GetClassRemovingSignal()
145
194
  if self._classRemovingSignal then
146
195
  return self._classRemovingSignal
@@ -152,7 +201,11 @@ function Binder:GetClassRemovingSignal()
152
201
  return self._classRemovingSignal
153
202
  end
154
203
 
155
- -- Returns a new signal that will fire whenever a class is removed from the binder
204
+ --[=[
205
+ Returns a new signal that will fire whenever a class is removed from the binder.
206
+
207
+ @return Signal<T>
208
+ ]=]
156
209
  function Binder:GetClassRemovedSignal()
157
210
  if self._classRemovedSignal then
158
211
  return self._classRemovedSignal
@@ -164,21 +217,24 @@ function Binder:GetClassRemovedSignal()
164
217
  return self._classRemovedSignal
165
218
  end
166
219
 
167
- --[[
168
- @usage
220
+ --[=[
221
+ Returns all of the classes in a new table.
169
222
 
170
- local birdBinder = Binder.new("Bird", require("Bird")) -- Load bird into binder
223
+ ```lua
224
+ local birdBinder = Binder.new("Bird", require("Bird")) -- Load bird into binder
171
225
 
172
- -- Update every bird every frame
173
- RunService.Stepped:Connect(function()
174
- for _, bird in pairs(birdBinder:GetAll()) do
175
- bird:Update()
176
- end
177
- end)
226
+ -- Update every bird every frame
227
+ RunService.Stepped:Connect(function()
228
+ for _, bird in pairs(birdBinder:GetAll()) do
229
+ bird:Update()
230
+ end
231
+ end)
232
+
233
+ birdBinder:Start()
234
+ ```
178
235
 
179
- birdBinder:Start()
180
- ]]
181
- --- Returns all of the classes in a new table
236
+ @return {T}
237
+ ]=]
182
238
  function Binder:GetAll()
183
239
  local all = {}
184
240
  for class, _ in pairs(self._allClassSet) do
@@ -188,30 +244,45 @@ function Binder:GetAll()
188
244
  end
189
245
 
190
246
 
191
- --[[
192
- @usage
247
+ --[=[
248
+ Faster method to get all items in a binder
193
249
 
194
- local birdBinder = Binder.new("Bird", require("Bird")) -- Load bird into binder
250
+ ```lua
251
+ local birdBinder = Binder.new("Bird", require("Bird")) -- Load bird into binder
195
252
 
196
- -- Update every bird every frame
197
- RunService.Stepped:Connect(function()
198
- for bird, _ in pairs(birdBinder:GetAllSet()) do
199
- bird:Update()
200
- end
201
- end)
253
+ -- Update every bird every frame
254
+ RunService.Stepped:Connect(function()
255
+ for bird, _ in pairs(birdBinder:GetAllSet()) do
256
+ bird:Update()
257
+ end
258
+ end)
202
259
 
203
- birdBinder:Start()
204
- ]]
205
- --- Faster method to get all items in a binder
206
- -- NOTE: Do not mutate this set directly
260
+ birdBinder:Start()
261
+ ```
262
+
263
+ :::warning
264
+ Do not mutate this set directly
265
+ :::
266
+
267
+ @return { [T]: boolean }
268
+ ]=]
207
269
  function Binder:GetAllSet()
208
270
  return self._allClassSet
209
271
  end
210
272
 
211
- --- Binds an instance to this binder using collection service and attempts
212
- -- to return it if it's bound properly. See BinderUtils.promiseBoundClass() for a safe
213
- -- way to retrieve it.
214
- -- NOTE: Do not assume that a bound object will be retrieved
273
+ --[=[
274
+ Binds an instance to this binder using collection service and attempts
275
+ to return it if it's bound properly. See BinderUtils.promiseBoundClass() for a safe
276
+ way to retrieve it.
277
+
278
+ :::warning
279
+ Do not assume that a bound object will be retrieved
280
+ :::
281
+
282
+ @server
283
+ @param inst Instance -- Instance to check
284
+ @return T? -- Bound class
285
+ ]=]
215
286
  function Binder:Bind(inst)
216
287
  if RunService:IsClient() then
217
288
  warn(("[Binder.Bind] - Bindings '%s' done on the client! Will be disrupted upon server replication! %s")
@@ -222,7 +293,12 @@ function Binder:Bind(inst)
222
293
  return self:Get(inst)
223
294
  end
224
295
 
225
- -- Unbinds the instance by removing the tag
296
+ --[=[
297
+ Unbinds the instance by removing the tag.
298
+
299
+ @server
300
+ @param inst Instance -- Instance to unbind
301
+ ]=]
226
302
  function Binder:Unbind(inst)
227
303
  assert(typeof(inst) == "Instance", "Bad inst'")
228
304
 
@@ -234,9 +310,16 @@ function Binder:Unbind(inst)
234
310
  CollectionService:RemoveTag(inst, self._tagName)
235
311
  end
236
312
 
237
- -- See :Bind(). Acknowledges the risk of doing this on the client.
238
- -- Using this acknowledges that we're intentionally binding on a safe client object,
239
- -- i.e. one without replication. If another tag is changed on this instance, this tag will be lost/changed.
313
+ --[=[
314
+ See :Bind(). Acknowledges the risk of doing this on the client.
315
+
316
+ Using this acknowledges that we're intentionally binding on a safe client object,
317
+ i.e. one without replication. If another tag is changed on this instance, this tag will be lost/changed.
318
+
319
+ @client
320
+ @param inst Instance -- Instance to bind
321
+ @return T? -- Bound class (potentially)
322
+ ]=]
240
323
  function Binder:BindClient(inst)
241
324
  if not RunService:IsClient() then
242
325
  warn(("[Binder.BindClient] - Bindings '%s' done on the server! Will be replicated!")
@@ -247,18 +330,35 @@ function Binder:BindClient(inst)
247
330
  return self:Get(inst)
248
331
  end
249
332
 
250
- -- See Unbind(), acknowledges risk of doing this on the client.
333
+ --[=[
334
+ See Unbind(), acknowledges risk of doing this on the client.
335
+
336
+ @client
337
+ @param inst Instance -- Instance to unbind
338
+ ]=]
251
339
  function Binder:UnbindClient(inst)
252
340
  assert(typeof(inst) == "Instance", "Bad inst")
253
341
  CollectionService:RemoveTag(inst, self._tagName)
254
342
  end
255
343
 
256
- --- Returns a version of the clas
344
+ --[=[
345
+ Returns a instance of the class that is bound to the instance given.
346
+
347
+ @param inst Instance -- Instance to check
348
+ @return T?
349
+ ]=]
257
350
  function Binder:Get(inst)
258
351
  assert(typeof(inst) == "Instance", "Argument 'inst' is not an Instance")
259
352
  return self._instToClass[inst]
260
353
  end
261
354
 
355
+ --[=[
356
+ Returns a promise which will resolve when the instance is bound.
357
+
358
+ @param inst Instance -- Instance to check
359
+ @param cancelToken? CancelToken
360
+ @return Promise<T>
361
+ ]=]
262
362
  function Binder:Promise(inst, cancelToken)
263
363
  assert(typeof(inst) == "Instance", "Argument 'inst' is not an Instance")
264
364
  return promiseBoundClass(self, inst, cancelToken)
@@ -355,7 +455,9 @@ function Binder:_remove(inst)
355
455
  end
356
456
  end
357
457
 
358
- --- Cleans up all bound classes, and disconnects all events
458
+ --[=[
459
+ Cleans up all bound classes, and disconnects all events.
460
+ ]=]
359
461
  function Binder:Destroy()
360
462
  local inst, class = next(self._instToClass)
361
463
  while class ~= nil do
@@ -1,5 +1,13 @@
1
- --- Groups binders together
2
- -- @classmod BinderGroup
1
+ --[=[
2
+ Groups binders together into a list, and allows binders to be dynamically
3
+ added or removed.
4
+
5
+ Also allows their interface to be validated using a validation function.
6
+ This ensures that all added objects are the same type, so they can be used
7
+ for dynamic interactions.
8
+
9
+ @class BinderGroup
10
+ ]=]
3
11
 
4
12
  local require = require(script.Parent.loader).load(script)
5
13
 
@@ -10,6 +18,13 @@ local BinderGroup = {}
10
18
  BinderGroup.ClassName = "BinderGroup"
11
19
  BinderGroup.__index = BinderGroup
12
20
 
21
+ --[=[
22
+ Constructs a new BinderGroup
23
+
24
+ @param binders { Binder<T> } -- A list of binders that
25
+ @param validateConstructor (constructor: any) -> boolean -- Validates a binder matches T
26
+ @return BinderGroup<T>
27
+ ]=]
13
28
  function BinderGroup.new(binders, validateConstructor)
14
29
  local self = setmetatable({}, BinderGroup)
15
30
 
@@ -24,6 +39,11 @@ function BinderGroup.new(binders, validateConstructor)
24
39
  return self
25
40
  end
26
41
 
42
+ --[=[
43
+ Adds a list of binders to the group.
44
+
45
+ @param binders { Binder<T> }
46
+ ]=]
27
47
  function BinderGroup:AddList(binders)
28
48
  assert(type(binders) == "table", "Bad binders")
29
49
 
@@ -34,6 +54,11 @@ function BinderGroup:AddList(binders)
34
54
  end
35
55
  end
36
56
 
57
+ --[=[
58
+ Adds the specific binder to the list
59
+
60
+ @param binder Binder<T>
61
+ ]=]
37
62
  function BinderGroup:Add(binder)
38
63
  assert(Binder.isBinder(binder))
39
64
 
@@ -52,6 +77,15 @@ function BinderGroup:Add(binder)
52
77
  self.BinderAdded:Fire(binder)
53
78
  end
54
79
 
80
+ --[=[
81
+ Returns a list of binders.
82
+
83
+ :::warning
84
+ Do not modify the list of binders returned here
85
+ :::
86
+
87
+ @return { T }
88
+ ]=]
55
89
  function BinderGroup:GetBinders()
56
90
  assert(self._binders, "No self._binders")
57
91
 
@@ -1,5 +1,7 @@
1
- --- Provides a basis for binderGroups that can be retrieved anywhere
2
- -- @classmod BinderGroupProvider
1
+ --[=[
2
+ Provides a basis for binderGroups that can be retrieved anywhere
3
+ @class BinderGroupProvider
4
+ ]=]
3
5
 
4
6
  local require = require(script.Parent.loader).load(script)
5
7
 
@@ -9,6 +11,11 @@ local BinderGroupProvider = {}
9
11
  BinderGroupProvider.ClassName = "BinderGroupProvider"
10
12
  BinderGroupProvider.__index = BinderGroupProvider
11
13
 
14
+ --[=[
15
+ Constructs a new BinderGroupProvider
16
+ @param initMethod (BinderGroupProvider) -> ()
17
+ @return BinderGroupProvider
18
+ ]=]
12
19
  function BinderGroupProvider.new(initMethod)
13
20
  local self = setmetatable({}, BinderGroupProvider)
14
21
 
@@ -21,10 +28,18 @@ function BinderGroupProvider.new(initMethod)
21
28
  return self
22
29
  end
23
30
 
31
+ --[=[
32
+ Returns a promise that will resolve once groups are added.
33
+ @return Promise
34
+ ]=]
24
35
  function BinderGroupProvider:PromiseGroupsAdded()
25
36
  return self._groupsAddedPromise
26
37
  end
27
38
 
39
+ --[=[
40
+ Starts the binder provider. Should be called via ServiceBag.
41
+ @param ... ServiceBag | any
42
+ ]=]
28
43
  function BinderGroupProvider:Init(...)
29
44
  assert(not self._init, "Already initialized")
30
45
 
@@ -34,6 +49,9 @@ function BinderGroupProvider:Init(...)
34
49
  self._groupsAddedPromise:Resolve()
35
50
  end
36
51
 
52
+ --[=[
53
+ Starts the binder provider. Should be called via ServiceBag.
54
+ ]=]
37
55
  function BinderGroupProvider:Start()
38
56
  -- Do nothing
39
57
  end
@@ -46,11 +64,23 @@ function BinderGroupProvider:__index(index)
46
64
  error(("%q Not a valid index"):format(tostring(index)))
47
65
  end
48
66
 
49
- function BinderGroupProvider:Get(tagName)
50
- assert(type(tagName) == "string", "tagName must be a string")
51
- return rawget(self, tagName)
67
+ --[=[
68
+ Returns a binder group given the binderName
69
+
70
+ @param groupName string
71
+ @return BinderGroup?
72
+ ]=]
73
+ function BinderGroupProvider:Get(groupName)
74
+ assert(type(groupName) == "string", "groupName must be a string")
75
+ return rawget(self, groupName)
52
76
  end
53
77
 
78
+ --[=[
79
+ Adds a new group at the given name
80
+
81
+ @param groupName string
82
+ @param binderGroup BinderGroup
83
+ ]=]
54
84
  function BinderGroupProvider:Add(groupName, binderGroup)
55
85
  assert(type(groupName) == "string", "Bad groupName")
56
86
  assert(type(binderGroup) == "table", "Bad binderGroup")
@@ -1,5 +1,7 @@
1
- --- Provides a basis for binders that can be retrieved anywhere
2
- -- @classmod BinderProvider
1
+ --[=[
2
+ Provides a basis for binders that can be retrieved anywhere
3
+ @class BinderProvider
4
+ ]=]
3
5
 
4
6
  local require = require(script.Parent.loader).load(script)
5
7
 
@@ -9,6 +11,28 @@ local BinderProvider = {}
9
11
  BinderProvider.ClassName = "BinderProvider"
10
12
  BinderProvider.__index = BinderProvider
11
13
 
14
+ --[=[
15
+ Constructs a new BinderProvider.
16
+
17
+ ```lua
18
+ local serviceBag = ServiceBag.new()
19
+
20
+ -- Usually in a separate file!
21
+ local binderProvider = BinderProvider.new(function(self, serviceBag)
22
+ serviceBag:Add(Binder.new("Bird", require("Bird")))
23
+ end)
24
+
25
+ -- Retrieve binders
26
+ local binders = serviceBag:GetService(binderProvider)
27
+
28
+ -- Runs the game (including binders)
29
+ serviceBag:Init()
30
+ serviceBag:Start()
31
+ ```
32
+
33
+ @param initMethod (self, serviceBag: ServiceBag)
34
+ @return BinderProvider
35
+ ]=]
12
36
  function BinderProvider.new(initMethod)
13
37
  local self = setmetatable({}, BinderProvider)
14
38
 
@@ -25,13 +49,21 @@ function BinderProvider.new(initMethod)
25
49
  return self
26
50
  end
27
51
 
28
- --- Retrieves whether or not its a binder provider
29
- -- @param value
30
- -- @return true or false, whether or not it is a value
52
+ --[=[
53
+ Retrieves whether or not its a binder provider
54
+ @param value any
55
+ @return boolean -- True if it is a binder provider
56
+ ]=]
31
57
  function BinderProvider.isBinderProvider(value)
32
58
  return type(value) == "table" and value.ClassName == "BinderProvider"
33
59
  end
34
60
 
61
+ --[=[
62
+ Resolves to the given binder given the binderName.
63
+
64
+ @param binderName string
65
+ @return Promise<Binder<T>>
66
+ ]=]
35
67
  function BinderProvider:PromiseBinder(binderName)
36
68
  if self._bindersAddedPromise:IsFulfilled() then
37
69
  local binder = self:Get(binderName)
@@ -53,7 +85,11 @@ function BinderProvider:PromiseBinder(binderName)
53
85
  end)
54
86
  end
55
87
 
56
- -- Initializes itself and all binders
88
+ --[=[
89
+ Initializes itself and all binders
90
+
91
+ @param ... ServiceBag | any
92
+ ]=]
57
93
  function BinderProvider:Init(...)
58
94
  assert(not self._initialized, "Already initialized")
59
95
 
@@ -62,15 +98,27 @@ function BinderProvider:Init(...)
62
98
  self._bindersAddedPromise:Resolve()
63
99
  end
64
100
 
101
+ --[=[
102
+ Returns a promise that will resolve once all binders are added.
103
+
104
+ @return Promise
105
+ ]=]
65
106
  function BinderProvider:PromiseBindersAdded()
66
107
  return self._bindersAddedPromise
67
108
  end
68
109
 
110
+ --[=[
111
+ Returns a promise that will resolve once all binders are started.
112
+
113
+ @return Promise
114
+ ]=]
69
115
  function BinderProvider:PromiseBindersStarted()
70
116
  return self._startPromise
71
117
  end
72
118
 
73
- -- Starts all of the binders
119
+ --[=[
120
+ Starts all of the binders.
121
+ ]=]
74
122
  function BinderProvider:Start()
75
123
  assert(self._initialized, "Not initialized")
76
124
  assert(not self._started, "Already started")
@@ -92,11 +140,22 @@ function BinderProvider:__index(index)
92
140
  error(("%q Not a valid index"):format(tostring(index)))
93
141
  end
94
142
 
143
+ --[=[
144
+ Retrieves a binder given a tagName
145
+
146
+ @param tagName string
147
+ @return Binder<T>?
148
+ ]=]
95
149
  function BinderProvider:Get(tagName)
96
150
  assert(type(tagName) == "string", "tagName must be a string")
97
151
  return rawget(self, tagName)
98
152
  end
99
153
 
154
+ --[=[
155
+ Adds a binder given a tag name.
156
+
157
+ @param binder Binder<T>
158
+ ]=]
100
159
  function BinderProvider:Add(binder)
101
160
  assert(not self._started, "Already inited")
102
161
  assert(not self:Get(binder:GetTag()), "Binder already exists")
@@ -1,10 +1,20 @@
1
- --- Utility methods for binders
2
- -- @module BinderUtils
1
+ --[=[
2
+ Utility methods for the binder object.
3
+ @class BinderUtils
4
+ ]=]
3
5
 
4
6
  local CollectionService = game:GetService("CollectionService")
5
7
 
6
8
  local BinderUtils = {}
7
9
 
10
+ --[=[
11
+ Finds the first ancestor that is bound with the current child.
12
+ Skips the child class, of course.
13
+
14
+ @param binder Binder<T>
15
+ @param child Instance
16
+ @return T?
17
+ ]=]
8
18
  function BinderUtils.findFirstAncestor(binder, child)
9
19
  assert(type(binder) == "table", "Binder must be binder")
10
20
  assert(typeof(child) == "Instance", "Child parameter must be instance")
@@ -20,6 +30,14 @@ function BinderUtils.findFirstAncestor(binder, child)
20
30
  return nil
21
31
  end
22
32
 
33
+ --[=[
34
+ Finds the first child bound with the given binder and returns
35
+ the bound class.
36
+
37
+ @param binder Binder<T>
38
+ @param parent Instance
39
+ @return T?
40
+ ]=]
23
41
  function BinderUtils.findFirstChild(binder, parent)
24
42
  assert(type(binder) == "table", "Binder must be binder")
25
43
  assert(typeof(parent) == "Instance", "Parent parameter must be instance")
@@ -34,6 +52,13 @@ function BinderUtils.findFirstChild(binder, parent)
34
52
  return nil
35
53
  end
36
54
 
55
+ --[=[
56
+ Gets all bound children of the given binder for the parent.
57
+
58
+ @param binder Binder<T>
59
+ @param parent Instance
60
+ @return {T}
61
+ ]=]
37
62
  function BinderUtils.getChildren(binder, parent)
38
63
  assert(type(binder) == "table", "Binder must be binder")
39
64
  assert(typeof(parent) == "Instance", "Parent parameter must be instance")
@@ -48,6 +73,16 @@ function BinderUtils.getChildren(binder, parent)
48
73
  return objects
49
74
  end
50
75
 
76
+
77
+ --[=[
78
+ Maps a list of binders into a look up table where the keys are
79
+ tags and the value is the binder.
80
+
81
+ Duplicates are overwritten by the last entry.
82
+
83
+ @param bindersList { Binder<any> }
84
+ @return { [string]: Binder<any> }
85
+ ]=]
51
86
  function BinderUtils.mapBinderListToTable(bindersList)
52
87
  assert(type(bindersList) == "table", "bindersList must be a table of binders")
53
88
 
@@ -58,6 +93,19 @@ function BinderUtils.mapBinderListToTable(bindersList)
58
93
  return tags
59
94
  end
60
95
 
96
+ --[=[
97
+ Given a mapping of tags to binders, retrieves the bound values
98
+ from an instanceList by quering the list of :GetTags() instead
99
+ of iterating over each binder.
100
+
101
+ This lookup should be faster when there are potentially many
102
+ interaction points for a given tag map, but the actual bound
103
+ list should be low.
104
+
105
+ @param tagsMap { [string]: Binder<T> }
106
+ @param instanceList { Instance }
107
+ @return { T }
108
+ ]=]
61
109
  function BinderUtils.getMappedFromList(tagsMap, instanceList)
62
110
  local objects = {}
63
111
 
@@ -76,6 +124,13 @@ function BinderUtils.getMappedFromList(tagsMap, instanceList)
76
124
  return objects
77
125
  end
78
126
 
127
+ --[=[
128
+ Given a list of binders retrieves all children bound with the given value.
129
+
130
+ @param bindersList { Binder<T> }
131
+ @param parent Instance
132
+ @return { T }
133
+ ]=]
79
134
  function BinderUtils.getChildrenOfBinders(bindersList, parent)
80
135
  assert(type(bindersList) == "table", "bindersList must be a table of binders")
81
136
  assert(typeof(parent) == "Instance", "Parent parameter must be instance")
@@ -84,6 +139,14 @@ function BinderUtils.getChildrenOfBinders(bindersList, parent)
84
139
  return BinderUtils.getMappedFromList(tagsMap, parent:GetChildren())
85
140
  end
86
141
 
142
+ --[=[
143
+ Gets all the linked (via objectValues of name `linkName`) bound objects
144
+
145
+ @param binder Binder<T>
146
+ @param linkName string -- Name of the object values required
147
+ @param parent Instance
148
+ @return {T}
149
+ ]=]
87
150
  function BinderUtils.getLinkedChildren(binder, linkName, parent)
88
151
  local seen = {}
89
152
  local objects = {}
@@ -103,6 +166,13 @@ function BinderUtils.getLinkedChildren(binder, linkName, parent)
103
166
  return objects
104
167
  end
105
168
 
169
+ --[=[
170
+ Gets all bound descendants of the given binder for the parent.
171
+
172
+ @param binder Binder<T>
173
+ @param parent Instance
174
+ @return {T}
175
+ ]=]
106
176
  function BinderUtils.getDescendants(binder, parent)
107
177
  assert(type(binder) == "table", "Binder must be binder")
108
178
  assert(typeof(parent) == "Instance", "Parent parameter must be instance")
@@ -1,5 +1,7 @@
1
- --- Tracks child of type
2
- -- @classmod BoundChildCollection
1
+ --[=[
2
+ Tracks child of type of a binder.
3
+ @class BoundChildCollection
4
+ ]=]
3
5
 
4
6
  local require = require(script.Parent.loader).load(script)
5
7
 
@@ -10,17 +12,31 @@ local BoundChildCollection = setmetatable({}, BaseObject)
10
12
  BoundChildCollection.ClassName = "BoundChildCollection"
11
13
  BoundChildCollection.__index = BoundChildCollection
12
14
 
15
+ --[=[
16
+ Constructcs a new BoundChildCollection.
17
+ @param binder Binder<T>
18
+ @param parent Instance
19
+ @return BoundChildCollection<T>
20
+ ]=]
13
21
  function BoundChildCollection.new(binder, parent)
14
22
  local self = setmetatable(BaseObject.new(), BoundChildCollection)
15
23
 
16
24
  self._binder = binder or error("No binder")
17
25
  self._parent = parent or error("No parent")
18
26
 
19
- --- Fires on class addition
27
+ --[=[
28
+ Fires on class addition
29
+ @prop ClassAdded Signal<T>
30
+ @within BoundChildCollection
31
+ ]=]
20
32
  self.ClassAdded = Signal.new() -- :Fire(class)
21
33
  self._maid:GiveTask(self.ClassAdded)
22
34
 
23
- --- Fires on class removal
35
+ --[=[
36
+ Fires on class removal
37
+ @prop ClassRemoved Signal<T>
38
+ @within BoundChildCollection
39
+ ]=]
24
40
  self.ClassRemoved = Signal.new() -- :Fire(class)
25
41
  self._maid:GiveTask(self.ClassRemoved)
26
42
 
@@ -39,24 +55,40 @@ function BoundChildCollection.new(binder, parent)
39
55
  return self
40
56
  end
41
57
 
42
- --- Returns whether the track has the class
43
- -- @return true if the class exists, nil otherwise
58
+ --[=[
59
+ Returns whether the track has the class
60
+ @param class T
61
+ @return boolean? -- true if the class exists, nil otherwise
62
+ ]=]
44
63
  function BoundChildCollection:HasClass(class)
45
64
  return self._classes[class]
46
65
  end
47
66
 
67
+ --[=[
68
+ Gets the size
69
+ @return number
70
+ ]=]
48
71
  function BoundChildCollection:GetSize()
49
72
  return self._size
50
73
  end
51
74
 
52
- --- Returns the raw classes variable as [class] = true
53
- -- @return The set
75
+ --[=[
76
+ Returns the raw classes variable as [class] = true.
77
+
78
+ :::warning
79
+ Do not modify the set
80
+ :::
81
+
82
+ @return { [T] = true } -- The set
83
+ ]=]
54
84
  function BoundChildCollection:GetSet()
55
85
  return self._classes
56
86
  end
57
87
 
58
- --- Slow than :GetSet(), but adds them in an ordered list
59
- -- @return The list
88
+ --[=[
89
+ Slow than :GetSet(), but adds them in an ordered list
90
+ @return { T }
91
+ ]=]
60
92
  function BoundChildCollection:GetClasses()
61
93
  local list = {}
62
94
  for class, _ in pairs(self._classes) do
@@ -1,11 +1,22 @@
1
- --- Utility function to promise a bound class on an object
2
- -- @function promiseBoundClass
1
+ --[=[
2
+ Utility function to promise a bound class on an object
3
+ @class promiseBoundClass
4
+ ]=]
3
5
 
4
6
  local require = require(script.Parent.loader).load(script)
5
7
 
6
8
  local Promise = require("Promise")
7
9
  local Maid = require("Maid")
8
10
 
11
+ --[=[
12
+ Returns a promise that resolves when the class is bound to the instance.
13
+ @param binder Binder<T>
14
+ @param inst Instance
15
+ @param cancelToken CancelToken
16
+ @return Promise<T>
17
+ @function promiseBoundClass
18
+ @within promiseBoundClass
19
+ ]=]
9
20
  return function(binder, inst, cancelToken)
10
21
  assert(type(binder) == "table", "'binder' must be table")
11
22
  assert(typeof(inst) == "Instance", "'inst' must be instance")
@@ -1,5 +1,7 @@
1
- --- Tracks a parent bound to a specific binder
2
- -- @classmod BoundAncestorTracker
1
+ --[=[
2
+ Tracks a parent bound to a specific binder
3
+ @class BoundAncestorTracker
4
+ ]=]
3
5
 
4
6
  local require = require(script.Parent.loader).load(script)
5
7
 
@@ -11,13 +13,26 @@ local BoundAncestorTracker = setmetatable({}, BaseObject)
11
13
  BoundAncestorTracker.ClassName = "BoundAncestorTracker"
12
14
  BoundAncestorTracker.__index = BoundAncestorTracker
13
15
 
16
+
17
+ --[=[
18
+ Constructs a new BoundAncestorTracker
19
+
20
+ @param binder Binder<T>
21
+ @param child Instance
22
+ @return BoundAncestorTracker
23
+ ]=]
14
24
  function BoundAncestorTracker.new(binder, child)
15
25
  local self = setmetatable(BaseObject.new(), BoundAncestorTracker)
16
26
 
17
27
  self._child = child or error("No child")
18
28
  self._binder = binder or error("No binder")
19
29
 
20
- -- Bound value
30
+ --[=[
31
+ @prop Class ValueObject<T>
32
+ @readonly
33
+ @within BoundAncestorTracker
34
+ Bound value
35
+ ]=]
21
36
  self.Class = ValueObject.new()
22
37
  self._maid:GiveTask(self.Class)
23
38
 
@@ -1,5 +1,7 @@
1
- --- Tracks a parent bound to a specific binder
2
- -- @classmod BoundParentTracker
1
+ --[=[
2
+ Tracks a parent bound to a specific binder
3
+ @class BoundParentTracker
4
+ ]=]
3
5
 
4
6
  local require = require(script.Parent.loader).load(script)
5
7