-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtime.lua
150 lines (124 loc) · 4.68 KB
/
time.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
--[[
#########################################################################
# #
# time.lua #
# #
# Timer objects for scheduled events #
# #
# Copyright 2011 Josh Bothun #
# http://minornine.com #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License <http://www.gnu.org/licenses/> for #
# more details. #
# #
#########################################################################
--]]
require 'math'
require 'leaf.object'
require 'leaf.containers'
require 'leaf.functional'
-- Timer class --
local Timer = leaf.Object:extend()
function Timer:init(duration, callback, loops, start)
self.duration = duration
self.callback = callback
self.loops = loops or 1
self.timeleft = self.duration
self.running = false
self.dead = false
start = start or true
if start then self:start() end
end
-- Start or restart the timer
function Timer:start()
self.running = true
self.timeleft = self.duration
end
Timer.restart = Timer.start
-- Stops timer and flags it for removal
function Timer:kill()
self.running = false
self.dead = true
end
-- Safe pause
function Timer:pause()
self.running = false
end
-- Safe resume
function Timer:resume()
self.running = true
end
-- Update the timer
function Timer:update(dt)
if self.running then
self.timeleft = self.timeleft - dt
if self.timeleft < 0.0 then
self.timeleft = self.timeleft + self.duration
self.callback()
-- Check how many loops remaining, loop infinitely if set to < 0
self.loops = math.max(self.loops - 1, -1) -- Prevent overflow
if self.loops == 0 then self:kill() end
return true
end
return false
end
return false
end
-- Interpolator class --
-- Interpolators which execute every tick, passing
-- a 0-1 alpha argument to its bound callback
local Interpolator = Timer:extend()
function Interpolator:update(dt)
if Timer.update(self) then
-- Finished, call with max value
self.callback(1)
end
-- Calculate alpha
local alpha = 1.0 - self.timeleft / self.duration
self.callback(alpha)
end
-- Time controller class
local Time = leaf.Object:extend()
function Time:init()
self.timers = {}
end
-- Update time system -- this must be called from main loop
function Time:update(dt)
-- Clean up dead timers
leaf.remove_if(self.timers, function(t) return t.dead end)
-- Update alive timers
for i, timer in ipairs(self.timers) do
timer:update(dt)
end
end
-- Create, register and return a new timer
function Time:timer(duration, callback, loops, start)
local timer = Timer(duration, callback, loops, start)
table.insert(self.timers, timer)
return timer
end
-- Create, register and return a new interpolator
function Time:interp(duration, callback, loops, start)
local interp = Interpolator(duration, callback, loops, start)
table.insert(self.timers, interp)
return interp
end
-- Schedule `callback` after `duration` milliseconds
function Time:after(duration, callback, loops)
return self:timer(duration, callback, 1, true)
end
-- Schedule `callback` every `duration` milliseconds
function Time:every(duration, callback, loops)
return self:timer(duration, callback, loops or 0, true)
end
-- Namespace exports
leaf.Time = Time