-
Notifications
You must be signed in to change notification settings - Fork 64
/
Timer.js
137 lines (126 loc) · 3.48 KB
/
Timer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* Timer.js - object oriented friendly timeout object
* From code originally found on:
*
* http://www.codingforums.com/archive/index.php/index.php?t-10531.html
*
* The problems with the setTimeout and setInterval functions
* provided in Javascript are twofold. First, you can't call a local
* object method without losing your scope, and second, you can't pass
* objects to the function, since the function call is implemented as a string.
*
* The Timer class solves these difficulties by employing a static array
* to store the parent object and function arguments until the function is
* called.
*
* This class is provided as-is and pro bono, so go ahead and muck with
* it if you see things that could be done better.
*
* Thanks to WA for giving me the idea for this (albeit indirectly)!
*
* Updated 4/18/2003: Footprint decreased, minor code improvements.
* Updated 5/3/2003: Minor comment clarification; no code changes.
* Updated 5/10/2003: Minor code improvements.
*/
// The constructor should be called with
// the parent object (optional, defaults to window).
function
Timer ()
{
this.obj = (arguments.length) ? arguments[0] : window;
return this;
}
// The set functions should be called with:
// - The name of the object method (as a string) (required)
// - The millisecond delay (required)
// - Any number of extra arguments, which will all be
// passed to the method when it is evaluated.
Timer.prototype.setInterval = function (func, msec)
{
var i = Timer.getNew ();
var t = Timer.buildCall (this.obj, i, arguments);
Timer.set[i].timer = window.setInterval (t, msec);
return i;
}
Timer.prototype.setTimeout = function (func, msec)
{
var i = Timer.getNew ();
Timer.buildCall (this.obj, i, arguments);
Timer.set[i].timer = window.setTimeout ("Timer.callOnce(" + i + ");", msec);
return i;
}
// The clear functions should be called with
// the return value from the equivalent set function.
Timer.prototype.clearInterval = function (i)
{
if (!Timer.set[i])
return;
window.clearInterval (Timer.set[i].timer);
Timer.set[i] = null;
}
Timer.prototype.clearTimeout = function (i)
{
if (!Timer.set[i])
return;
window.clearTimeout (Timer.set[i].timer);
Timer.set[i] = null;
}
// Private data
Timer.set = new Array ();
Timer.buildCall = function (obj, i, args)
{
var t = "";
Timer.set[i] = new Array ();
if (obj != window)
{
Timer.set[i].obj = obj;
t = "Timer.set[" + i + "].obj.";
}
t += args[0] + "(";
if (args.length > 2)
{
Timer.set[i][0] = args[2];
t += "Timer.set[" + i + "][0]";
for (var j = 1; (j + 2) < args.length; j++)
{
Timer.set[i][j] = args[j + 2];
t += ", Timer.set[" + i + "][" + j + "]";
}
}
t += ");";
Timer.set[i].call = t;
return t;
}
Timer.callOnce = function (i)
{
if (!Timer.set[i])
return;
eval (Timer.set[i].call);
Timer.set[i] = null;
}
Timer.getNew = function ()
{
var i = 0;
while (Timer.set[i])
i++;
return i;
}
/*
Here 's an example of the code in action:
function Ticker ()
{
this.count = 0;
this.timer = new Timer (this);
}
Ticker.prototype.tick = function (d)
{
this.count += d;
window.status = "" + this.count;
this.timer.setTimeout ("tick", 1000, d);
}
window.onload = function ()
{
var ticker = new Ticker ();
ticker.tick (1);
}
*/