www.pudn.com > MicroWindows-Source-200606.zip > timer.cpp
// // Micro Windows Implementation // timer.h: the Timer Controller // // NOTE: this module is COMPILER and MACHINE DEPENDENT. // // $Revision: 1.2 $ // $Source: P:/MWINDOWS/LIB/rcs/timer.cpp $ // $Date: 1993/11/27 09:53:32 $ // #include#include "timer.h" #include "global.h" static BOOL timer_on; static void interrupt (*timer_oldtimer)(...) = NULL; static void interrupt timer_newtimer (...); struct TimerObject : public Object { TimerObject (View *apr) { applier = apr; counter = tick = amount = 0; } View *applier; unsigned int counter, tick, amount; }; Timer::Timer () { if (timer_oldtimer) return; // Int 1ch handler is occupied timer_oldtimer = getvect (0x1c); setvect (0x1c, timer_newtimer); } Timer::~Timer() { setvect (0x1c, timer_oldtimer); Object *obj = applierList.first (); do { if (obj == NULL) break; delete obj; obj = applierList.next (); } while (1); } void Timer::apply (View *applier, unsigned int msec) { if (findApplier (applier) == TRUE) return; TimerObject *newobj = new TimerObject (applier); // calc the tick and amount of the timer object unsigned long ltick = (msec * 18) / 1000; if (!ltick) newobj->tick = 1; else newobj->tick = (unsigned int)ltick; unsigned long lamount = 1000 / (msec * 18); if (!ltick) { if (!lamount) newobj->amount = 1; else newobj->amount = (unsigned int)lamount; } else newobj->amount = 1; newobj->counter = newobj->tick; applierList.put (newobj); } void Timer::remove (View *applier) { if (findApplier (applier) == FALSE) return; TimerObject *obj = (TimerObject*)applierList.here (); applierList.remove (); // remove all messages that sent by me to the applier, // otherwise, those undispatched messages will be // sent to the destructed one... :Q // msgqueue->removeBy (this, obj->applier); delete obj; } void Timer::pool (MessageQueue *queue) { // if Int 1ch (i.e. the timer) is triggered, send timer messages // to ALL the appliers. // if (timer_on == FALSE) return; timer_on = FALSE; TimerObject *obj = (TimerObject*)applierList.first(); do { if (obj == NULL) break; obj->counter --; if (!obj->counter) { for (int i = 0; i < obj->amount; i++) { queue->put (NULL, obj->applier, this); } obj->counter = obj->tick; } obj = (TimerObject*)applierList.next(); } while (1); } BOOL Timer::findApplier (View *applier) { TimerObject *obj; obj = (TimerObject*)applierList.first (); do { if (obj == NULL) break; if (obj->applier == applier) return (TRUE); obj = (TimerObject*)applierList.next(); } while (1); return (FALSE); } static void interrupt timer_newtimer (...) { timer_oldtimer (...); timer_on = TRUE; }