@quenty/observablecollection 5.15.0 → 5.16.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 +12 -0
- package/package.json +6 -6
- package/src/Shared/FilteredObservableListView.lua +1 -5
- package/src/Shared/ObservableCountingMap.lua +3 -4
- package/src/Shared/ObservableList.lua +22 -5
- package/src/Shared/ObservableMap.lua +4 -5
- package/src/Shared/ObservableMapSet.lua +10 -6
- package/src/Shared/ObservableSet.lua +4 -5
- package/src/Shared/ObservableSortedList.lua +60 -21
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
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.16.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/observablecollection@5.15.0...@quenty/observablecollection@5.16.0) (2023-05-26)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Add :Observe() calls to ObservableList and ObservableSortedList ([2f22fbc](https://github.com/Quenty/NevermoreEngine/commit/2f22fbc0830f51aa73ba01b6bb0d25f736e37b6e))
|
|
12
|
+
* Initial refactor of guis to use ValueObject instead of ValueObject ([723aba0](https://github.com/Quenty/NevermoreEngine/commit/723aba0208cae7e06c9d8bf2d8f0092d042d70ea))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
6
18
|
# [5.15.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/observablecollection@5.14.0...@quenty/observablecollection@5.15.0) (2023-05-08)
|
|
7
19
|
|
|
8
20
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/observablecollection",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.16.0",
|
|
4
4
|
"description": "A set of observable collections, such as sets, maps, sorted lists, and more.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -27,17 +27,17 @@
|
|
|
27
27
|
"Quenty"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@quenty/brio": "^8.
|
|
30
|
+
"@quenty/brio": "^8.13.0",
|
|
31
31
|
"@quenty/loader": "^6.2.1",
|
|
32
32
|
"@quenty/maid": "^2.5.0",
|
|
33
33
|
"@quenty/promise": "^6.5.0",
|
|
34
|
-
"@quenty/rx": "^7.
|
|
35
|
-
"@quenty/signal": "^2.
|
|
34
|
+
"@quenty/rx": "^7.11.0",
|
|
35
|
+
"@quenty/signal": "^2.4.0",
|
|
36
36
|
"@quenty/symbol": "^2.2.0",
|
|
37
|
-
"@quenty/
|
|
37
|
+
"@quenty/valueobject": "^7.14.0"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "11058e90e51ea83d3dad6ae9abe59cc19c36b94b"
|
|
43
43
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
local require = require(script.Parent.loader).load(script)
|
|
6
6
|
|
|
7
7
|
local BaseObject = require("BaseObject")
|
|
8
|
-
local ObservableSortedList = require("ObservableSortedList")
|
|
9
8
|
local Observable = require("Observable")
|
|
9
|
+
local ObservableSortedList = require("ObservableSortedList")
|
|
10
10
|
local Rx = require("Rx")
|
|
11
11
|
|
|
12
12
|
local FilteredObservableListView = setmetatable({}, BaseObject)
|
|
@@ -35,10 +35,6 @@ function FilteredObservableListView.new(observableList, observeScoreCallback, co
|
|
|
35
35
|
end)
|
|
36
36
|
self._maid:GiveTask(self._scoredList)
|
|
37
37
|
|
|
38
|
-
self._countValue = Instance.new("IntValue")
|
|
39
|
-
self._countValue.Value = 0
|
|
40
|
-
self._maid:GiveTask(self._countValue)
|
|
41
|
-
|
|
42
38
|
-- Shockingly this is somewhat performant because the sorted list defers all events
|
|
43
39
|
-- to process the list reordering.
|
|
44
40
|
self._maid:GiveTask(self._baseList:ObserveItemsBrio():Subscribe(function(brio)
|
|
@@ -9,7 +9,7 @@ local Signal = require("Signal")
|
|
|
9
9
|
local Observable = require("Observable")
|
|
10
10
|
local Maid = require("Maid")
|
|
11
11
|
local Brio = require("Brio")
|
|
12
|
-
local
|
|
12
|
+
local ValueObject = require("ValueObject")
|
|
13
13
|
|
|
14
14
|
local ObservableCountingMap = {}
|
|
15
15
|
ObservableCountingMap.ClassName = "ObservableCountingMap"
|
|
@@ -25,8 +25,7 @@ function ObservableCountingMap.new()
|
|
|
25
25
|
self._maid = Maid.new()
|
|
26
26
|
self._map = {}
|
|
27
27
|
|
|
28
|
-
self._totalKeyCountValue =
|
|
29
|
-
self._totalKeyCountValue.Value = 0
|
|
28
|
+
self._totalKeyCountValue = ValueObject.new(0, "number")
|
|
30
29
|
self._maid:GiveTask(self._totalKeyCountValue)
|
|
31
30
|
|
|
32
31
|
--[=[
|
|
@@ -198,7 +197,7 @@ end
|
|
|
198
197
|
@return Observable<number>
|
|
199
198
|
]=]
|
|
200
199
|
function ObservableCountingMap:ObserveTotalKeyCount()
|
|
201
|
-
return
|
|
200
|
+
return self._totalKeyCountValue:Observe()
|
|
202
201
|
end
|
|
203
202
|
|
|
204
203
|
--[=[
|
|
@@ -9,8 +9,9 @@ local Signal = require("Signal")
|
|
|
9
9
|
local Observable = require("Observable")
|
|
10
10
|
local Maid = require("Maid")
|
|
11
11
|
local Brio = require("Brio")
|
|
12
|
-
local RxValueBaseUtils = require("RxValueBaseUtils")
|
|
13
12
|
local Symbol = require("Symbol")
|
|
13
|
+
local ValueObject = require("ValueObject")
|
|
14
|
+
local Rx = require("Rx")
|
|
14
15
|
|
|
15
16
|
local ObservableList = {}
|
|
16
17
|
ObservableList.ClassName = "ObservableList"
|
|
@@ -31,8 +32,7 @@ function ObservableList.new()
|
|
|
31
32
|
|
|
32
33
|
self._keyObservables = {} -- { [Symbol]: { Subscription } }
|
|
33
34
|
|
|
34
|
-
self._countValue =
|
|
35
|
-
self._countValue.Value = 0
|
|
35
|
+
self._countValue = ValueObject.new(0, "number")
|
|
36
36
|
self._maid:GiveTask(self._countValue)
|
|
37
37
|
|
|
38
38
|
--[=[
|
|
@@ -72,6 +72,23 @@ function ObservableList.isObservableList(value)
|
|
|
72
72
|
return type(value) == "table" and getmetatable(value) == ObservableList
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
--[=[
|
|
76
|
+
Observes the list, allocating a new list in the process.
|
|
77
|
+
|
|
78
|
+
@return Observable<{ T }>
|
|
79
|
+
]=]
|
|
80
|
+
function ObservableList:Observe()
|
|
81
|
+
return Rx.combineLatest({
|
|
82
|
+
Rx.fromSignal(self.ItemAdded):Pipe({ Rx.startWith({ true }) });
|
|
83
|
+
Rx.fromSignal(self.ItemRemoved):Pipe({ Rx.startWith({ true }) });
|
|
84
|
+
}):Pipe({
|
|
85
|
+
Rx.throttleDefer();
|
|
86
|
+
Rx.map(function()
|
|
87
|
+
return self:GetList();
|
|
88
|
+
end);
|
|
89
|
+
})
|
|
90
|
+
end
|
|
91
|
+
|
|
75
92
|
--[=[
|
|
76
93
|
Observes all items in the list
|
|
77
94
|
@return Observable<Brio<T>>
|
|
@@ -211,7 +228,7 @@ end
|
|
|
211
228
|
@return number
|
|
212
229
|
]=]
|
|
213
230
|
function ObservableList:GetCount()
|
|
214
|
-
return self._countValue.Value
|
|
231
|
+
return self._countValue.Value or 0
|
|
215
232
|
end
|
|
216
233
|
|
|
217
234
|
--[=[
|
|
@@ -219,7 +236,7 @@ end
|
|
|
219
236
|
@return Observable<number>
|
|
220
237
|
]=]
|
|
221
238
|
function ObservableList:ObserveCount()
|
|
222
|
-
return
|
|
239
|
+
return self._countValue:Observe()
|
|
223
240
|
end
|
|
224
241
|
|
|
225
242
|
--[=[
|
|
@@ -9,7 +9,7 @@ local Signal = require("Signal")
|
|
|
9
9
|
local Observable = require("Observable")
|
|
10
10
|
local Maid = require("Maid")
|
|
11
11
|
local Brio = require("Brio")
|
|
12
|
-
local
|
|
12
|
+
local ValueObject = require("ValueObject")
|
|
13
13
|
|
|
14
14
|
local ObservableMap = {}
|
|
15
15
|
ObservableMap.ClassName = "ObservableMap"
|
|
@@ -27,8 +27,7 @@ function ObservableMap.new()
|
|
|
27
27
|
|
|
28
28
|
self._keyToSubList = {}
|
|
29
29
|
|
|
30
|
-
self._countValue =
|
|
31
|
-
self._countValue.Value = 0
|
|
30
|
+
self._countValue = ValueObject.new(0, "number")
|
|
32
31
|
self._maid:GiveTask(self._countValue)
|
|
33
32
|
|
|
34
33
|
--[=[
|
|
@@ -164,7 +163,7 @@ end
|
|
|
164
163
|
@return number
|
|
165
164
|
]=]
|
|
166
165
|
function ObservableMap:GetCount()
|
|
167
|
-
return self._countValue.Value
|
|
166
|
+
return self._countValue.Value or 0
|
|
168
167
|
end
|
|
169
168
|
|
|
170
169
|
--[=[
|
|
@@ -172,7 +171,7 @@ end
|
|
|
172
171
|
@return Observable<number>
|
|
173
172
|
]=]
|
|
174
173
|
function ObservableMap:ObserveCount()
|
|
175
|
-
return
|
|
174
|
+
return self._countValue:Observe()
|
|
176
175
|
end
|
|
177
176
|
|
|
178
177
|
--[=[
|
|
@@ -13,7 +13,7 @@ local ObservableSet = require("ObservableSet")
|
|
|
13
13
|
local Signal = require("Signal")
|
|
14
14
|
local Brio = require("Brio")
|
|
15
15
|
local RxBrioUtils = require("RxBrioUtils")
|
|
16
|
-
local
|
|
16
|
+
local ValueObject = require("ValueObject")
|
|
17
17
|
|
|
18
18
|
local ObservableMapSet = {}
|
|
19
19
|
ObservableMapSet.ClassName = "ObservableMapSet"
|
|
@@ -47,8 +47,7 @@ function ObservableMapSet.new()
|
|
|
47
47
|
self.SetRemoved = Signal.new() -- :Fire(key)
|
|
48
48
|
self._maid:GiveTask(self.SetRemoved)
|
|
49
49
|
|
|
50
|
-
self._setCount =
|
|
51
|
-
self._setCount.Value = 0
|
|
50
|
+
self._setCount = ValueObject.new(0, "number")
|
|
52
51
|
self._maid:GiveTask(self._setCount)
|
|
53
52
|
|
|
54
53
|
return self
|
|
@@ -107,7 +106,7 @@ end
|
|
|
107
106
|
@return Observable<number>
|
|
108
107
|
]=]
|
|
109
108
|
function ObservableMapSet:ObserveSetCount()
|
|
110
|
-
return
|
|
109
|
+
return self._setCount:Observe()
|
|
111
110
|
end
|
|
112
111
|
|
|
113
112
|
--[=[
|
|
@@ -262,7 +261,9 @@ function ObservableMapSet:_removeObservableSet(key)
|
|
|
262
261
|
self.SetRemoved:Fire(key)
|
|
263
262
|
end
|
|
264
263
|
|
|
265
|
-
|
|
264
|
+
if self._setCount.Destroy then
|
|
265
|
+
self._setCount.Value = self._setCount.Value - 1
|
|
266
|
+
end
|
|
266
267
|
end
|
|
267
268
|
end
|
|
268
269
|
|
|
@@ -278,7 +279,10 @@ function ObservableMapSet:_getOrCreateObservableSet(key)
|
|
|
278
279
|
self._observableSetMap[key] = set
|
|
279
280
|
|
|
280
281
|
self.SetAdded:Fire(key, set)
|
|
281
|
-
|
|
282
|
+
|
|
283
|
+
if self._setCount.Destroy then
|
|
284
|
+
self._setCount.Value = self._setCount.Value + 1
|
|
285
|
+
end
|
|
282
286
|
|
|
283
287
|
self._maid[set] = maid
|
|
284
288
|
return set
|
|
@@ -9,7 +9,7 @@ local Signal = require("Signal")
|
|
|
9
9
|
local Observable = require("Observable")
|
|
10
10
|
local Maid = require("Maid")
|
|
11
11
|
local Brio = require("Brio")
|
|
12
|
-
local
|
|
12
|
+
local ValueObject = require("ValueObject")
|
|
13
13
|
local ObservableSubscriptionTable = require("ObservableSubscriptionTable")
|
|
14
14
|
|
|
15
15
|
local ObservableSet = {}
|
|
@@ -29,8 +29,7 @@ function ObservableSet.new()
|
|
|
29
29
|
self._containsObservables = ObservableSubscriptionTable.new()
|
|
30
30
|
self._maid:GiveTask(self._containsObservables)
|
|
31
31
|
|
|
32
|
-
self._countValue =
|
|
33
|
-
self._countValue.Value = 0
|
|
32
|
+
self._countValue = ValueObject.new(0, "number")
|
|
34
33
|
self._maid:GiveTask(self._countValue)
|
|
35
34
|
|
|
36
35
|
--[=[
|
|
@@ -152,7 +151,7 @@ end
|
|
|
152
151
|
@return number
|
|
153
152
|
]=]
|
|
154
153
|
function ObservableSet:GetCount()
|
|
155
|
-
return self._countValue.Value
|
|
154
|
+
return self._countValue.Value or 0
|
|
156
155
|
end
|
|
157
156
|
|
|
158
157
|
--[=[
|
|
@@ -160,7 +159,7 @@ end
|
|
|
160
159
|
@return Observable<number>
|
|
161
160
|
]=]
|
|
162
161
|
function ObservableSet:ObserveCount()
|
|
163
|
-
return
|
|
162
|
+
return self._countValue:Observe()
|
|
164
163
|
end
|
|
165
164
|
|
|
166
165
|
--[=[
|
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
|
|
15
15
|
local require = require(script.Parent.loader).load(script)
|
|
16
16
|
|
|
17
|
-
local Signal = require("Signal")
|
|
18
|
-
local Observable = require("Observable")
|
|
19
|
-
local Maid = require("Maid")
|
|
20
17
|
local Brio = require("Brio")
|
|
21
|
-
local
|
|
22
|
-
local
|
|
18
|
+
local Maid = require("Maid")
|
|
19
|
+
local Observable = require("Observable")
|
|
23
20
|
local ObservableSubscriptionTable = require("ObservableSubscriptionTable")
|
|
21
|
+
local Rx = require("Rx")
|
|
22
|
+
local Signal = require("Signal")
|
|
23
|
+
local Symbol = require("Symbol")
|
|
24
|
+
local ValueObject = require("ValueObject")
|
|
24
25
|
|
|
25
26
|
-- Higher numbers last. Using <= ensures insertion at end on ties.
|
|
26
27
|
local function defaultCompare(a, b)
|
|
@@ -56,8 +57,8 @@ function ObservableSortedList.new(compare)
|
|
|
56
57
|
self._keyObservables = {} -- { [Symbol]: { Subscription } }
|
|
57
58
|
|
|
58
59
|
self._compare = compare or defaultCompare
|
|
59
|
-
|
|
60
|
-
self._countValue
|
|
60
|
+
|
|
61
|
+
self._countValue = ValueObject.new(0, "number")
|
|
61
62
|
self._maid:GiveTask(self._countValue)
|
|
62
63
|
|
|
63
64
|
--[=[
|
|
@@ -78,6 +79,9 @@ function ObservableSortedList.new(compare)
|
|
|
78
79
|
self.ItemRemoved = Signal.new()
|
|
79
80
|
self._maid:GiveTask(self.ItemRemoved)
|
|
80
81
|
|
|
82
|
+
self.OrderChanged = Signal.new()
|
|
83
|
+
self._maid:GiveTask(self.OrderChanged)
|
|
84
|
+
|
|
81
85
|
--[=[
|
|
82
86
|
Fires when the count changes.
|
|
83
87
|
@prop CountChanged RBXScriptSignal
|
|
@@ -88,6 +92,25 @@ function ObservableSortedList.new(compare)
|
|
|
88
92
|
return self
|
|
89
93
|
end
|
|
90
94
|
|
|
95
|
+
--[=[
|
|
96
|
+
Observes the list, allocating a new list in the process.
|
|
97
|
+
|
|
98
|
+
@return Observable<{ T }>
|
|
99
|
+
]=]
|
|
100
|
+
function ObservableSortedList:Observe()
|
|
101
|
+
return Rx.combineLatest({
|
|
102
|
+
Rx.fromSignal(self.ItemAdded):Pipe({ Rx.startWith({ true }) });
|
|
103
|
+
Rx.fromSignal(self.ItemRemoved):Pipe({ Rx.startWith({ true }) });
|
|
104
|
+
Rx.fromSignal(self.OrderChanged):Pipe({ Rx.startWith({ true }) });
|
|
105
|
+
}):Pipe({
|
|
106
|
+
Rx.throttleDefer();
|
|
107
|
+
Rx.map(function()
|
|
108
|
+
return self:GetList();
|
|
109
|
+
end);
|
|
110
|
+
})
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
91
114
|
--[=[
|
|
92
115
|
Returns whether the value is an observable list
|
|
93
116
|
@param value any
|
|
@@ -251,7 +274,7 @@ end
|
|
|
251
274
|
@return number
|
|
252
275
|
]=]
|
|
253
276
|
function ObservableSortedList:GetCount()
|
|
254
|
-
return self._countValue.Value
|
|
277
|
+
return self._countValue.Value or 0
|
|
255
278
|
end
|
|
256
279
|
|
|
257
280
|
--[=[
|
|
@@ -271,7 +294,7 @@ end
|
|
|
271
294
|
@return Observable<number>
|
|
272
295
|
]=]
|
|
273
296
|
function ObservableSortedList:ObserveCount()
|
|
274
|
-
return
|
|
297
|
+
return self._countValue:Observe()
|
|
275
298
|
end
|
|
276
299
|
|
|
277
300
|
--[=[
|
|
@@ -491,17 +514,24 @@ function ObservableSortedList:_deferChange(countChange, itemAdded, itemRemoved,
|
|
|
491
514
|
end
|
|
492
515
|
|
|
493
516
|
function ObservableSortedList:_queueDeferredChange()
|
|
494
|
-
if
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
517
|
+
if self._deferredChange then
|
|
518
|
+
return
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
self._deferredChange = {
|
|
522
|
+
countChange = 0;
|
|
523
|
+
indexChanges = {};
|
|
524
|
+
itemsAdded = {};
|
|
525
|
+
itemsRemoved = {};
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
self._maid._currentDefer = task.defer(function()
|
|
529
|
+
local snapshot = self._deferredChange
|
|
530
|
+
self._deferredChange = nil
|
|
531
|
+
|
|
532
|
+
task.spawn(function()
|
|
533
|
+
self._maid._currentDefer = nil
|
|
534
|
+
local changed = false
|
|
505
535
|
|
|
506
536
|
self._countValue.Value = self._countValue.Value + snapshot.countChange
|
|
507
537
|
|
|
@@ -510,6 +540,8 @@ function ObservableSortedList:_queueDeferredChange()
|
|
|
510
540
|
if not self.ItemAdded.Destroy then
|
|
511
541
|
break
|
|
512
542
|
end
|
|
543
|
+
|
|
544
|
+
changed = true
|
|
513
545
|
self.ItemAdded:Fire(lastAdded.item, lastAdded.newIndex, lastAdded.key)
|
|
514
546
|
|
|
515
547
|
-- Item adds are included in indexChanges.
|
|
@@ -520,6 +552,7 @@ function ObservableSortedList:_queueDeferredChange()
|
|
|
520
552
|
break
|
|
521
553
|
end
|
|
522
554
|
|
|
555
|
+
changed = true
|
|
523
556
|
self.ItemRemoved:Fire(lastRemoved.item, lastRemoved.key)
|
|
524
557
|
|
|
525
558
|
-- Fire only if we aren't handled by an index change.
|
|
@@ -531,6 +564,8 @@ function ObservableSortedList:_queueDeferredChange()
|
|
|
531
564
|
-- Fire off index change on each key list (if the data isn't stale)
|
|
532
565
|
for _, lastChange in pairs(snapshot.indexChanges) do
|
|
533
566
|
if self._indexes[lastChange.key] == lastChange.newIndex then
|
|
567
|
+
changed = true
|
|
568
|
+
|
|
534
569
|
local subs = self._keyObservables[lastChange.key]
|
|
535
570
|
if subs then
|
|
536
571
|
self:_fireSubs(subs, lastChange.newIndex)
|
|
@@ -539,8 +574,12 @@ function ObservableSortedList:_queueDeferredChange()
|
|
|
539
574
|
self._indexObservers:Fire(lastChange.newIndex, self._contents[lastChange.key])
|
|
540
575
|
end
|
|
541
576
|
end
|
|
577
|
+
|
|
578
|
+
if changed then
|
|
579
|
+
self.OrderChanged:Fire()
|
|
580
|
+
end
|
|
542
581
|
end)
|
|
543
|
-
end
|
|
582
|
+
end)
|
|
544
583
|
end
|
|
545
584
|
|
|
546
585
|
function ObservableSortedList:_findCorrectIndex(sortValue, currentIndex)
|