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
|
-- Private functions
|
||||||
|
|
||||||
local entries -- initialized in cron.reset
|
|
||||||
|
|
||||||
local function isCallable(callback)
|
local function isCallable(callback)
|
||||||
local tc = type(callback)
|
local tc = type(callback)
|
||||||
if tc == 'function' then return true end
|
if tc == 'function' then return true end
|
||||||
@ -40,67 +38,61 @@ local function isCallable(callback)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function checkTimeAndCallback(time, callback)
|
local function checkPositiveInteger(name, value)
|
||||||
assert(type(time) == "number" and time > 0, "time must be a positive number")
|
if type(value) ~= "number" or value < 0 then
|
||||||
assert(isCallable(callback), "callback must be a function")
|
error(name .. " must be a positive number")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function newEntry(time, callback, update, ...)
|
local Clock = {}
|
||||||
local entry = {
|
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,
|
time = time,
|
||||||
callback = callback,
|
callback = callback,
|
||||||
args = {...},
|
args = {...},
|
||||||
running = 0,
|
running = 0,
|
||||||
update = update
|
update = update
|
||||||
}
|
}, Clock_mt)
|
||||||
entries[entry] = entry
|
|
||||||
return entry
|
|
||||||
end
|
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
|
self.running = self.running + dt
|
||||||
|
|
||||||
if self.running >= self.time then
|
if self.running >= self.time then
|
||||||
self.callback(unpack(self.args))
|
self.callback(unpack(self.args))
|
||||||
cron.cancel(self)
|
return true
|
||||||
end
|
end
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function updatePeriodicEntry(self, dt)
|
local function updateEveryClock(self, dt)
|
||||||
|
checkPositiveInteger('dt', dt)
|
||||||
|
|
||||||
self.running = self.running + dt
|
self.running = self.running + dt
|
||||||
|
|
||||||
while self.running >= self.time do
|
while self.running >= self.time do
|
||||||
self.callback(unpack(self.args))
|
self.callback(unpack(self.args))
|
||||||
self.running = self.running - self.time
|
self.running = self.running - self.time
|
||||||
end
|
end
|
||||||
end
|
return false
|
||||||
|
|
||||||
-- Public functions
|
|
||||||
|
|
||||||
function cron.cancel(id)
|
|
||||||
entries[id] = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function cron.after(time, callback, ...)
|
function cron.after(time, callback, ...)
|
||||||
checkTimeAndCallback(time, callback)
|
return newClock(time, callback, updateAfterClock, ...)
|
||||||
return newEntry(time, callback, updateTimedEntry, ...)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function cron.every(time, callback, ...)
|
function cron.every(time, callback, ...)
|
||||||
checkTimeAndCallback(time, callback)
|
return newClock(time, callback, updateEveryClock, ...)
|
||||||
return newEntry(time, callback, updatePeriodicEntry, ...)
|
|
||||||
end
|
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
|
return cron
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ local cron = require 'cron'
|
|||||||
|
|
||||||
describe( 'cron', function()
|
describe( 'cron', function()
|
||||||
|
|
||||||
local counter = 0
|
local counter
|
||||||
local function count(amount)
|
local function count(amount)
|
||||||
amount = amount or 1
|
amount = amount or 1
|
||||||
counter = counter + amount
|
counter = counter + amount
|
||||||
@ -11,41 +11,25 @@ describe( 'cron', function()
|
|||||||
|
|
||||||
before_each(function()
|
before_each(function()
|
||||||
counter = 0
|
counter = 0
|
||||||
cron.reset()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('.update', function()
|
|
||||||
|
describe('clock', function()
|
||||||
|
|
||||||
|
describe(':update', function()
|
||||||
it('throws an error if dt is a negative number', function()
|
it('throws an error if dt is a negative number', function()
|
||||||
assert.error(function() cron.update() end)
|
local clock = cron.every(1, count)
|
||||||
assert.error(function() cron.update(-1) end)
|
assert.error(function() clock:update() end)
|
||||||
assert.not_error(function() cron.update(1) end)
|
assert.error(function() clock:update(-1) end)
|
||||||
|
assert.not_error(function() clock:update(1) end)
|
||||||
end)
|
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)
|
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()
|
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('error', count) end)
|
||||||
assert.error(function() cron.after(2, 'error') end)
|
assert.error(function() cron.after(2, 'error') end)
|
||||||
assert.error(function() cron.after(-2, count) 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)
|
assert.not_error(function() cron.after(2, countable) end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('Executes timed actions only once, at the right time', function()
|
it('produces a clock that executes actions only once, at the right time', function()
|
||||||
cron.after(2, count)
|
local c1 = cron.after(2, count)
|
||||||
cron.after(4, count)
|
local c2 = cron.after(4, count)
|
||||||
cron.update(1)
|
|
||||||
|
-- 1
|
||||||
|
c1:update(1)
|
||||||
assert.equal(counter, 0)
|
assert.equal(counter, 0)
|
||||||
cron.update(1)
|
c2:update(1)
|
||||||
|
assert.equal(counter, 0)
|
||||||
|
|
||||||
|
-- 2
|
||||||
|
c1:update(1)
|
||||||
assert.equal(counter, 1)
|
assert.equal(counter, 1)
|
||||||
cron.update(1)
|
c2:update(1)
|
||||||
assert.equal(counter, 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)
|
assert.equal(counter, 2)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('Passes on parameters to the function, if specified', function()
|
it('Passes on parameters to the callback', function()
|
||||||
cron.after(1, count, 2)
|
local c1 = cron.after(1, count, 2)
|
||||||
cron.update(1)
|
c1:update(1)
|
||||||
assert.equal(counter, 2)
|
assert.equal(counter, 2)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('.every', function()
|
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('error', count) end)
|
||||||
assert.error(function() cron.every(2, 'error') end)
|
assert.error(function() cron.every(2, 'error') end)
|
||||||
assert.error(function() cron.every(-2, count) 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)
|
assert.not_error(function() cron.every(2, countable) end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('Executes periodical actions periodically', function()
|
it('Invokes callback periodically', function()
|
||||||
cron.every(3, count)
|
local c = cron.every(3, count)
|
||||||
cron.update(1)
|
|
||||||
|
c:update(1)
|
||||||
assert.equal(counter, 0)
|
assert.equal(counter, 0)
|
||||||
cron.update(2)
|
|
||||||
|
c:update(2)
|
||||||
assert.equal(counter, 1)
|
assert.equal(counter, 1)
|
||||||
cron.update(2)
|
|
||||||
|
c:update(2)
|
||||||
assert.equal(counter, 1)
|
assert.equal(counter, 1)
|
||||||
cron.update(1)
|
|
||||||
|
c:update(1)
|
||||||
assert.equal(counter, 2)
|
assert.equal(counter, 2)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('Executes the same action multiple times on a single update if appropiate', function()
|
it('Executes the same action multiple times on a single update if appropiate', function()
|
||||||
cron.every(1, count)
|
local c = cron.every(1, count)
|
||||||
cron.update(2)
|
c:update(2)
|
||||||
assert.equal(counter, 2)
|
assert.equal(counter, 2)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('Respects parameters', function()
|
it('Respects parameters', function()
|
||||||
cron.every(1, count, 2)
|
local c = cron.every(1, count, 2)
|
||||||
cron.update(2)
|
c:update(2)
|
||||||
assert.equal(counter, 4)
|
assert.equal(counter, 4)
|
||||||
end)
|
end)
|
||||||
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)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user