home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-01-02 | 11.6 KB | 434 lines | [TEXT/CWIE] |
- // ===========================================================================
- // CActiveXScheduler.cpp ©1996 Microsoft Corporation. All rights reserved.
- // ===========================================================================
- //
- // schedules Active X idle tasks
-
- #ifdef PowerPlant_PCH
- #include PowerPlant_PCH
- #endif
-
- #include "CActiveXScheduler.h"
-
- CActiveXScheduler* CActiveXScheduler::sActiveXScheduler = NULL;
- static Int16 CompareSchedControlStruct(SchedControlStruct *p1, SchedControlStruct *p2);
-
- #pragma mark === CActiveXScheduler Constructor & Destructor ===
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::GetActiveXScheduler [static]
- // ---------------------------------------------------------------------------
- // creates a single instance
-
- CActiveXScheduler*
- CActiveXScheduler::GetActiveXScheduler(Boolean8 MakeIt)
- {
- if (!sActiveXScheduler && MakeIt)
- sActiveXScheduler = new CActiveXScheduler;
-
- return sActiveXScheduler;
- }
-
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::CActiveXScheduler
- // ---------------------------------------------------------------------------
- // default constructor
-
- CActiveXScheduler::CActiveXScheduler()
- {
- mScheduledControls = NULL;
- mNeedsSorting = false;
- }
-
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::~CActiveXScheduler
- // ---------------------------------------------------------------------------
- // destructor
-
- CActiveXScheduler::~CActiveXScheduler(void)
- {
- if (mScheduledControls)
- ::DisposeHandle(Handle(mScheduledControls));
- }
-
-
- #pragma mark === CActiveXScheduler Idle methods ===
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::Idle
- // ---------------------------------------------------------------------------
- // give time to scheduled active x objects
-
- ErrorCode
- CActiveXScheduler::Idle(Boolean8 inNullEvent)
- {
- if (mScheduledControls)
- {
- if (mNeedsSorting)
- Sort();
-
- // give time to controls
- ::HLockHi(Handle(mScheduledControls));
- SchedControlStruct* here = *mScheduledControls;
- SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + ::GetHandleSize(Handle(mScheduledControls)));
- Int32 CurrentTime = ::TickCount();
-
- while (here < end && here->WaitUntil <= CurrentTime)
- {
- if (here->AfterAllEvents || inNullEvent)
- {
- here->Control->DoIdle(here->ControlRefCon);
-
- // reschedule the control if its waituntil time changes
- if (here->Interval > 0)
- {
- mNeedsSorting = true;
- here->WaitUntil = CurrentTime + here->Interval;
- }
- }
- here++;
- }
-
- ::HUnlock(Handle(mScheduledControls));
- }
-
- return S_OK;
- }
-
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::IdleControl
- // ---------------------------------------------------------------------------
- // give time to the one control if it is registered to want it
-
- ErrorCode
- CActiveXScheduler::IdleControl(Boolean8 inNullEvent, IControl* inControl)
- {
- if (mScheduledControls)
- {
- if (mNeedsSorting)
- Sort();
-
- // give time to the control
- ::HLockHi(Handle(mScheduledControls));
- SchedControlStruct* here = *mScheduledControls;
- SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + ::GetHandleSize(Handle(mScheduledControls)));
- Int32 CurrentTime = ::TickCount();
-
- while (here < end && here->WaitUntil <= CurrentTime)
- {
- if ((here->AfterAllEvents || inNullEvent) && here->Control == inControl)
- {
- here->Control->DoIdle(here->ControlRefCon);
-
- // reschedule the control if its waituntil time changes
- if (here->Interval > 0)
- {
- mNeedsSorting = true;
- here->WaitUntil = CurrentTime + here->Interval;
- }
- }
- here++;
- }
-
- ::HUnlock(Handle(mScheduledControls));
- }
-
- return S_OK;
- }
-
-
- #pragma mark === CActiveXScheduler change queue items ===
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::ScheduleControl
- // ---------------------------------------------------------------------------
- // schedule a control - adding it if it isn't there, changing its time if it is
-
- ErrorCode
- CActiveXScheduler::ScheduleControl(Boolean8 AfterAllEvents, Int32 Interval, IControl* inControl, Uint32 ControlRefCon)
- {
- ErrorCode Result = E_FAIL;
- Uint32 WaitUntil = ::TickCount() + Interval;
- Uint32 HandleBytes = 0;
-
- AfterAllEvents = AfterAllEvents ? true : false; // be sure there are only two possible values
-
- // first see if we can just overwrite an existing record
- if (mScheduledControls)
- {
- HandleBytes = ::GetHandleSize(Handle(mScheduledControls));
-
- // I'm not going to lock handles here since I make NO function calls
- SchedControlStruct* here = *mScheduledControls;
- SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + HandleBytes);
-
- while (Result == E_FAIL && here < end)
- {
- if (here->Control == inControl && here->ControlRefCon == ControlRefCon)
- {
- mNeedsSorting = true;
- Result = S_OK;
- here->WaitUntil = WaitUntil;
- here->Interval = Interval;
- here->AfterAllEvents = AfterAllEvents;
- }
- else
- here++;
- }
- }
-
- if (Result == E_FAIL)
- {
- if (!mScheduledControls)
- mScheduledControls = (SchedControlStruct**)::NewHandle(0);
-
- if (mScheduledControls)
- {
- ::SetHandleSize(Handle(mScheduledControls), HandleBytes + sizeof(SchedControlStruct));
- if (::MemError() == noErr)
- {
- // again, no handle locking since there aren't any function calls
- SchedControlStruct* here = (SchedControlStruct*)((Char8*)*mScheduledControls + HandleBytes);
-
- mNeedsSorting = true;
- here->Control = inControl;
- here->ControlRefCon = ControlRefCon;
- here->WaitUntil = WaitUntil;
- here->Interval = Interval;
- here->AfterAllEvents = AfterAllEvents;
- Result = S_OK;
- }
- }
- }
-
- return Result;
- }
-
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::RemoveControlByRefCon
- // ---------------------------------------------------------------------------
- // remove a specific control and refcon pair from the queue
-
- ErrorCode
- CActiveXScheduler::RemoveControlByRefCon(IControl* inControl, Uint32 ControlRefCon)
- {
- ErrorCode Result = E_FAIL;
-
- if (mScheduledControls)
- {
- ::HLock(Handle(mScheduledControls));
- if (::MemError() == noErr)
- {
- Uint32 HandleBytes = ::GetHandleSize(Handle(mScheduledControls));
- SchedControlStruct* here = *mScheduledControls;
- SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + HandleBytes);
-
- while (Result == E_FAIL && here < end)
- {
- if (here->Control == inControl && here->ControlRefCon == ControlRefCon)
- {
- Result = S_OK;
- ::BlockMove(here+1, here, (Char8*)end - (Char8*)(here+1));
- HandleBytes -= sizeof(SchedControlStruct);
- }
- else
- here++;
- }
- ::HUnlock(Handle(mScheduledControls));
-
- // if we removed something then resize the handle down
- if (Result == S_OK)
- ::SetHandleSize(Handle(mScheduledControls), HandleBytes);
- }
- }
-
- return Result;
- }
-
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::RemoveControl
- // ---------------------------------------------------------------------------
- // remove all items in the queue belonging the the control
-
- ErrorCode
- CActiveXScheduler::RemoveControl(IControl* inControl)
- {
- ErrorCode Result = E_FAIL;
-
- if (mScheduledControls)
- {
- ::HLock(Handle(mScheduledControls));
- if (::MemError() == noErr)
- {
- Uint32 HandleBytes = ::GetHandleSize(Handle(mScheduledControls));
- SchedControlStruct* here = *mScheduledControls;
- SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + HandleBytes);
-
- while (here < end)
- {
- if (here->Control == inControl)
- {
- Result = S_OK;
- ::BlockMove(here+1, here, (Char8*)end - (Char8*)(here+1));
- end--;
- }
- else
- here++;
- }
-
- // if we removed something then resize the handle down
- HandleBytes = (Char8*)end - (Char8*)*mScheduledControls;
- ::HUnlock(Handle(mScheduledControls));
- if (Result == S_OK)
- ::SetHandleSize(Handle(mScheduledControls), HandleBytes);
- }
- }
-
- return Result;
- }
-
-
- #pragma mark === CActiveXScheduler query scheduler methods ===
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::HasNullEventItems
- // ---------------------------------------------------------------------------
- // remove all items in the queue belonging the the control
-
- Boolean8
- CActiveXScheduler::HasNullEventItems(void)
- {
- Boolean8 Result = false;
-
- if (mScheduledControls)
- {
- // I'm not going to lock handles here since I make NO function calls
- SchedControlStruct* here = *mScheduledControls;
- SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + ::GetHandleSize(Handle(mScheduledControls)));
-
- while (!Result && here < end)
- {
- Result = !here->AfterAllEvents;
- here++;
- }
- }
-
- return Result;
- }
-
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::HasAllEventItems
- // ---------------------------------------------------------------------------
- // remove all items in the queue belonging the the control
-
- Boolean8
- CActiveXScheduler::HasAllEventItems(void)
- {
- Boolean8 Result = false;
-
- if (mScheduledControls)
- {
- Uint32 HandleBytes = ::GetHandleSize(Handle(mScheduledControls));
-
- // I'm not going to lock handles here since I make NO function calls
- SchedControlStruct* here = *mScheduledControls;
- SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + ::GetHandleSize(Handle(mScheduledControls)));
-
- while (!Result && here < end)
- {
- Result = here->AfterAllEvents;
- here++;
- }
- }
-
- return Result;
- }
-
-
- #pragma mark === CActiveXScheduler private methods ===
-
- // ---------------------------------------------------------------------------
- // • CActiveXScheduler::Sort
- // ---------------------------------------------------------------------------
- // sort the job schedule queue - use a bubble sort since the queue shouldn't
- // be very long nor very out of order
-
- void
- CActiveXScheduler::Sort(void)
- {
- Uint32 ItemCount;
-
- if (mNeedsSorting && (!mScheduledControls ||
- (ItemCount = ::GetHandleSize(Handle(mScheduledControls))/sizeof(SchedControlStruct)) <= 1))
- mNeedsSorting = false;
-
- if (mNeedsSorting)
- {
- SchedControlStruct *p1, *p2;
- SchedControlStruct *begin = *mScheduledControls;
- SchedControlStruct *end = begin + ItemCount - 1;
-
- while (begin < end)
- {
- SchedControlStruct *newEnd = NULL;
- for (p1 = begin, p2 = begin + 1; p2 <= end; p1++, p2++)
- {
- SchedControlStruct Temp;
-
- if (CompareSchedControlStruct(p1, p2) > 0)
- {
- Temp = *p1;
- *p1 = *p2;
- *p2 = Temp;
- newEnd = p1;
- }
- }
- end = newEnd;
- }
-
- mNeedsSorting = false;
- }
- }
-
-
- #pragma mark === static function ===
-
- // ---------------------------------------------------------------------------
- // • CompareSchedControlStruct
- // ---------------------------------------------------------------------------
- // comparison function - sort order is (WaitUntil ascending, NullOnly, Job, JobRefCon)
-
- Int16 CompareSchedControlStruct(SchedControlStruct *p1, SchedControlStruct *p2)
- {
- Int32 ReturnValue = 1;
-
- if (p1->WaitUntil < p2->WaitUntil)
- ReturnValue = -1;
- else if (p1->WaitUntil == p2->WaitUntil)
- {
- if (p1->AfterAllEvents && !p2->AfterAllEvents)
- ReturnValue = -1;
- else if (p1->AfterAllEvents == p2->AfterAllEvents)
- {
- if (p1->Control < p2->Control)
- ReturnValue = -1;
- else if (p1->Control == p2->Control)
- {
- if (p1->ControlRefCon < p2->ControlRefCon)
- ReturnValue = -1;
- else if (p1->ControlRefCon == p2->ControlRefCon)
- ReturnValue = 0;
- }
- }
- }
-
- return ReturnValue;
- }
-
-