@quenty/undostack 2.0.0-canary.331.7eefa75.0 → 2.0.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 +151 -1
- package/LICENSE.md +1 -1
- package/package.json +9 -6
- package/src/Shared/UndoStack.lua +62 -14
- package/src/Shared/UndoStackEntry.lua +61 -6
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,157 @@
|
|
|
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
|
-
# [2.0.0
|
|
6
|
+
# [2.0.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.23.0...@quenty/undostack@2.0.0) (2023-10-11)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [1.23.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.22.0...@quenty/undostack@1.23.0) (2023-09-21)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# [1.22.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.21.0...@quenty/undostack@1.22.0) (2023-09-04)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# [1.21.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.20.0...@quenty/undostack@1.21.0) (2023-08-23)
|
|
31
|
+
|
|
32
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# [1.20.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.19.0...@quenty/undostack@1.20.0) (2023-08-01)
|
|
39
|
+
|
|
40
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# [1.19.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.18.0...@quenty/undostack@1.19.0) (2023-07-28)
|
|
47
|
+
|
|
48
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# [1.18.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.17.0...@quenty/undostack@1.18.0) (2023-07-23)
|
|
55
|
+
|
|
56
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# [1.17.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.16.0...@quenty/undostack@1.17.0) (2023-07-15)
|
|
63
|
+
|
|
64
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# [1.16.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.15.0...@quenty/undostack@1.16.0) (2023-07-10)
|
|
71
|
+
|
|
72
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# [1.15.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.14.0...@quenty/undostack@1.15.0) (2023-06-17)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### Features
|
|
82
|
+
|
|
83
|
+
* UndoStackEntry has a maid and can be removed from the stack ([d40668e](https://github.com/Quenty/NevermoreEngine/commit/d40668e07dbd00fc9b816eb7070a1d90219f8e95))
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# [1.14.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.13.0...@quenty/undostack@1.14.0) (2023-05-26)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
### Features
|
|
93
|
+
|
|
94
|
+
* Initial refactor of guis to use ValueObject instead of ValueObject ([723aba0](https://github.com/Quenty/NevermoreEngine/commit/723aba0208cae7e06c9d8bf2d8f0092d042d70ea))
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# [1.13.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.12.0...@quenty/undostack@1.13.0) (2023-05-08)
|
|
101
|
+
|
|
102
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# [1.12.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.11.1...@quenty/undostack@1.12.0) (2023-04-10)
|
|
109
|
+
|
|
110
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## [1.11.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.11.0...@quenty/undostack@1.11.1) (2023-04-07)
|
|
117
|
+
|
|
118
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# [1.11.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.10.0...@quenty/undostack@1.11.0) (2023-04-06)
|
|
125
|
+
|
|
126
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# [1.10.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.9.0...@quenty/undostack@1.10.0) (2023-04-03)
|
|
133
|
+
|
|
134
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# [1.9.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.8.0...@quenty/undostack@1.9.0) (2023-03-31)
|
|
141
|
+
|
|
142
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# [1.8.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.7.0...@quenty/undostack@1.8.0) (2023-03-05)
|
|
149
|
+
|
|
150
|
+
**Note:** Version bump only for package @quenty/undostack
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# [1.7.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/undostack@1.6.0...@quenty/undostack@1.7.0) (2023-02-27)
|
|
7
157
|
|
|
8
158
|
**Note:** Version bump only for package @quenty/undostack
|
|
9
159
|
|
package/LICENSE.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/undostack",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Generalized undo stack for Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -25,13 +25,16 @@
|
|
|
25
25
|
"Quenty"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@quenty/baseobject": "
|
|
29
|
-
"@quenty/instanceutils": "8.0.0
|
|
30
|
-
"@quenty/loader": "
|
|
31
|
-
"@quenty/
|
|
28
|
+
"@quenty/baseobject": "^7.0.0",
|
|
29
|
+
"@quenty/instanceutils": "^8.0.0",
|
|
30
|
+
"@quenty/loader": "^7.0.0",
|
|
31
|
+
"@quenty/maid": "^2.6.0",
|
|
32
|
+
"@quenty/promise": "^7.0.0",
|
|
33
|
+
"@quenty/signal": "^3.0.0",
|
|
34
|
+
"@quenty/valueobject": "^8.0.0"
|
|
32
35
|
},
|
|
33
36
|
"publishConfig": {
|
|
34
37
|
"access": "public"
|
|
35
38
|
},
|
|
36
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "fdeae46099587019ec5fc15317dc673aed379400"
|
|
37
40
|
}
|
package/src/Shared/UndoStack.lua
CHANGED
|
@@ -7,7 +7,8 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
7
|
local BaseObject = require("BaseObject")
|
|
8
8
|
local Promise = require("Promise")
|
|
9
9
|
local UndoStackEntry = require("UndoStackEntry")
|
|
10
|
-
local
|
|
10
|
+
local ValueObject = require("ValueObject")
|
|
11
|
+
local Maid = require("Maid")
|
|
11
12
|
|
|
12
13
|
local DEFAULT_MAX_SIZE = 25
|
|
13
14
|
|
|
@@ -25,16 +26,13 @@ function UndoStack.new(maxSize)
|
|
|
25
26
|
self._undoStack = {}
|
|
26
27
|
self._redoStack = {}
|
|
27
28
|
|
|
28
|
-
self._hasUndoEntries =
|
|
29
|
-
self._hasUndoEntries.Value = false
|
|
29
|
+
self._hasUndoEntries = ValueObject.new(false, "boolean")
|
|
30
30
|
self._maid:GiveTask(self._hasUndoEntries)
|
|
31
31
|
|
|
32
|
-
self._hasRedoEntries =
|
|
33
|
-
self._hasRedoEntries.Value = false
|
|
32
|
+
self._hasRedoEntries = ValueObject.new(false, "boolean")
|
|
34
33
|
self._maid:GiveTask(self._hasRedoEntries)
|
|
35
34
|
|
|
36
|
-
self._isActionExecuting =
|
|
37
|
-
self._isActionExecuting.Value = false
|
|
35
|
+
self._isActionExecuting = ValueObject.new(false, "boolean")
|
|
38
36
|
self._maid:GiveTask(self._isActionExecuting)
|
|
39
37
|
|
|
40
38
|
return self
|
|
@@ -46,7 +44,7 @@ end
|
|
|
46
44
|
@return boolean
|
|
47
45
|
]=]
|
|
48
46
|
function UndoStack:ClearRedoStack()
|
|
49
|
-
self._redoStack ={}
|
|
47
|
+
self._redoStack = {}
|
|
50
48
|
self:_updateHasRedoEntries()
|
|
51
49
|
end
|
|
52
50
|
|
|
@@ -63,7 +61,7 @@ end
|
|
|
63
61
|
@return Observable<boolean>
|
|
64
62
|
]=]
|
|
65
63
|
function UndoStack:ObserveHasUndoEntries()
|
|
66
|
-
return
|
|
64
|
+
return self._hasUndoEntries:Observe()
|
|
67
65
|
end
|
|
68
66
|
|
|
69
67
|
--[=[
|
|
@@ -71,7 +69,7 @@ end
|
|
|
71
69
|
@return Observable<boolean>
|
|
72
70
|
]=]
|
|
73
71
|
function UndoStack:ObserveHasRedoEntries()
|
|
74
|
-
return
|
|
72
|
+
return self._hasRedoEntries:Observe()
|
|
75
73
|
end
|
|
76
74
|
|
|
77
75
|
--[=[
|
|
@@ -111,6 +109,23 @@ end
|
|
|
111
109
|
function UndoStack:Push(undoStackEntry)
|
|
112
110
|
assert(UndoStackEntry.isUndoStackEntry(undoStackEntry), "Bad undoStackEntry")
|
|
113
111
|
|
|
112
|
+
if self._maid[undoStackEntry] then
|
|
113
|
+
return function()
|
|
114
|
+
self:Remove(undoStackEntry)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
local maid = Maid.new()
|
|
119
|
+
maid:GiveTask(undoStackEntry)
|
|
120
|
+
|
|
121
|
+
maid:GiveTask(undoStackEntry.Destroying:Connect(function()
|
|
122
|
+
if undoStackEntry.Destroy then
|
|
123
|
+
self:Remove(undoStackEntry)
|
|
124
|
+
end
|
|
125
|
+
end))
|
|
126
|
+
|
|
127
|
+
self._maid[undoStackEntry] = maid
|
|
128
|
+
|
|
114
129
|
table.insert(self._undoStack, undoStackEntry)
|
|
115
130
|
while #self._undoStack > self._maxSize do
|
|
116
131
|
table.remove(self._undoStack, 1)
|
|
@@ -135,18 +150,25 @@ end
|
|
|
135
150
|
function UndoStack:Remove(undoStackEntry)
|
|
136
151
|
assert(UndoStackEntry.isUndoStackEntry(undoStackEntry), "Bad undoStackEntry")
|
|
137
152
|
|
|
153
|
+
self._maid[undoStackEntry] = nil
|
|
154
|
+
|
|
155
|
+
local changed = false
|
|
138
156
|
local undoIndex = table.find(self._undoStack, undoStackEntry)
|
|
139
157
|
if undoIndex then
|
|
140
158
|
table.remove(self._undoStack, undoIndex)
|
|
159
|
+
changed = true
|
|
141
160
|
end
|
|
142
161
|
|
|
143
162
|
local redoIndex = table.find(self._redoStack, undoStackEntry)
|
|
144
163
|
if redoIndex then
|
|
145
164
|
table.remove(self._redoStack, redoIndex)
|
|
165
|
+
changed = true
|
|
146
166
|
end
|
|
147
167
|
|
|
148
|
-
|
|
149
|
-
|
|
168
|
+
if changed then
|
|
169
|
+
self:_updateHasUndoEntries()
|
|
170
|
+
self:_updateHasRedoEntries()
|
|
171
|
+
end
|
|
150
172
|
end
|
|
151
173
|
|
|
152
174
|
--[=[
|
|
@@ -163,7 +185,9 @@ function UndoStack:PromiseUndo()
|
|
|
163
185
|
|
|
164
186
|
self:_updateHasUndoEntries()
|
|
165
187
|
|
|
166
|
-
return
|
|
188
|
+
return self:_executePromiseWithMaid(function(maid)
|
|
189
|
+
return undoStackEntry:PromiseUndo(maid)
|
|
190
|
+
end)
|
|
167
191
|
:Then(function()
|
|
168
192
|
if undoStackEntry:HasRedo() then
|
|
169
193
|
table.insert(self._redoStack, undoStackEntry)
|
|
@@ -189,7 +213,9 @@ function UndoStack:PromiseRedo()
|
|
|
189
213
|
|
|
190
214
|
self:_updateHasRedoEntries()
|
|
191
215
|
|
|
192
|
-
return
|
|
216
|
+
return self:_executePromiseWithMaid(function(maid)
|
|
217
|
+
return undoStackEntry:PromiseRedo(maid)
|
|
218
|
+
end)
|
|
193
219
|
:Then(function()
|
|
194
220
|
if undoStackEntry:HasUndo() then
|
|
195
221
|
table.insert(self._undoStack, undoStackEntry)
|
|
@@ -227,6 +253,28 @@ function UndoStack:_promiseCurrent(doNextPromise)
|
|
|
227
253
|
return promise
|
|
228
254
|
end
|
|
229
255
|
|
|
256
|
+
function UndoStack:_executePromiseWithMaid(callback)
|
|
257
|
+
local maid = Maid.new()
|
|
258
|
+
|
|
259
|
+
local promise = Promise.new()
|
|
260
|
+
maid:GiveTask(promise)
|
|
261
|
+
|
|
262
|
+
local result = callback(maid)
|
|
263
|
+
|
|
264
|
+
maid:GiveTask(function()
|
|
265
|
+
self._maid[maid] = nil
|
|
266
|
+
end)
|
|
267
|
+
self._maid[maid] = maid
|
|
268
|
+
|
|
269
|
+
promise:Finally(function()
|
|
270
|
+
self._maid[maid] = nil
|
|
271
|
+
end)
|
|
272
|
+
|
|
273
|
+
promise:Resolve(result)
|
|
274
|
+
|
|
275
|
+
return promise
|
|
276
|
+
end
|
|
277
|
+
|
|
230
278
|
function UndoStack:_updateHasUndoEntries()
|
|
231
279
|
self._hasUndoEntries.Value = #self._undoStack > 0
|
|
232
280
|
end
|
|
@@ -1,51 +1,98 @@
|
|
|
1
1
|
--[=[
|
|
2
|
+
Holds undo state
|
|
2
3
|
@class UndoStackEntry
|
|
3
4
|
]=]
|
|
4
5
|
|
|
5
6
|
local require = require(script.Parent.loader).load(script)
|
|
6
7
|
|
|
7
8
|
local Promise = require("Promise")
|
|
9
|
+
local Maid = require("Maid")
|
|
10
|
+
local BaseObject = require("BaseObject")
|
|
11
|
+
local Signal = require("Signal")
|
|
8
12
|
|
|
9
|
-
local UndoStackEntry = {}
|
|
13
|
+
local UndoStackEntry = setmetatable({}, BaseObject)
|
|
10
14
|
UndoStackEntry.ClassName = "UndoStackEntry"
|
|
11
15
|
UndoStackEntry.__index = UndoStackEntry
|
|
12
16
|
|
|
17
|
+
--[=[
|
|
18
|
+
Constructs a new undo restack entry. See [UndoStack] for usage.
|
|
19
|
+
|
|
20
|
+
@return UndoStackEntry
|
|
21
|
+
]=]
|
|
13
22
|
function UndoStackEntry.new()
|
|
14
|
-
local self = setmetatable(
|
|
23
|
+
local self = setmetatable(BaseObject.new(), UndoStackEntry)
|
|
24
|
+
|
|
25
|
+
self.Destroying = Signal.new()
|
|
26
|
+
self._maid:GiveTask(function()
|
|
27
|
+
self.Destroying:Fire()
|
|
28
|
+
self.Destroying:Destroy()
|
|
29
|
+
end)
|
|
15
30
|
|
|
16
31
|
return self
|
|
17
32
|
end
|
|
18
33
|
|
|
34
|
+
--[=[
|
|
35
|
+
Returns true if the etnry is an undo stack entry
|
|
36
|
+
|
|
37
|
+
@param value any
|
|
38
|
+
@return boolean
|
|
39
|
+
]=]
|
|
19
40
|
function UndoStackEntry.isUndoStackEntry(value)
|
|
20
41
|
return type(value) == "table" and getmetatable(value) == UndoStackEntry
|
|
21
42
|
end
|
|
22
43
|
|
|
44
|
+
--[=[
|
|
45
|
+
Sets the handler that will undo the result
|
|
46
|
+
|
|
47
|
+
@param promiseUndo function | nil
|
|
48
|
+
]=]
|
|
23
49
|
function UndoStackEntry:SetPromiseUndo(promiseUndo)
|
|
24
50
|
assert(type(promiseUndo) == "function" or promiseUndo == nil, "Bad promiseUndo")
|
|
25
51
|
|
|
26
52
|
self._promiseUndo = promiseUndo
|
|
27
53
|
end
|
|
28
54
|
|
|
55
|
+
--[=[
|
|
56
|
+
Sets the handler that will redo the result
|
|
57
|
+
|
|
58
|
+
@param promiseRedo function | nil
|
|
59
|
+
]=]
|
|
29
60
|
function UndoStackEntry:SetPromiseRedo(promiseRedo)
|
|
30
61
|
assert(type(promiseRedo) == "function" or promiseRedo == nil, "Bad promiseRedo")
|
|
31
62
|
|
|
32
63
|
self._promiseRedo = promiseRedo
|
|
33
64
|
end
|
|
34
65
|
|
|
66
|
+
--[=[
|
|
67
|
+
Returns true if this entry can be undone
|
|
68
|
+
@return boolean
|
|
69
|
+
]=]
|
|
35
70
|
function UndoStackEntry:HasUndo()
|
|
36
71
|
return self._promiseUndo ~= nil
|
|
37
72
|
end
|
|
38
73
|
|
|
74
|
+
--[=[
|
|
75
|
+
Returns true if this entry can be redone
|
|
76
|
+
@return boolean
|
|
77
|
+
]=]
|
|
39
78
|
function UndoStackEntry:HasRedo()
|
|
40
79
|
return self._promiseRedo ~= nil
|
|
41
80
|
end
|
|
42
81
|
|
|
43
|
-
|
|
82
|
+
--[=[
|
|
83
|
+
Promises undo. Should be done via [UndoStack.PromiseUndo]
|
|
84
|
+
|
|
85
|
+
@param maid Maid
|
|
86
|
+
@return Promise
|
|
87
|
+
]=]
|
|
88
|
+
function UndoStackEntry:PromiseUndo(maid)
|
|
89
|
+
assert(Maid.isMaid(maid), "Bad maid")
|
|
90
|
+
|
|
44
91
|
if not self._promiseUndo then
|
|
45
92
|
return Promise.resolved()
|
|
46
93
|
end
|
|
47
94
|
|
|
48
|
-
local result = self._promiseUndo()
|
|
95
|
+
local result = maid:GivePromise(self._promiseUndo(maid))
|
|
49
96
|
if Promise.isPromise(result) then
|
|
50
97
|
return result
|
|
51
98
|
else
|
|
@@ -53,12 +100,20 @@ function UndoStackEntry:PromiseUndo()
|
|
|
53
100
|
end
|
|
54
101
|
end
|
|
55
102
|
|
|
56
|
-
|
|
103
|
+
--[=[
|
|
104
|
+
Promises redo execution. Should be done via [UndoStack.PromiseRedo]
|
|
105
|
+
|
|
106
|
+
@param maid Maid
|
|
107
|
+
@return Promise
|
|
108
|
+
]=]
|
|
109
|
+
function UndoStackEntry:PromiseRedo(maid)
|
|
110
|
+
assert(Maid.isMaid(maid), "Bad maid")
|
|
111
|
+
|
|
57
112
|
if not self._promiseUndo then
|
|
58
113
|
return Promise.resolved()
|
|
59
114
|
end
|
|
60
115
|
|
|
61
|
-
local result = self._promiseRedo()
|
|
116
|
+
local result = maid:GivePromise(self._promiseRedo(maid))
|
|
62
117
|
if Promise.isPromise(result) then
|
|
63
118
|
return result
|
|
64
119
|
else
|