-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathTransitionManager.lua
309 lines (309 loc) · 35.5 KB
/
TransitionManager.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
--------------------------------------------------------------------------------------------------------------------
local mexico = require "mexico" -- load the mexico framework --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Class: TransitionManager --
-- --
-- Used to manage all transitions in a game scene. You can pause, resume and cancel all transitions at once. --
-- --
-- Properties: --
-- + isPaused [boolean] : (ReadOnly) Indicates whether all managed transitions are cureently paused or not. -- --
-- The value of this property is important if you add new transitions after a call to --
-- <TransitionManager:pauseAll>. If it is true, all newly added transitions are auto- --
-- matically paused. --
-- --
-- Methods: --
-- + to ( target , params) --
-- + from ( target , params) --
-- + cancel ( id ) --
-- + pause ( id ) --
-- + resume ( id ) --
-- + pauseAll ( ) --
-- + resumeAll ( ) --
-- + cancelAll ( ) --
-- --
--------------------------------------------------------------------------------------------------------------------
local TransitionManager = mexico.class(mexico.Object) --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Constructor --
-- --
-- Parameters: --
-- + isPaused [boolean] : Initial manager state. --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:init(isPaused) -- --
self.nextId = 1 -- next item id --
self.items = {} -- container for transition items --
self.isPaused = isPaused -- paused or not by default --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- (Internal) Used by <TransitionManager:to> and <TransitionManager:from> to track a corona transition. --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:add(target, params) -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
local itemId = self.nextId -- next item id --
self.nextId = itemId + 1 -- increase next id --
--------------------------------------------------------------------------------------------------------------------
local item = { -- create transition state item --
id = itemId, -- unique id --
state = "added", -- current transition state --
target = target, -- transition target --
params = params, -- transition parameters --
original = { -- remember some original params --
onComplete = params.onComplete, -- original on complete callback --
delay = params.delay, -- original transition delay --
time = params.time, -- original transition time --
}, -- --
--------------------------------------------------------------------------------------------------------------------
to = function(me) -- transition to wrapper --
me.mode = "to" -- transition mode is to --
me.started = system.getTimer() -- start time --
me.handle = transition.to(me.target, me.params) -- corona transition handle --
me.state = "running" -- state is now running --
end, -- --
--------------------------------------------------------------------------------------------------------------------
from = function(me) -- transition from wrapper --
me.mode = "from" -- transition mode is from --
me.started = system.getTimer() -- start time --
me.handle = transition.from(me.target, me.params) -- corona transition handle --
me.state = "running" -- state is now running --
end, -- --
--------------------------------------------------------------------------------------------------------------------
prepare = function(me, mode) -- prepare transition but not start it --
me.mode = mode -- the target transition mode --
me.started = system.getTimer() -- set started time = paused time --
me.paused = me.started -- --
me.state = "paused" -- initial state is paused --
end, -- --
--------------------------------------------------------------------------------------------------------------------
pause = function(me) -- --
if (me.state == "running") then -- test if transation running (or sheduled) --
if me.handle then -- --
transition.cancel(me.handle) -- cancel corona transition --
me.handle = nil -- --
me.paused = system.getTimer() -- paused since --
me.state = "paused" -- state is paused now --
end -- --
end -- --
end, -- --
--------------------------------------------------------------------------------------------------------------------
resume = function(me) -- --
if (me.state == "paused") then -- test if transation is paused --
local elapsed = me.paused - me.started -- elapsed time between started and paused --
if ((me.params.delay or 0) > elapsed) then -- test if transition is still delayed --
me.params.delay = me.params.delay - elapsed -- shorten delay time --
else -- or it transition time must be cut --
me.params.time = me.params.time - elapsed - -- calculate left transition time --
(me.params.delay or 0) -- --
me.params.delay = 0 -- reset delay --
end -- --
me.paused = 0 -- reset paused since time --
if me.mode == "from" then -- restart either to or from transition --
me:from() else -- --
me:to() -- --
end -- --
end -- --
end, -- --
--------------------------------------------------------------------------------------------------------------------
cancel = function(me) -- --
if (me.state == "running") then -- test if transation is running (or sheduled) --
if me.handle then -- --
transition.cancel(me.handle) -- cancel corona transition --
end -- --
me:restore() -- restore transition to its original state --
me:dispose() -- dispose item since it is no longer of use --
end -- --
end, -- --
--------------------------------------------------------------------------------------------------------------------
restore = function(me) -- Used to restore the transition into its --
me.params.onComplete = me.original.onComplete -- original state --
me.params.delay = me.original.delay -- --
me.params.time = me.original.time -- --
end, -- --
--------------------------------------------------------------------------------------------------------------------
dispose = function(me) -- Used to clean the item if it is no longer --
if me.original then -- of use. --
me.original.onComplete = nil -- --
me.original = nil -- --
end -- --
me.target = nil -- --
me.params = nil -- --
me.handle = nil -- --
end, -- --
} -- --
--------------------------------------------------------------------------------------------------------------------
params.onComplete = function() self:onComplete(itemId) end -- change onComplete callback --
self.items[itemId] = item -- store item reference --
return item -- return item --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- (Internal) Called after a transition is complete. --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:onComplete(itemId) -- --
local item = self.items[itemId] -- get item by id --
if item then -- do we have an item? --
local callback = item.original.onComplete -- original on complete callback --
item:restore() -- restore transition to its original state --
item:dispose() -- dispose item since it is no longer of use --
self.items[itemId] = nil -- remove item from manager --
item = nil -- --
if callback then callback() end -- invoke original on complete callback --
end -- --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Animates a display object's properties over time. --
-- --
-- Parameters: --
-- + target [object] : A display object that will be the target of the transition. --
-- + params [table] : A table that specifies the properties of the display object which will be animated. --
-- --
-- Returns: --
-- A unique id identifing the transition. This is NOT the handle returned by corona's transition.to. --
-- --
-- --
-- See Corona SDK documentation (http://developer.anscamobile.com/node/2407) for more information. --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:to(target, params) -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
local item = self:add(target, params) -- add transition to item collection --
if self.isPaused then item:prepare("to") else item:to() end -- if manager is paused then do not start the --
return item.id -- transition directly, instead just set the --
end -- target transition mode --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Similar to <TransitionManager:to> except the starting property values are specified in the function's --
-- parameter table and the final values are the corresponding property values in target prior to the call. --
-- --
-- Parameters: --
-- + target [object] : A display object that will be the target of the transition. --
-- + params [table] : A table that specifies the properties of the display object which will be animated. --
-- --
-- Returns: --
-- A unique id identifing the transition. This is NOT the handle returned by corona's transition.from. --
-- --
-- Remarks: --
-- Note that adding a from-transition to a paused transition manager may result in an unexpected behavior. --
-- --
-- See Corona SDK documentation (http://developer.anscamobile.com/node/2407) for more information. --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:from(target, params) -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
local item = self:add(target, params) -- add transition to item collection --
if self.isPaused then item:prepare("from") else -- if manager is paused then do not start the --
item:from() end -- --
return item.id -- transition directly, instead just set the --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Cancel a single running or sheduled transition. --
-- --
-- Parameters: --
-- + id [number] : The id assigned and returned by <TransitionManager:to> or <TransitionManager:from>. --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:cancel(id) -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
local item = self.items[id] -- get item by id --
if (item) then -- check if item is not null --
item:cancel() -- cancel item --
item = nil -- --
self.items[id] = nil -- remove item from items collection --
mexico.gc:collect() -- collect garbage next frame --
return true -- transition canceled --
end -- --
return false -- failed but ok --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Pauses a single running or sheduled transition. --
-- --
-- Parameters: --
-- + id [number] : The id assigned and returned by <TransitionManager:to> or <TransitionManager:from>. --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:pause(id) -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
local item = self.items[id] -- get item by id --
if (item) then -- check if item is not null --
item:pause() -- pause item --
return true -- transition paused --
end -- --
return false -- failed but ok --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Resumes a previously paused transition. --
-- --
-- Parameters: --
-- + id [number] : The id assigned and returned by <TransitionManager:to> or <TransitionManager:from>. --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:resume(id) -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
local item = self.items[id] -- get item by id --
if (item) then -- check if item is not null --
item:resume() -- resume item --
return true -- transition resumed --
end -- --
return false -- failed but ok --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Cancel all running or sheduled transitions at once. --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:cancelAll() -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
print("TransitionManager: cancelAll") -- --
for id,item in pairs(self.items) do -- iterate over all transition items --
item:cancel() -- cancel the transition --
item = nil -- --
end -- --
self.items = {} -- reset items collection --
mexico.gc:collect() -- collect garbage next frame --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Pauses all running or sheduled transitions at once. --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:pauseAll() -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
print("TransitionManager: pauseAll") -- --
self.isPaused = true -- will auto pause all further added transitions --
for id,item in pairs(self.items) do -- iterate over all transition items --
item:pause() -- pause the transition --
end -- --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Resumes all previously paused transitions at once. --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:resumeAll() -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
print("TransitionManager: resumeAll") -- --
self.isPaused = false -- --
for id,item in pairs(self.items) do -- iterate over all transition items --
item:resume() -- resume the transition --
end -- --
end -- --
--------------------------------------------------------------------------------------------------------------------
-- --
-- Disposes the manager and releases all resources (all running transitions will be canceled). --
-- --
--------------------------------------------------------------------------------------------------------------------
function TransitionManager:dispose() -- --
mexico.Object.assert(self) -- test if self is not null and not disposed --
self:cancelAll() -- cancel all transitions --
self.items = nil -- remove transition item collection --
mexico.Object.dispose(self) -- base or super dispose call --
end -- --
--------------------------------------------------------------------------------------------------------------------
return TransitionManager --
--------------------------------------------------------------------------------------------------------------------