/
init.lua
97 lines (82 loc) · 1.92 KB
/
init.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
-- TaskQueue
-- Stephen Leitnick
-- November 20, 2021
--[=[
@class TaskQueue
A queue that flushes all objects at the end of the current
execution step. This works by scheduling all tasks with
`task.defer`.
A possible use-case is to batch all requests being sent through
a RemoteEvent to help prevent calling it too many times on
the same frame.
```lua
local bulletQueue = TaskQueue.new(function(bullets)
bulletRemoteEvent:FireAllClients(bullets)
end)
-- Add 3 bullets. Because they're all added on the same
-- execution step, they will all be grouped together on
-- the next queue flush, which the above function will
-- handle.
bulletQueue:Add(someBullet)
bulletQueue:Add(someBullet)
bulletQueue:Add(someBullet)
```
]=]
local TaskQueue = {}
TaskQueue.__index = TaskQueue
--[=[
@param onFlush ({T}) -> ()
@return TaskQueue<T>
Constructs a new TaskQueue.
]=]
function TaskQueue.new<T>(onFlush: ({ T }) -> ())
local self = setmetatable({}, TaskQueue)
self._queue = {}
self._flushing = false
self._scheduled = nil
self._onFlush = onFlush
return self
end
--[=[
@param object T
Add an object to the queue.
]=]
function TaskQueue:Add<T>(object: T)
table.insert(self._queue, object)
if self._scheduled == nil then
self._scheduled = task.defer(function()
self._flushing = true
self._onFlush(self._queue)
table.clear(self._queue)
self._flushing = false
self._scheduled = nil
end)
end
end
--[=[
Clears the TaskQueue. This will clear any tasks
that were scheduled to be flushed on the current
execution frame.
```lua
queue:Add(something1)
queue:Add(something2)
queue:Clear()
```
]=]
function TaskQueue:Clear()
if self._flushing then
return
end
if self._scheduled ~= nil then
task.cancel(self._scheduled)
self._scheduled = nil
end
table.clear(self._queue)
end
--[=[
Destroys the TaskQueue. Just an alias for `Clear()`.
]=]
function TaskQueue:Destroy()
self:Clear()
end
return TaskQueue