An event-based loop class which can take arbitrary numbers of intervals/callback pairs. Based on Node.js EventEmitter. Created with game loops in mind.
It's very simple:
var EventedLoop = require('eventedloop'); // Only relevant if you're using Node or Browserify
var loop = new EventedLoop();
loop.every('20ms', function (e) {
console.log('I did something at', e); // prints 'I did something at 20ms'
});
loop.start();
But wait, there's more! You can specify a bunch of different things to happen at different times, and they don't have to be milliseconds! (you can use ms
, s
, m
, or h
)
var EventedLoop = require('eventedloop'); // Only relevant if you're using Node or Browserify
var loop = new EventedLoop();
loop.every('2s', function (e) {
console.log('Every 2 seconds I will run');
});
loop.every('1m', function (e) {
console.log('Every 1 minute I will run');
});
loop.every('50s', function (e) {
console.log('Every 1 minute I will run');
});
loop.start();
// You can even add new intervals after it starts running
loop.every('2m', function (e) {
console.log('Every 2 minutes I will run');
});
You can do as many as you like, but I highly recommend you take it easy an don't overdo it. In newer versions of Chrome, 50 intervals seems to have no detrimental effects, but of course it depends on what is happening in the callback. An example of a situation with 50 intervals is available in this demo.
You can also remove events, and even do it after the loop has started!
var EventedLoop = require('eventedloop'); // Only relevant if you're using Node or Browserify
var loop = new EventedLoop();
loop.every('2s', function (e) {
console.log('Every 2 seconds I will run');
});
var oneMinuteEvent = loop.every('1m', function (e) {
console.log('Every 1 minute I will run');
});
loop.start();
// You can even add new intervals after it starts running
oneMinuteEvent.remove(); // The console.log happening once a minute no longer happens
loop.every(interval, callback)
- Tell the loop to execute thecallback
regularly at whatever time was specified ininterval
, which can either be milliseconds (e.g.2ms
), seconds (e.g.5s
), minutes (e.g.10m
), or hours (1h
). Returns an object with the follow method:event.remove()
- remove this event from the loop, so it will no longer take place
loop.start()
- Starts the loop.loop.stop()
- Stops the loop. Will not clear out all the intervals, this can be done with the inherited method fromEventEmitter
,loop.removeAllListeners
.loop.tick()
- This will cause a single iteration at the greatest common factor of time for all the given intervals, i.e., if you have two intervals at50ms
and75ms
, a single tick will be25ms
. This is useful for debugging, and for mimicing slowed-down time.loop.on()
- Does the same thing asevery
. Inherited fromEventEmitter
.
EventedLoop in fact inherits all the methods from EventEmitter
.
- You can only set intervals at numbers whose millisecond equivalents are factors of 10ms. E.g. '1s', '20ms', '20', or '5h'.
- When the browser tab is blurred, the loop will stop. This is because of browser behaviour only allowing
setInterval
callbacks every 1000ms when not focused. I will probably make this an option with default behaviour.
If you are doing this on the front-end I would highly recommend Browserify for using this library, and it also works with Node.JS.
npm install eventedloop
Or if you're feeling dangerous:
npm install --save git://github.com/basicallydan/eventedloop#master
Download eventedloop.min.js
or eventedloop.js
and stick it your DOM somewhere, and you should find that the EventedLoop
class is now exposed globally for your pleasure.
This was created as part of a game that Jon and I are developing, and it's quite good for games where a lot of things will be happening at different rates and you need a simple API for managing it.
If you'd like to create a game loop, here's a really simple example of how you can do so, taken from the main game file in my SkiFree port:
var gameLoop = new EventedLoop();
gameLoop.on('20ms', game.draw);
gameLoop.on('20ms', game.update);
gameLoop.start();
You can also recreate the XKCD Frequency comic, like so: Show me the demo.
It's also a nice, cleaner version of setInterval
which can be turned on and off at will.
If you've cloned this repo you can first npm install
it, and then run npm test
to run some beautiful vows tests.
Build using Browserify:
browserify lib/main.js -o eventedloop.js
And minify with UglifyJS2
browserify lib/main.js | uglifyjs > eventedloop.min.js
Please, please, please feel free to open an issue or fork this sucker and give it a pull request. It's a pretty cool little library but it could definitely do with some love, it was knocked together in a couple of hours during a heated evening in the mountains.