mirror of
https://github.com/kikito/cron.lua.git
synced 2024-12-19 18:34:20 +00:00
did not make the initial commit correctly. Oh, well. On this commit update, reset and after are implemented and passing tests. Only every is missing
This commit is contained in:
parent
1a045ca348
commit
d74a00145e
26
BSD-LICENSE.txt
Normal file
26
BSD-LICENSE.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Copyright (c) 2011, Enrique García Cota
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of MiddleClass nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
40
README.textile
Normal file
40
README.textile
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
h1. cron.lua
|
||||||
|
|
||||||
|
@cron.lua@ are a set of functions for executing actions at a certain time interval.
|
||||||
|
|
||||||
|
h1. Examples of use
|
||||||
|
|
||||||
|
* @cron.after(time, f)@ will execute f after the given amount of time units.
|
||||||
|
* @cron.every(time, f)@ will repeat the same action periodically.
|
||||||
|
* @cron.cancel(id)@ will stop a timed event from happening. @id@ is returned by @cron.after@ and @cron.every@ respectively. It will stop a timed event from happening, or stop a periodic action.
|
||||||
|
* @cron.reset()@ removes all timed and periodic actions, and resets the time passed back to 0.
|
||||||
|
* @cron.update(dt)@ is needed to be executed on the main program loop. @dt@ is the amount of time that has passed since the last iteration. When @cron.update@ is executed, cron will check the list of pending actions and execute them if needed.
|
||||||
|
|
||||||
|
|
||||||
|
h1. Gotchas / Warnings
|
||||||
|
|
||||||
|
* @cron.lua@ does *not* implement any hardware or software clock; you will have to provide it with the access to the hardware timers, in the form of periodic calls to @cron.update@
|
||||||
|
* @cron@ does not have any defined time units (seconds, milliseconds, etc). You define the units it uses by passing it a @dt@ on @cron.update@. If @dt@ is in seconds, then @cron@ will work in seconds. If @dt@ is in milliseconds, then @cron@ will work in milliseconds.
|
||||||
|
|
||||||
|
h1. Installation
|
||||||
|
|
||||||
|
Just copy the cron.lua file somewhere in your projects (maybe inside a /lib/ folder) and require it accordingly.
|
||||||
|
|
||||||
|
Remember to store the value returned by require somewhere! (I suggest a local variable named @cron@)
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
local cron = require 'cron'
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Also, make sure to read the license file; the text of that license file must appear somewhere in your projects' files.
|
||||||
|
|
||||||
|
h1. Specs
|
||||||
|
|
||||||
|
This project uses "telescope":https://github.com/norman/telescope for its specs. If you want to run the specs, you will have to install telescope first. Then just enter the spec folder and execute run.lua:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cd path/to/cron.lua/specs
|
||||||
|
lua run.lua
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
60
cron.lua
Normal file
60
cron.lua
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
-----------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- cron.lua - v1.0 (2011-04)
|
||||||
|
-- Enrique García Cota - enrique.garcia.cota [AT] gmail [DOT] com
|
||||||
|
-- time-related functions for Lua.
|
||||||
|
-- inspired by Javascript's setTimeout and setInterval
|
||||||
|
-----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
local entries = {}
|
||||||
|
|
||||||
|
local TimedEntry = {}
|
||||||
|
|
||||||
|
function TimedEntry:new(time, callback, ...)
|
||||||
|
return setmetatable( {
|
||||||
|
time = time,
|
||||||
|
callback = callback,
|
||||||
|
args = {...},
|
||||||
|
running = 0
|
||||||
|
},
|
||||||
|
{ __index = TimedEntry }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TimedEntry:update(dt)
|
||||||
|
self.running = self.running + dt
|
||||||
|
if self.running >= self.time then
|
||||||
|
self.callback(unpack(self.args))
|
||||||
|
self.expired = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local cron = {}
|
||||||
|
|
||||||
|
function cron.reset()
|
||||||
|
entries = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function cron.after(time, callback, ...)
|
||||||
|
assert(type(time) == "number" and time > 0, "time must be a positive number")
|
||||||
|
assert(type(callback) == "function", "callback must be a function")
|
||||||
|
|
||||||
|
local entry = TimedEntry:new(time, callback, ...)
|
||||||
|
entries[entry] = entry
|
||||||
|
end
|
||||||
|
|
||||||
|
function cron.update(dt)
|
||||||
|
assert(type(dt) == "number" and dt > 0, "dt must be a positive number")
|
||||||
|
|
||||||
|
local expired = {}
|
||||||
|
|
||||||
|
for _, entry in pairs(entries) do
|
||||||
|
entry:update(dt, runningTime)
|
||||||
|
if entry.expired then expired[entry] = entry end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, entry in pairs(expired) do entries[entry] = nil end
|
||||||
|
end
|
||||||
|
|
||||||
|
return cron
|
||||||
|
|
@ -2,4 +2,65 @@ local cron = require 'cron'
|
|||||||
|
|
||||||
context( 'cron', function()
|
context( 'cron', function()
|
||||||
|
|
||||||
|
local counter = 0
|
||||||
|
local function count(amount)
|
||||||
|
amount = amount or 1
|
||||||
|
counter = counter + amount
|
||||||
|
end
|
||||||
|
|
||||||
|
before(function()
|
||||||
|
counter = 0
|
||||||
|
cron.reset()
|
||||||
|
end)
|
||||||
|
|
||||||
|
context('update', function()
|
||||||
|
test( 'Should throw an error if dt is not a positive number', function()
|
||||||
|
assert_error(function() cron.update() end)
|
||||||
|
assert_error(function() cron.update(-1) end)
|
||||||
|
assert_not_error(function() cron.update(1) end)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
context('reset', function()
|
||||||
|
test('Should cancel all 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)
|
||||||
|
|
||||||
|
context( 'after', function()
|
||||||
|
test( 'Should throw error if time is not a positive number, or f is not function', 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)
|
||||||
|
assert_not_error(function() cron.after(2, count) end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test( 'Should execute timed actions are executed only once, at the right time', function()
|
||||||
|
cron.after(2, count)
|
||||||
|
cron.after(4, count)
|
||||||
|
cron.update(1)
|
||||||
|
assert_equal(counter, 0)
|
||||||
|
cron.update(1)
|
||||||
|
assert_equal(counter, 1)
|
||||||
|
cron.update(1)
|
||||||
|
assert_equal(counter, 1)
|
||||||
|
cron.update(1)
|
||||||
|
assert_equal(counter, 2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test( 'Should pass on parameters to the function, if specified', function()
|
||||||
|
cron.after(1, count, 2)
|
||||||
|
cron.update(1)
|
||||||
|
assert_equal(counter, 2)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user