Skip to content

Instantly share code, notes, and snippets.

@apendley
Last active December 16, 2015 05:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save apendley/5382684 to your computer and use it in GitHub Desktop.
Save apendley/5382684 to your computer and use it in GitHub Desktop.
Lua Timing classes compatible with Codea
--# Main
-- Main
function setup()
timer = createTimer()
scheduler = createScheduler()
timer(.5, 0, function(t) print('timer:', t.elapsed) end)
timer(1, 1, function(t, ...) print('Hello', ...) end, 'Aaron!')
timer(1.5, 0, function(t)
print('timer2:', t.ncalled, t.elapsed)
if t.ncalled == 5 then
print('stopping timer2')
t:stop()
timer(5, 1, function()
print('restarting timer2')
t:reset()
end)
end
end)
local o, _elapsed = {}, 0
function o:func(dt, ...)
_elapsed = _elapsed + dt
print('o:func', dt, _elapsed)
if _elapsed > 2 then
scheduler.remove(o, 'func')
print('removing o:func() from schedule')
end
end
scheduler.add(o, 'func')
end
function draw()
local dt = DeltaTime
scheduler.elapsed(dt)
timer.elapsed(dt)
end
--# createScheduler
-- createScheduler
local pairs = pairs
local type = type
_G.createScheduler = function()
local _scheduled, _locked = {}
local function _elapsed(dt)
_locked = {}
local method
for target, methods in pairs(_scheduled) do
for method, params in pairs(methods) do
if type(method) == 'string' then
target[method](target, dt)
else
method(target, dt)
end
end
end
for target, methods in pairs(_locked) do
local tmethods = _scheduled[target]
if tmethods then
for method, params in pairs(methods) do
tmethods[method] = params
end
else
_scheduled[target] = _locked[target]
end
end
_locked = nil
end
local function _add(target, method)
local targets, methods = _locked and _locked or _scheduled
methods = targets[target]
if not methods then
methods = {}
targets[target] = methods
end
methods[method] = true
end
local function _remove(target, method)
if method == nil then
_scheduled[target] = nil
if _locked then _locked[target] = nil end
else
local methods = _scheduled[target]
if methods then methods[method] = nil end
if _locked then
methods = _locked[target]
if methods then methods[method] = nil end
end
end
end
return {
elapsed = _elapsed,
add = _add,
remove = _remove
}
end
--# createTimer
-- createTimer
local pairs = pairs
local select = select
_G.createTimer = function()
local _timers, _locked = {}
local function _elapsed(dt)
_locked = {}
local trigger, params
for timer in pairs(_timers) do
timer.accum = timer.accum + dt
timer.elapsed = timer.accum
trigger = false
if timer.interval == 0 then
timer.accum = 0
trigger = true
else
while timer.accum >= timer.interval do
timer.accum = timer.accum - timer.interval
trigger = true
end
end
if trigger then
timer.ncalled = timer.ncalled + 1
if timer.ntimes > 0 and timer.ncalled >= timer.ntimes then
_timers[timer] = nil
end
params = timer.params
if params then
timer:call(unpack(params))
else
timer:call()
end
end
end
for timer in pairs(_locked) do
_timers[timer] = true
end
_locked = nil
end
function _add(timer)
if _locked then
if not _timers[timer] then
_locked[timer] = true
end
else
_timers[timer] = true
end
return timer
end
local function _reset(timer)
timer.accum = 0
timer.ncalled = 0
_add(timer)
end
local function _stop(timer)
_timers[timer] = nil
end
return setmetatable({elapsed = _elapsed}, {
__call = function(_, interval, ntimes, fn, ...)
local timer = {
accum = 0,
interval = (interval > 0) and interval or 0,
ntimes = (ntimes > 0) and ntimes or 0,
call = fn,
elapsed = 0,
ncalled = 0,
reset = _reset,
stop = _stop
}
if select('#', ...) > 0 then
timer.params = {...}
end
return _add(timer)
end,
})
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment