@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 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.15.0",
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.12.0",
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.10.0",
35
- "@quenty/signal": "^2.3.0",
34
+ "@quenty/rx": "^7.11.0",
35
+ "@quenty/signal": "^2.4.0",
36
36
  "@quenty/symbol": "^2.2.0",
37
- "@quenty/valuebaseutils": "^7.13.0"
37
+ "@quenty/valueobject": "^7.14.0"
38
38
  },
39
39
  "publishConfig": {
40
40
  "access": "public"
41
41
  },
42
- "gitHead": "2ad8cea7dd3ad79a39afd7d7b785b489b90553fd"
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 RxValueBaseUtils = require("RxValueBaseUtils")
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 = Instance.new("IntValue")
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 RxValueBaseUtils.observeValue(self._totalKeyCountValue)
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 = Instance.new("IntValue")
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 RxValueBaseUtils.observeValue(self._countValue)
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 RxValueBaseUtils = require("RxValueBaseUtils")
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 = Instance.new("IntValue")
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 RxValueBaseUtils.observeValue(self._countValue)
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 RxValueBaseUtils = require("RxValueBaseUtils")
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 = Instance.new("IntValue")
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 RxValueBaseUtils.observeValue(self._setCount)
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
- self._setCount.Value = self._setCount.Value - 1
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
- self._setCount.Value = self._setCount.Value + 1
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 RxValueBaseUtils = require("RxValueBaseUtils")
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 = Instance.new("IntValue")
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 RxValueBaseUtils.observeValue(self._countValue)
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 RxValueBaseUtils = require("RxValueBaseUtils")
22
- local Symbol = require("Symbol")
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
- self._countValue = Instance.new("IntValue")
60
- self._countValue.Value = 0
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 RxValueBaseUtils.observeValue(self._countValue)
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 not self._deferredChange then
495
- self._deferredChange = {
496
- countChange = 0;
497
- indexChanges = {};
498
- itemsAdded = {};
499
- itemsRemoved = {};
500
- }
501
-
502
- task.defer(function()
503
- local snapshot = self._deferredChange
504
- self._deferredChange = nil
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)