summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/timer.hxx6
-rw-r--r--vcl/qa/cppunit/timer.cxx11
-rw-r--r--vcl/source/app/timer.cxx74
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 );
}