/
Counter.lua
107 lines (81 loc) · 1.95 KB
/
Counter.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
--[=[
@class Counter
]=]
local require = require(script.Parent.loader).load(script)
local BaseObject = require("BaseObject")
local Maid = require("Maid")
local Observable = require("Observable")
local ValueObject = require("ValueObject")
local Counter = setmetatable({}, BaseObject)
Counter.ClassName = "Counter"
Counter.__index = Counter
--[=[
Creates a new counter
@return Counter
]=]
function Counter.new()
local self = setmetatable(BaseObject.new(), Counter)
self._count = self._maid:Add(ValueObject.new(0, "number"))
self.Changed = assert(self._count.Changed, "Bad .Changed")
return self
end
--[=[
Returns the current count
@return number
]=]
function Counter:GetValue()
return self._count.Value
end
--[=[
Observes the current count
@return number
]=]
function Counter:Observe()
return self._count:Observe()
end
--[=[
Adds an amount to the counter.
@param amount number | Observable<number>
@return MaidTask
]=]
function Counter:Add(amount)
if type(amount) == "number" then
self._count.Value = self._count.Value + amount
return function()
if self._count.Destroy then
self._count.Value = self._count.Value - amount
end
end
elseif Observable.isObservable(amount) then
return self:_addObservable(amount)
else
error("Bad amount")
end
end
function Counter:_addObservable(observeAmount)
assert(Observable.isObservable(observeAmount), "Bad observeAmount")
local lastCount = 0
local maid = Maid.new()
maid:GiveTask(observeAmount:Subscribe(function(count)
assert(type(count) == "number", "Bad count")
local delta = count - lastCount
lastCount = count
self._count.Value = self._count.Value + delta
end))
maid:GiveTask(function()
if not self._count.Destroy then
return
end
local delta = lastCount
lastCount = 0
self._count.Value = self._count.Value - delta
end)
self._maid[maid] = maid
maid:GiveTask(function()
self._maid[maid] = nil
end)
return function()
self._maid[maid] = nil
end
end
return Counter