vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 local weakK_mt = {__mode="k"};
2 local weakV_mt = {__mode="v"};
3  
4 local TIMEX_UPDATE = 1;
5 local TIMEX_EVENT = 2;
6 local FUNCTION = 4;
7  
8 local TT_UPDATE = "doTimexEvent";
9  
10 local TT_UPDATE_EVENT = "TIMEX_UPDATE";
11  
12 local function ARG_ID(t) return t.schedule.id; end;
13 local function ARG_COUNT(t) return t.schedule.c; end;
14 local function ARG_ELAPSED(t) return t.schedule.elapsed; end;
15  
16 local DEBUG_DB = "Debug";
17 local timexDebug = nil;
18  
19 local getTime = GetTime;
20  
21 --<< ================================================= >>--
22 -- Section I: Initialize the AddOn Object. --
23 --<< ================================================= >>--
24  
25 Timex = AceAddon:new({
26 name = TimexLocals.Title,
27 version = TimexLocals.Version,
28 description = TimexLocals.Desc,
29 author = "Rowne/facboy",
30 aceCompatible = "100",
31 category = ACE_CATEGORY_OTHERS,
32 cmd = AceChatCmd:new(TimexLocals.ChatCmd, (TimexLocals.ChatOpt or {})),
33 db = AceDatabase:new("TimexDB"),
34  
35 TT_UPDATE = TT_UPDATE,
36 ARG_ID = ARG_ID,
37 ARG_COUNT = ARG_COUNT,
38 ARG_ELAPSED = ARG_ELAPSED,
39  
40 weakV_mt = weakV_mt,
41 })
42  
43 -- make all this stuff local...there should only be one Timex instance anyway, this will effectively make it a singleton
44 local scheduleDB = {};
45 local scheduleMap = setmetatable({}, weakV_mt);
46  
47 local timerDB = {};
48  
49 local initDB = {};
50  
51 local onUpdateDB = {};
52 local onUpdateMap = setmetatable({}, weakV_mt);
53  
54 --<< ================================================= >>--
55 -- Section II: Private utility functions. --
56 --<< ================================================= >>--
57  
58 --------------------
59 -- table management
60 --------------------
61  
62 local getn = table.getn;
63 local setn = table.setn;
64 local tinsert = table.insert;
65 local tremove = table.remove;
66  
67 local unusedTables = setmetatable({}, weakK_mt);
68  
69 local function newTable()
70 local new = next(unusedTables);
71 if new then
72 unusedTables[new] = nil;
73 else
74 new = {};
75 end
76 return new;
77 end
78  
79 local function deleteTable(deleteTable)
80 unusedTables[deleteTable] = true;
81 end
82  
83 --------------------
84 -- argument stuff
85 --------------------
86 local args_switch = {};
87 args_switch[ARG_ID] = ARG_ID;
88 args_switch[ARG_COUNT] = ARG_COUNT;
89 args_switch[ARG_ELAPSED] = ARG_ELAPSED;
90  
91 local function buildArgs(args, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
92 local sub = args.sub;
93 local f = args_switch[a20]; args[20], sub[20] = not f and a20 or nil, f;
94 f = args_switch[a19]; args[19], sub[19] = not f and a19 or nil, f;
95 f = args_switch[a18]; args[18], sub[18] = not f and a18 or nil, f;
96 f = args_switch[a17]; args[17], sub[17] = not f and a17 or nil, f;
97 f = args_switch[a16]; args[16], sub[16] = not f and a16 or nil, f;
98 f = args_switch[a15]; args[15], sub[15] = not f and a15 or nil, f;
99 f = args_switch[a14]; args[14], sub[14] = not f and a14 or nil, f;
100 f = args_switch[a13]; args[13], sub[13] = not f and a13 or nil, f;
101 f = args_switch[a12]; args[12], sub[12] = not f and a12 or nil, f;
102 f = args_switch[a11]; args[11], sub[11] = not f and a11 or nil, f;
103 f = args_switch[a10]; args[10], sub[10] = not f and a10 or nil, f;
104 f = args_switch[a9]; args[9], sub[9] = not f and a9 or nil, f;
105 f = args_switch[a8]; args[8], sub[8] = not f and a8 or nil, f;
106 f = args_switch[a7]; args[7], sub[7] = not f and a7 or nil, f;
107 f = args_switch[a6]; args[6], sub[6] = not f and a6 or nil, f;
108 f = args_switch[a5]; args[5], sub[5] = not f and a5 or nil, f;
109 f = args_switch[a4]; args[4], sub[4] = not f and a4 or nil, f;
110 f = args_switch[a3]; args[3], sub[3] = not f and a3 or nil, f;
111 f = args_switch[a2]; args[2], sub[2] = not f and a2 or nil, f;
112 f = args_switch[a1]; args[1], sub[1] = not f and a1 or nil, f;
113 end
114  
115 local args_mt = {
116 __index = function(t, k)
117 local f = t.sub[k];
118 if f then return f(t); end
119 end,
120 }
121  
122 local function newArgs(schedule)
123 local args = newTable();
124 args.schedule, args.sub = schedule, newTable();
125 setmetatable(args, args_mt);
126 return args;
127 end
128  
129 --------------------
130 -- schedule heap management
131 --------------------
132  
133 --------------------
134 -- sifting functions
135 local function hSiftUp(heap, pos, schedule)
136 schedule = schedule or heap[pos];
137 local scheduleD = schedule.d;
138  
139 local curr, i = pos, floor(pos/2);
140 local parent = heap[i];
141 while i > 0 and scheduleD < parent.d do
142 heap[curr], parent.i = parent, curr;
143 curr, i = i, floor(i/2);
144 parent = heap[i];
145 end
146 heap[curr], schedule.i = schedule, curr;
147 return pos ~= curr;
148 end
149  
150 local function hSiftDown(heap, pos, schedule, size)
151 schedule, size = schedule or heap[pos], size or getn(heap);
152 local scheduleD = schedule.d;
153  
154 local curr = pos;
155 repeat
156 local child, childD, c;
157 -- determine the child to compare with
158 local j = 2 * curr;
159 if j > size then
160 break;
161 end
162 local k = j + 1;
163 if k > size then
164 child = heap[j];
165 childD, c = child.d, j;
166 else
167 local childj, childk = heap[j], heap[k];
168 local jD, kD = childj.d, childk.d;
169 if jD < kD then
170 child, childD, c = childj, jD, j;
171 else
172 child, childD, c = childk, kD, k;
173 end
174 end
175 -- do the comparison
176 if scheduleD <= childD then
177 break;
178 end
179 heap[curr], child.i = child, curr;
180 curr = c;
181 until false;
182 heap[curr], schedule.i = schedule, curr;
183 return pos ~= curr;
184 end
185  
186 --------------------
187 -- heap functions
188 local function hMaintain(heap, pos, schedule, size)
189 schedule, size = schedule or heap[pos], size or getn(heap);
190 if not hSiftUp(heap, pos, schedule) then
191 hSiftDown(heap, pos, schedule, size);
192 end
193 end
194  
195 local function hPush(heap, schedule)
196 tinsert(heap, schedule);
197 hSiftUp(heap, getn(heap), schedule);
198 end
199  
200 local function hPop(heap)
201 local head, tail = heap[1], tremove(heap);
202 local size = getn(heap);
203  
204 if size == 1 then
205 heap[1], tail.i = tail, 1;
206 elseif size > 1 then
207 hSiftDown(heap, 1, tail, size);
208 end
209 return head;
210 end
211  
212 local function hDelete(heap, pos)
213 local size = getn(heap);
214 local tail = tremove(heap);
215 if pos < size then
216 local size = size - 1;
217 if size == 1 then
218 heap[1], tail.i = tail, 1;
219 elseif size > 1 then
220 heap[pos] = tail;
221 hMaintain(heap, pos, tail, size);
222 end
223 end
224 end
225  
226 --------------------
227 -- schedule management
228 --------------------
229  
230 local unusedSchedules = setmetatable({}, weakK_mt);
231  
232 local function newSchedule()
233 local schedule = next(unusedSchedules);
234 if schedule then
235 unusedSchedules[schedule] = nil;
236 else
237 schedule = newTable();
238 schedule.a = newArgs(schedule);
239 end
240 return schedule;
241 end
242  
243 -- schedule should already have been removed from the heap
244 local function deleteSchedule(schedule)
245 schedule.del = nil;
246 scheduleMap[schedule.id] = nil;
247 unusedSchedules[schedule] = true;
248 end
249  
250 local function deleteOnUpdate(onUpdate)
251 onUpdate.del = nil;
252 onUpdateMap[onUpdate.id] = nil;
253 unusedSchedules[onUpdate] = true;
254 end
255  
256 --------------------
257 -- function callers
258 --------------------
259  
260 local function callFunction(schedule)
261 local a = schedule.a;
262 local status, err = pcall(schedule.f, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20]);
263 if not status then
264 Timex.cmd:msg("Scheduled function '%s' failed with error: %s", tostring(schedule.id), tostring(err));
265 end
266 return err;
267 end
268  
269 local function triggerEvent(schedule)
270 local a = schedule.a;
271 local status, err = pcall(schedule.f, self, schedule.e, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20]);
272 if not status then
273 Timex.cmd:msg("Scheduled function '%s' failed with error: %s", tostring(schedule.id), tostring(err));
274 end
275 return err;
276 end
277  
278 local function triggerDeprecatedEvent(schedule)
279 local a = schedule.a;
280 local status, err = pcall(schedule.f, self, schedule.e, a, schedule.c, schedule.id, schedule.elapsed);
281 if not status then
282 Timex.cmd:msg("Scheduled function '%s' failed with error: %s", tostring(schedule.id), tostring(err));
283 end
284 return err;
285 end
286  
287 local function runMultiple(schedule, runCount)
288 local runFunc = schedule.runF;
289 local result = runFunc(schedule);
290 if runCount > 1 then
291 local autoRemove = schedule.aR;
292 schedule.elapsed = 0;
293 for i = 2, runCount do
294 result = runFunc(schedule);
295 if autoRemove and result then break; end
296 end
297 end
298 return result;
299 end
300  
301 --------------------
302 -- other stuff
303 --------------------
304  
305 local function handleFrame()
306 local runCount = getn(scheduleDB) + getn(onUpdateDB);
307 if (runCount == 1) then
308 TimexUpdateFrame:Show();
309 elseif (runCount == 0) then
310 TimexUpdateFrame:Hide();
311 end
312 end
313  
314 local function runStartupFunctions()
315 for k, v in pairs(initDB) do
316 if v.f then
317 v.f(v.a1, v.a2, v.a3, v.a4, v.a5, v.a6, v.a7, v.a8, v.a9, v.a10, v.a11, v.a12, v.a13, v.a14, v.a15, v.a16, v.a17, v.a18, v.a19, v.a20);
318 end
319 -- delete the table
320 v.f, v.a = nil, nil;
321 v.a1, v.a2, v.a3, v.a4, v.a5 = nil, nil, nil, nil, nil;
322 v.a6, v.a7, v.a8, v.a9, v.a10 = nil, nil, nil, nil, nil;
323 v.a11, v.a12, v.a13, v.a14, v.a15 = nil, nil, nil, nil, nil;
324 v.a16, v.a17, v.a18, v.a19, v.a20 = nil, nil, nil, nil, nil;
325 deleteTable(v);
326 initDB[k] = nil;
327 end
328 end
329  
330 local function togOpt(timex, var)
331 return timex.db:toggle(timex.profilePath, var)
332 end
333  
334 local function getOpt(timex, var)
335 return timex.db:get(timex.profilePath, var)
336 end
337  
338 local function getNumber(n)
339 local num = tonumber(n);
340 if not num then
341 error("'" .. n .. "' is not a number.");
342 end
343 return num;
344 end
345  
346 --<< ================================================= >>--
347 -- Section III: The Timex System Functions. --
348 --<< ================================================= >>--
349  
350 function Timex:Enable()
351 TimexBar:Enable();
352 timexDebug = getOpt(self, DEBUG_DB);
353 TimexBar:Debug(timexDebug);
354 runStartupFunctions(self);
355 end
356  
357 function Timex:AddStartupFunc(f, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
358 local init = newTable();
359 init.f, init.a = f, arg;
360 init.a1, init.a2, init.a3, init.a4, init.a5 = a1, a2, a3, a4, a5;
361 init.a6, init.a7, init.a8, init.a9, init.a10 = a6, a7, a8, a9, a10;
362 init.a11, init.a12, init.a13, init.a14, init.a15 = a11, a12, a13, a14, a15;
363 init.a16, init.a17, init.a18, init.a19, init.a20 = a16, a17, a18, a19, a20;
364 tinsert(initDB, init);
365 end
366  
367 function Timex:Update(dt)
368 local now = getTime();
369  
370 for k, onUpdate in pairs(onUpdateDB) do
371 onUpdate.del = true;
372 local a = onUpdate.a;
373 local ret = onUpdate.f(a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20]);
374 if ret and onUpdate.aR and onUpdate.del then
375 onUpdateDB[k] = nil;
376 onUpdateMap[onUpdate.id] = nil;
377 unusedSchedules[onUpdate] = true;
378 end
379 onUpdate.del = nil;
380 end
381  
382 local schedule = scheduleDB[1];
383 while schedule and now >= schedule.d do
384 local elapsed = now - schedule.l;
385 schedule.elapsed = elapsed;
386  
387 local runCount;
388  
389 local count, t = schedule.c, schedule.t;
390 local runCount;
391 if count then
392 runCount = t > 0 and floor((now - schedule.s)/t) or 1;
393 runCount = runCount < count and runCount or count;
394 count = count - runCount;
395 schedule.c = count;
396 if (count <= 0) then
397 -- mark schedule for deletion
398 schedule.del = true;
399 else
400 schedule.l, schedule.s, schedule.d = now, schedule.d, schedule.d + t;
401 hSiftDown(scheduleDB, 1, schedule);
402 end
403 elseif schedule.r then
404 schedule.l, schedule.s, schedule.d = now, schedule.d, schedule.d + t;
405 hSiftDown(scheduleDB, 1, schedule);
406 else
407 -- mark schedule for deletion
408 schedule.del = true;
409 end
410 -- run the function
411 local run = schedule.run;
412 if run then
413 local ret = run(schedule, runCount);
414 if ret and schedule.aR then
415 schedule.del = true;
416 end
417 end
418 if schedule.del then
419 -- remove from heap
420 hPop(scheduleDB);
421 if schedule.u then
422 deleteOnUpdate(schedule);
423 else
424 deleteSchedule(schedule);
425 end
426 end
427 schedule = scheduleDB[1];
428 end
429 handleFrame();
430 end
431  
432 function Timex:Debug()
433 togOpt(self, DEBUG_DB);
434 timexDebug = getOpt(self, DEBUG_DB);
435 TimexBar:Debug(timexDebug);
436 if timexDebug then
437 self.cmd:msg("Debug: ON");
438 else
439 self.cmd:msg("Debug: OFF");
440 end
441 end
442  
443 --<< ================================================= >>--
444 -- Section IV: The Timex Schedule Functions. --
445 --<< ================================================= >>--
446  
447 -- changed to support max of 20 arguments (to prevent table creation)
448 function Timex:AddSchedule(id, t, r, c, f, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
449 if id or t then
450 local now = getTime();
451 -- look for named schedule
452 local schedule;
453 if id then
454 schedule = scheduleMap[id];
455 end
456  
457 if not schedule then
458 -- create
459 schedule = newSchedule();
460 if id then
461 scheduleMap[id] = schedule;
462 end
463 tinsert(scheduleDB, schedule);
464 schedule.i = getn(scheduleDB);
465 end
466 schedule.id = id or this:GetName() or scheduleDB;
467 t = t and getNumber(t) or 0;
468 t = t >= 0 and t or 0;
469 schedule.t, schedule.r, schedule.c = t, r, c and getNumber(c) or nil;
470 if f then
471 local fType = type(f);
472 if fType == "function" then
473 schedule.f, schedule.run = f, callFunction;
474 elseif fType == "string" then
475 schedule.f = self.TriggerEvent;
476 if f == TT_UPDATE then
477 schedule.e, schedule.run = TT_UPDATE_EVENT, triggerDeprecatedEvent;
478 else
479 schedule.e, schedule.run = f, triggerEvent;
480 end
481 else
482 error("Timex:AddSchedule: param f is not a function or an event name");
483 end
484  
485 -- check for multi
486 if c then
487 schedule.runF, schedule.run = schedule.run, runMultiple;
488 end
489 else
490 schedule.run = nil;
491 end
492 buildArgs(schedule.a, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
493 -- last update, start time, due time
494 schedule.l, schedule.s, schedule.d = now, now, now + t;
495  
496 -- clear deletion, auto-remove (for onUpdate) flag
497 schedule.del = nil;
498 schedule.aR = nil;
499  
500 -- onupdate flag;
501 schedule.u = nil;
502  
503 -- place in scheduleDB
504 hMaintain(scheduleDB, schedule.i, schedule);
505  
506 handleFrame();
507 end
508 end
509  
510 function Timex:DeleteSchedule(id)
511 local schedule = scheduleMap[id];
512 if schedule then
513 hDelete(scheduleDB, schedule.i);
514 deleteSchedule(schedule);
515 handleFrame();
516 end
517 end
518  
519 function Timex:CheckSchedule(id, r)
520 local schedule = scheduleMap[id];
521 if schedule then
522 if r then
523 -- shows the time remaining
524 return schedule.d - getTime();
525 else
526 return true;
527 end
528 end
529 end
530  
531 function Timex:ElapsedScheduleTime(id)
532 local now = getTime();
533 local schedule = scheduleMap[id];
534 if schedule then
535 -- show the time elapsed
536 return now - schedule.s, schedule.s, now;
537 else
538 return 0, 0, now;
539 end
540 end
541  
542 function Timex:RemainingScheduleTime(id)
543 local now = getTime();
544 local schedule = scheduleMap[id];
545 if schedule then
546 -- show the time remaining
547 return schedule.d - now, schedule.d, now;
548 else
549 return 0, 0, now;
550 end
551 end
552  
553 function Timex:ChangeScheduleDuration(id, t)
554 local schedule = scheduleMap[id];
555 if schedule and t then
556 schedule.t, schedule.d = t, schedule.s + t;
557 hMaintain(scheduleDB, schedule.i, schedule);
558 end
559 end
560  
561 function Timex:ChangeScheduleDue(id, d)
562 local schedule = scheduleMap[id];
563 if schedule then
564 schedule.d = d or getTime();
565 hMaintain(scheduleDB, schedule.i, schedule);
566 end
567 end
568  
569 --<< ================================================= >>--
570 -- Section V: The Timex Timer Functions. --
571 --<< ================================================= >>--
572 -- largely for Chronos compatibility - plus it's a pretty cool idea!
573  
574 function Timex:AddTimer(id)
575 local now = getTime();
576 id = id or this:GetName();
577 local timer = timerDB[id];
578 if not timer then
579 timer = newTable();
580 timerDB[id] = timer;
581 end
582 tinsert(timer, now);
583 end
584  
585 function Timex:DeleteTimer(id)
586 local now = getTime();
587 id = id or this:GetName();
588 local timer = timerDB[id];
589 local start;
590 if timer then
591 local start = tremove(timer);
592 -- delete timer if it is empt
593 if getn(timer) == 0 then
594 deleteTable(timer);
595 timerDB[id] = nil;
596 end
597 return now - start, start, now;
598 else
599 return 0, 0, now;
600 end
601 end
602  
603 function Timex:GetTimer(id)
604 local now = getTime();
605 id = id or this:GetName();
606 local timer = timerDB[id];
607 local start;
608 if timer then
609 local start = timer[getn(timer)];
610 return now - start, start, now;
611 else
612 return 0, 0, now;
613 end
614 end
615  
616 function Timex:CheckTimer(id)
617 id = id or this:GetName();
618 if timerDB[id] then
619 return true;
620 else
621 return false;
622 end
623 end
624  
625 --<< ================================================= >>--
626 -- Section VI: The Timex OnUpdate Functions. --
627 --<< ================================================= >>--
628  
629 local function insertOnUpdate(onUpdate)
630 -- find first empty spot
631 local i, v = 1, onUpdateDB[1];
632 while v ~= nil do
633 i = i + 1;
634 v = onUpdateDB[i];
635 end
636 onUpdateDB[i], onUpdate.i = onUpdate, i;
637 end
638  
639 -- moves the onUpdate to the correct table based on the new rate
640 local function maintainOnUpdate(onUpdate, rate)
641 if rate then
642 if not onUpdate.t then
643 -- remove from onUpdateDB
644 onUpdateDB[onUpdate.i] = nil;
645 -- add to scheduleDB
646 tinsert(scheduleDB, onUpdate);
647 onUpdate.i = getn(scheduleDB);
648 end
649 elseif onUpdate.t then
650 -- remove from scheduleDB and add to onUpdateDB
651 hDelete(scheduleDB, onUpdate.i, onUpdate);
652 insertOnUpdate(onUpdate);
653 end
654 end
655  
656 local function setOnUpdateRate(onUpdate, rate, now)
657 if rate then
658 -- last update, start time, due time
659 onUpdate.t, onUpdate.l, onUpdate.s, onUpdate.d = rate, now, now, now + rate;
660  
661 -- place in scheduleDB
662 hMaintain(scheduleDB, onUpdate.i, onUpdate);
663 else
664 onUpdate.t, onUpdate.l, onUpdate.s, onUpdate.d = nil, nil, nil, nil;
665 end
666 end
667  
668 function Timex:AddOnUpdate(id, rate, autoRemove, f, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
669 if f then
670 local now = getTime();
671 -- look for named onUpdate
672 local onUpdate;
673 if id then
674 onUpdate = onUpdateMap[id];
675 end
676  
677 if rate then
678 rate = getNumber(rate);
679 rate = rate > 0 and rate or nil;
680 end
681  
682 if not onUpdate then
683 -- create
684 onUpdate = newSchedule();
685 if id then
686 onUpdateMap[id] = onUpdate;
687 end
688  
689 -- insert into scheduleDB or onUpdateDB, depending on whether a rate is specced or not
690 if rate then
691 tinsert(scheduleDB, onUpdate);
692 onUpdate.i = getn(scheduleDB);
693 else
694 insertOnUpdate(onUpdate);
695 end
696 else
697 maintainOnUpdate(onUpdate, rate);
698 end
699 onUpdate.id = id or this:GetName() or onUpdateDB;
700 onUpdate.aR, onUpdate.f, onUpdate.r, onUpdate.del = autoRemove, f, true, nil;
701  
702 -- maintain scheduleDB if necessary
703 setOnUpdateRate(onUpdate, rate, now);
704  
705 -- flag as an update schedule
706 onUpdate.u = true;
707  
708 buildArgs(onUpdate.a, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
709 handleFrame();
710 end
711 end
712  
713 function Timex:DeleteOnUpdate(id)
714 local onUpdate = onUpdateMap[id];
715 if onUpdate then
716 if onUpdate.t then
717 hDelete(scheduleDB, onUpdate.i);
718 deleteOnUpdate(onUpdate);
719 else
720 onUpdate.del = nil;
721 onUpdateDB[onUpdate.i] = nil;
722 onUpdateMap[id] = nil;
723 unusedSchedules[onUpdate] = true;
724 end
725 handleFrame();
726 end
727 end
728  
729 function Timex:ChangeOnUpdateRate(id, rate)
730 local onUpdate = onUpdateMap[id];
731 if onUpdate then
732 local now = getTime();
733 if rate then
734 rate = getNumber(rate);
735 rate = rate > 0 and rate or nil;
736 end
737  
738 maintainOnUpdate(onUpdate, rate);
739  
740 setOnUpdateRate(onUpdate, rate, now);
741 end
742 end
743  
744 --<< ================================================= >>--
745 -- Section Omega: Register the AddOn Object. --
746 --<< ================================================= >>--
747  
748 Timex:RegisterForLoad()