diff options
-rw-r--r-- | include/vcl/timer.hxx | 6 | ||||
-rw-r--r-- | vcl/qa/cppunit/timer.cxx | 11 | ||||
-rw-r--r-- | vcl/source/app/timer.cxx | 74 |
3 files changed, 78 insertions, 13 deletions
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx index 10dd3fca730f..11e8f3fa875d 100644 --- a/include/vcl/timer.hxx +++ b/include/vcl/timer.hxx @@ -35,8 +35,11 @@ protected: sal_uLong mnTimeout; bool mbActive; bool mbAuto; + bool mbIdle; Link maTimeoutHdl; + friend struct ImplTimerData; + public: Timer(); Timer( const Timer& rTimer ); @@ -60,6 +63,9 @@ public: static void ImplDeInitTimer(); static void ImplTimerCallbackProc(); + + /// Process all pending idle tasks ahead of time in priority order. + static void ProcessAllIdleHandlers(); }; /// An auto-timer is a multi-shot timer re-emitting itself at diff --git a/vcl/qa/cppunit/timer.cxx b/vcl/qa/cppunit/timer.cxx index 84dd40a75b69..a0860009ca6d 100644 --- a/vcl/qa/cppunit/timer.cxx +++ b/vcl/qa/cppunit/timer.cxx @@ -46,6 +46,7 @@ class TimerTest : public test::BootstrapFixture public: TimerTest() : BootstrapFixture(true, false) {} + void testIdle(); #ifdef TEST_WATCHDOG void testWatchdog(); #endif @@ -55,6 +56,7 @@ public: void testSlowTimerCallback(); CPPUNIT_TEST_SUITE(TimerTest); + CPPUNIT_TEST(testIdle); #ifdef TEST_WATCHDOG CPPUNIT_TEST(testWatchdog); #endif @@ -77,6 +79,15 @@ void TimerTest::testWatchdog() } #endif + +void TimerTest::testIdle() +{ +// Add an idle handler +// forcible execute that lot first ... and ... + +// Error ... +} + // -------------------------------------------------------------------- class TimerBool : public Timer diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx index 5f706abcb88a..529c8b53d881 100644 --- a/vcl/source/app/timer.cxx +++ b/vcl/source/app/timer.cxx @@ -36,6 +36,50 @@ struct ImplTimerData sal_uLong mnTimerUpdate; // TimerCallbackProcs on stack bool mbDelete; // Was timer deleted during Update()? bool mbInTimeout; // Are we in a timeout handler? + + void Invoke() + { + if (mbDelete || mbInTimeout ) + return; + + // if no AutoTimer than stop + if ( !mpTimer->mbAuto ) + { + mbDelete = true; + mpTimer->mbActive = false; + } + + // invoke it + mbInTimeout = true; + mpTimer->Timeout(); + mbInTimeout = false; + } + + sal_uLong GetDeadline() + { + return mnUpdateTime + mpTimer->mnTimeout; + } + static ImplTimerData *GetFirstIdle() + { + ImplSVData* pSVData = ImplGetSVData(); + ImplTimerData *pMostUrgent = NULL; + + for ( ImplTimerData *p = pSVData->mpFirstTimerData; p; p = p->mpNext ) + { + if ( !p->mpTimer || p->mbDelete || !p->mpTimer->mbIdle ) + continue; + if (!pMostUrgent) + pMostUrgent = p; + else + { + // Find the highest priority one somehow. + if ( p->GetDeadline() < pMostUrgent->GetDeadline() ) + pMostUrgent = p; + } + } + + return pMostUrgent; + } }; void Timer::ImplDeInitTimer() @@ -110,22 +154,12 @@ void Timer::ImplTimerCallbackProc() !pTimerData->mbDelete && !pTimerData->mbInTimeout ) { // time has expired - if ( (pTimerData->mnUpdateTime+pTimerData->mpTimer->mnTimeout) <= nTime ) + if ( pTimerData->GetDeadline() <= nTime ) { // set new update time pTimerData->mnUpdateTime = nTime; - // if no AutoTimer than stop - if ( !pTimerData->mpTimer->mbAuto ) - { - pTimerData->mpTimer->mbActive = false; - pTimerData->mbDelete = true; - } - - // call Timeout - pTimerData->mbInTimeout = true; - pTimerData->mpTimer->Timeout(); - pTimerData->mbInTimeout = false; + pTimerData->Invoke(); } } @@ -197,11 +231,22 @@ void Timer::ImplTimerCallbackProc() pSVData->mbNotAllTimerCalled = false; } +void Timer::ProcessAllIdleHandlers() +{ + // process all pending Idle timers + while (ImplTimerData* pTimerData = + ImplTimerData::GetFirstIdle()) + { + pTimerData->Invoke(); + } +} + Timer::Timer(): mpTimerData(NULL), mnTimeout(1), mbActive(false), - mbAuto(false) + mbAuto(false), + mbIdle(false) { } @@ -210,6 +255,7 @@ Timer::Timer( const Timer& rTimer ): mnTimeout(rTimer.mnTimeout), mbActive(false), mbAuto(false), + mbIdle(false), maTimeoutHdl(rTimer.maTimeoutHdl) { if ( rTimer.IsActive() ) @@ -339,12 +385,14 @@ AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer ) Idle::Idle() : Timer() { + mbIdle = true; SetPriority(VCL_IDLE_PRIORITY_LOWEST); } Idle::Idle( IdlePriority ePriority ) : Timer() { + mbIdle = true; SetPriority( ePriority ); } |