mirror of
https://github.com/kikito/cron.lua.git
synced 2024-12-19 18:34:20 +00:00
cron.before and cron.after now return a clock
This commit is contained in:
parent
d7b075a076
commit
c4f205460f
62
cron.lua
62
cron.lua
@ -28,8 +28,6 @@ local cron = {
|
||||
|
||||
-- Private functions
|
||||
|
||||
local entries -- initialized in cron.reset
|
||||
|
||||
local function isCallable(callback)
|
||||
local tc = type(callback)
|
||||
if tc == 'function' then return true end
|
||||
@ -40,67 +38,61 @@ local function isCallable(callback)
|
||||
return false
|
||||
end
|
||||
|
||||
local function checkTimeAndCallback(time, callback)
|
||||
assert(type(time) == "number" and time > 0, "time must be a positive number")
|
||||
assert(isCallable(callback), "callback must be a function")
|
||||
local function checkPositiveInteger(name, value)
|
||||
if type(value) ~= "number" or value < 0 then
|
||||
error(name .. " must be a positive number")
|
||||
end
|
||||
end
|
||||
|
||||
local function newEntry(time, callback, update, ...)
|
||||
local entry = {
|
||||
local Clock = {}
|
||||
local Clock_mt = {__index = Clock}
|
||||
|
||||
local function newClock(time, callback, update, ...)
|
||||
checkPositiveInteger('time', time)
|
||||
assert(isCallable(callback), "callback must be a function")
|
||||
|
||||
return setmetatable({
|
||||
time = time,
|
||||
callback = callback,
|
||||
args = {...},
|
||||
running = 0,
|
||||
update = update
|
||||
}
|
||||
entries[entry] = entry
|
||||
return entry
|
||||
}, Clock_mt)
|
||||
end
|
||||
|
||||
local function updateTimedEntry(self, dt) -- returns true if expired
|
||||
local function updateAfterClock(self, dt) -- returns true if expired
|
||||
checkPositiveInteger('dt', dt)
|
||||
|
||||
if self.running >= self.time then return true end
|
||||
|
||||
self.running = self.running + dt
|
||||
|
||||
if self.running >= self.time then
|
||||
self.callback(unpack(self.args))
|
||||
cron.cancel(self)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function updatePeriodicEntry(self, dt)
|
||||
local function updateEveryClock(self, dt)
|
||||
checkPositiveInteger('dt', dt)
|
||||
|
||||
self.running = self.running + dt
|
||||
|
||||
while self.running >= self.time do
|
||||
self.callback(unpack(self.args))
|
||||
self.running = self.running - self.time
|
||||
end
|
||||
end
|
||||
|
||||
-- Public functions
|
||||
|
||||
function cron.cancel(id)
|
||||
entries[id] = nil
|
||||
return false
|
||||
end
|
||||
|
||||
function cron.after(time, callback, ...)
|
||||
checkTimeAndCallback(time, callback)
|
||||
return newEntry(time, callback, updateTimedEntry, ...)
|
||||
return newClock(time, callback, updateAfterClock, ...)
|
||||
end
|
||||
|
||||
function cron.every(time, callback, ...)
|
||||
checkTimeAndCallback(time, callback)
|
||||
return newEntry(time, callback, updatePeriodicEntry, ...)
|
||||
return newClock(time, callback, updateEveryClock, ...)
|
||||
end
|
||||
|
||||
function cron.update(dt)
|
||||
assert(type(dt) == "number" and dt >= 0, "dt must be a non-negative number")
|
||||
|
||||
for _, entry in pairs(entries) do entry:update(dt) end
|
||||
end
|
||||
|
||||
function cron.reset()
|
||||
entries = {}
|
||||
end
|
||||
|
||||
cron.reset()
|
||||
|
||||
return cron
|
||||
|
||||
|
@ -2,7 +2,7 @@ local cron = require 'cron'
|
||||
|
||||
describe( 'cron', function()
|
||||
|
||||
local counter = 0
|
||||
local counter
|
||||
local function count(amount)
|
||||
amount = amount or 1
|
||||
counter = counter + amount
|
||||
@ -11,41 +11,25 @@ describe( 'cron', function()
|
||||
|
||||
before_each(function()
|
||||
counter = 0
|
||||
cron.reset()
|
||||
end)
|
||||
|
||||
describe('.update', function()
|
||||
|
||||
describe('clock', function()
|
||||
|
||||
describe(':update', function()
|
||||
it('throws an error if dt is a negative number', function()
|
||||
assert.error(function() cron.update() end)
|
||||
assert.error(function() cron.update(-1) end)
|
||||
assert.not_error(function() cron.update(1) end)
|
||||
local clock = cron.every(1, count)
|
||||
assert.error(function() clock:update() end)
|
||||
assert.error(function() clock:update(-1) end)
|
||||
assert.not_error(function() clock:update(1) end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('.reset', function()
|
||||
it('Cancels all timed actions', function()
|
||||
cron.after(1, count)
|
||||
cron.after(2, count)
|
||||
cron.update(1)
|
||||
assert.equal(counter, 1)
|
||||
cron.reset()
|
||||
cron.update(1)
|
||||
assert.equal(counter, 1)
|
||||
end)
|
||||
|
||||
it('Cancels all periodical actions', function()
|
||||
cron.every(1, count)
|
||||
cron.update(1)
|
||||
assert.equal(counter, 1)
|
||||
cron.reset()
|
||||
cron.update(1)
|
||||
assert.equal(counter, 1)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
describe('.after', function()
|
||||
it('Throws error if time is not a positive number, or callback is not callable', function()
|
||||
it('checks parameters', function()
|
||||
assert.error(function() cron.after('error', count) end)
|
||||
assert.error(function() cron.after(2, 'error') end)
|
||||
assert.error(function() cron.after(-2, count) end)
|
||||
@ -54,28 +38,45 @@ describe( 'cron', function()
|
||||
assert.not_error(function() cron.after(2, countable) end)
|
||||
end)
|
||||
|
||||
it('Executes timed actions only once, at the right time', function()
|
||||
cron.after(2, count)
|
||||
cron.after(4, count)
|
||||
cron.update(1)
|
||||
it('produces a clock that executes actions only once, at the right time', function()
|
||||
local c1 = cron.after(2, count)
|
||||
local c2 = cron.after(4, count)
|
||||
|
||||
-- 1
|
||||
c1:update(1)
|
||||
assert.equal(counter, 0)
|
||||
cron.update(1)
|
||||
c2:update(1)
|
||||
assert.equal(counter, 0)
|
||||
|
||||
-- 2
|
||||
c1:update(1)
|
||||
assert.equal(counter, 1)
|
||||
cron.update(1)
|
||||
c2:update(1)
|
||||
assert.equal(counter, 1)
|
||||
cron.update(1)
|
||||
|
||||
-- 3
|
||||
c1:update(1)
|
||||
assert.equal(counter, 1)
|
||||
c2:update(1)
|
||||
assert.equal(counter, 1)
|
||||
|
||||
-- 4
|
||||
c1:update(1)
|
||||
assert.equal(counter, 1)
|
||||
c2:update(1)
|
||||
assert.equal(counter, 2)
|
||||
|
||||
end)
|
||||
|
||||
it('Passes on parameters to the function, if specified', function()
|
||||
cron.after(1, count, 2)
|
||||
cron.update(1)
|
||||
it('Passes on parameters to the callback', function()
|
||||
local c1 = cron.after(1, count, 2)
|
||||
c1:update(1)
|
||||
assert.equal(counter, 2)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('.every', function()
|
||||
it('Throws errors if time is not a positive number, or callback is not function', function()
|
||||
it('checks parameters', function()
|
||||
assert.error(function() cron.every('error', count) end)
|
||||
assert.error(function() cron.every(2, 'error') end)
|
||||
assert.error(function() cron.every(-2, count) end)
|
||||
@ -84,49 +85,33 @@ describe( 'cron', function()
|
||||
assert.not_error(function() cron.every(2, countable) end)
|
||||
end)
|
||||
|
||||
it('Executes periodical actions periodically', function()
|
||||
cron.every(3, count)
|
||||
cron.update(1)
|
||||
it('Invokes callback periodically', function()
|
||||
local c = cron.every(3, count)
|
||||
|
||||
c:update(1)
|
||||
assert.equal(counter, 0)
|
||||
cron.update(2)
|
||||
|
||||
c:update(2)
|
||||
assert.equal(counter, 1)
|
||||
cron.update(2)
|
||||
|
||||
c:update(2)
|
||||
assert.equal(counter, 1)
|
||||
cron.update(1)
|
||||
|
||||
c:update(1)
|
||||
assert.equal(counter, 2)
|
||||
end)
|
||||
|
||||
it('Executes the same action multiple times on a single update if appropiate', function()
|
||||
cron.every(1, count)
|
||||
cron.update(2)
|
||||
local c = cron.every(1, count)
|
||||
c:update(2)
|
||||
assert.equal(counter, 2)
|
||||
end)
|
||||
|
||||
it('Respects parameters', function()
|
||||
cron.every(1, count, 2)
|
||||
cron.update(2)
|
||||
local c = cron.every(1, count, 2)
|
||||
c:update(2)
|
||||
assert.equal(counter, 4)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('.cancel', function()
|
||||
it('Cancels timed entries', function()
|
||||
local id = cron.after(1, count)
|
||||
cron.update(1)
|
||||
assert.equal(counter, 1)
|
||||
cron.cancel(id)
|
||||
cron.update(1)
|
||||
assert.equal(counter, 1)
|
||||
end)
|
||||
|
||||
it('Cancels periodical entries', function()
|
||||
local id = cron.every(1, count)
|
||||
cron.update(1)
|
||||
assert.equal(counter, 1)
|
||||
cron.cancel(id)
|
||||
cron.update(1)
|
||||
assert.equal(counter, 1)
|
||||
end)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user