@Amec: That implementation would do the job just fine, but there's still room for improvement.
- You're trying to add elements to the timers array, but since you're using a string as key you're actually just setting an object property. Either you use numerical indexes and make proper use of the array, or you just make timers an object. Because you're not actually using any array-specific features, you can simply get away with an object here.
- Instead of parsing data out of the keys in OnEvent_Timer, you can just store objects as elements in timers and read the properties instead.
- You should check whether the timerId actually exists in timers in OnEvent_Timer. Sure, chances are slim that you'll ever get an invalid timer, but you never know.
- Try to reuse some of your code! setTimeout and setInterval are almost identical.
I had a go with this myself, threw in some tasty OOP and here's what I came up with:
js code:
/* Somewhat private worker classes */
// Timer sets up a timer and exposes methods
var Timer = function(fCallback, nInterval) {
this.Callback = function() {
fCallback.call(this);
this.Cancel();
};
this.Interval = nInterval;
// Add to storage
this.Index = Timer.Storage.length;
Timer.Storage.push(this);
// Identifier for timer events
this.Id = 'Timer#'+this.Index;
MsgPlus.AddTimer(this.Id, this.Interval);
};
// Storage array as static property
Timer.Storage = [];
// Instance methods
Timer.prototype = {
Refresh : function() {
Timers[this.Index] = this;
MsgPlus.AddTimer(this.Id, this.Interval);
},
Cancel : function() {
Timers[this.Index] = null;
MsgPlus.CancelTimer(this.Id);
}
};
// Interval is identical to Timer, except for its Callback property
var Interval = function(fCallback, nInterval) {
// Call superclass constructor
Timer.apply(this, arguments);
// Callback refreshes timer instead of canceling it
this.Callback = function() {
fCallback.call(this);
this.Refresh();
};
};
Interval.prototype = Timer.prototype; // Prototypical inheritance! :O
// Timer event handling
function OnEvent_Timer(timerId) {
if((m = /^Timer#(\d+)$/.exec(timerId)) !== null) {
var nIndex = 1*m[1], timer = Timer.Storage[nIndex];
if(timer && timer.Callback) {
timer.Callback();
return;
}
}
// Other timers can be handled here...
}
function setTimeout(func, delay) {
var timer = new Timer(func, delay);
return timer.Index;
}
function setInterval(func, delay) {
var interval = new Interval(func, delay);
return interval.Index;
}
function clearTimeout(timerIndex) {
var timer = Timer.Storage[timerIndex];
if(timer && timer.Cancel) {
timer.Cancel();
}
}
var clearInterval = clearTimeout;
In fact, you could use this code without the functions at the bottom and simply go with the classes.
I don't want to scare you off, I simply thought I'd show you another way to do it. Feel free to play around with it.