diff options
author | Tobias Madl <tobias.madl.dev@gmail.com> | 2015-02-26 07:33:59 +0000 |
---|---|---|
committer | Tobias Madl <tobias.madl.dev@gmail.com> | 2015-03-06 12:27:10 +0000 |
commit | f33d6800fbdc42aa75477e31be0bba5a4a5a52c1 (patch) | |
tree | 031608831e7cc2b3ceb1decc45eab74fb1f06041 /vcl/source/app | |
parent | 8f9b0c869222e57f738bc25d51cc6364e3c6a65a (diff) |
Idle Timer: Invented Base Class
Change-Id: I03db46afcc0cb5e5d7a134b1bdd327abb542e63c
Diffstat (limited to 'vcl/source/app')
-rw-r--r-- | vcl/source/app/idle.cxx | 205 | ||||
-rw-r--r-- | vcl/source/app/scheduler.cxx | 235 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 14 | ||||
-rw-r--r-- | vcl/source/app/svmain.cxx | 6 | ||||
-rw-r--r-- | vcl/source/app/timer.cxx | 305 |
5 files changed, 283 insertions, 482 deletions
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx index 09ffbc77af92..7fe239d199f7 100644 --- a/vcl/source/app/idle.cxx +++ b/vcl/source/app/idle.cxx @@ -17,220 +17,27 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include <vcl/svapp.hxx> #include <vcl/idle.hxx> -#include <vcl/timer.hxx> -#include <svdata.hxx> -#include <salinst.hxx> - -struct ImplIdleData -{ - ImplIdleData* mpNext; // Pointer to the next element in list - Idle* mpIdle; // Pointer to VCL Idle instance - bool mbDelete; // Destroy this idle? - bool mbInIdle; // Idle handler currently processed? - - void Invoke() - { - if (mbDelete || mbInIdle ) - return; - - mpIdle->SetSchedulingPriority(static_cast<sal_Int32>(mpIdle->GetDefaultPriority())); - mbDelete = true; - mpIdle->mbActive = false; - - // invoke it - mbInIdle = true; - mpIdle->DoIdle(); - mbInIdle = false; - } - - static ImplIdleData *GetFirstIdle() - { - ImplSVData* pSVData = ImplGetSVData(); - ImplIdleData *pMostUrgent = NULL; - - for ( ImplIdleData *p = pSVData->mpFirstIdleData; p; p = p->mpNext ) - { - if ( !p->mpIdle || p->mbDelete ) - continue; - if (!pMostUrgent) - pMostUrgent = p; - else - { - // Find the highest priority. - // If the priority of the current idle is higher (numerical value is lower) than - // the priority of the most urgent, the priority of most urgent is increased and - // the current is the new most urgent. So starving is impossible. - if ( p->mpIdle->GetPriority() < pMostUrgent->mpIdle->GetPriority() ) - { - pMostUrgent->mpIdle->SetSchedulingPriority( pMostUrgent->mpIdle->GetPriority() - 1); - pMostUrgent = p; - } - else - p->mpIdle->SetSchedulingPriority( p->mpIdle->GetPriority() - 1); - } - } - - return pMostUrgent; - } -}; - -void Idle::ImplDeInitIdle() -{ - ImplSVData* pSVData = ImplGetSVData(); - ImplIdleData* pIdleData = pSVData->mpFirstIdleData; - - if ( pIdleData ) - { - do - { - ImplIdleData* pTempIdleData = pIdleData; - if ( pIdleData->mpIdle ) - { - pIdleData->mpIdle->mbActive = false; - pIdleData->mpIdle->mpIdleData = NULL; - } - pIdleData = pIdleData->mpNext; - delete pTempIdleData; - } - while ( pIdleData ); - - pSVData->mpFirstIdleData = NULL; - } -} - -void Idle::ProcessAllIdleHandlers() -{ - // process all pending idle - ImplIdleData* pIdleData = NULL; - ImplIdleData* pPrevIdleData = NULL; - ImplSVData* pSVData = ImplGetSVData(); - // timer can interrupt idle - while (!Timer::TimerReady() && (pIdleData = ImplIdleData::GetFirstIdle())) - { - pIdleData->Invoke(); - } - - pIdleData = pSVData->mpFirstIdleData; - while ( pIdleData ) - { - // Should idle be released from scheduling? - if ( pIdleData->mbDelete ) - { - if ( pPrevIdleData ) - pPrevIdleData->mpNext = pIdleData->mpNext; - else - pSVData->mpFirstIdleData = pIdleData->mpNext; - if ( pIdleData->mpIdle ) - pIdleData->mpIdle->mpIdleData = NULL; - ImplIdleData* pTempIdleData = pIdleData; - pIdleData = pIdleData->mpNext; - delete pTempIdleData; - } - else - { - pPrevIdleData = pIdleData; - pIdleData = pIdleData->mpNext; - } - } -} - -void Idle::SetPriority( IdlePriority ePriority ) -{ - meDefaultPriority = ePriority; -} - -void Idle::SetSchedulingPriority( sal_Int32 iPriority ) -{ - miPriority = iPriority; -} - -void Idle::DoIdle() +void Idle::Invoke() { maIdleHdl.Call( this ); } -void Idle::Start() -{ - // Mark timer active - mbActive = true; - - ImplSVData* pSVData = ImplGetSVData(); - if ( !mpIdleData ) - { - // insert Idle - mpIdleData = new ImplIdleData; - mpIdleData->mpIdle = this; - mpIdleData->mbInIdle = false; - - // insert last due to SFX! - ImplIdleData* pPrev = NULL; - ImplIdleData* pData = pSVData->mpFirstIdleData; - while ( pData ) - { - pPrev = pData; - pData = pData->mpNext; - } - mpIdleData->mpNext = NULL; - if ( pPrev ) - pPrev->mpNext = mpIdleData; - else - pSVData->mpFirstIdleData = mpIdleData; - } - mpIdleData->mbDelete = false; -} - -void Idle::Stop() -{ - mbActive = false; - - if ( mpIdleData ) - mpIdleData->mbDelete = true; -} - Idle& Idle::operator=( const Idle& rIdle ) { - if ( IsActive() ) - Stop(); - - mbActive = false; - miPriority = rIdle.miPriority; - meDefaultPriority = rIdle.meDefaultPriority; - maIdleHdl = rIdle.maIdleHdl; - - if ( rIdle.IsActive() ) - Start(); - + Scheduler::operator=(rIdle); + maIdleHdl = rIdle.maIdleHdl; return *this; } -Idle::Idle(): - mpIdleData(NULL), - miPriority(static_cast<sal_Int32>(IdlePriority::HIGH)), - meDefaultPriority(IdlePriority::HIGH), - mbActive(false) +Idle::Idle() : Scheduler() { } -Idle::Idle( const Idle& rIdle ): - mpIdleData(NULL), - miPriority(rIdle.miPriority), - meDefaultPriority(rIdle.meDefaultPriority), - mbActive(false), - maIdleHdl(rIdle.maIdleHdl) +Idle::Idle( const Idle& rIdle ) : Scheduler(rIdle) { - if ( rIdle.IsActive() ) - Start(); + maIdleHdl = rIdle.maIdleHdl; } -Idle::~Idle() -{ - if ( mpIdleData ) - { - mpIdleData->mbDelete = true; - mpIdleData->mpIdle = NULL; - } -} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx new file mode 100644 index 000000000000..e2465fecfda2 --- /dev/null +++ b/vcl/source/app/scheduler.cxx @@ -0,0 +1,235 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <svdata.hxx> +#include <tools/time.hxx> +#include <vcl/scheduler.hxx> + +void ImplSchedulerData::Invoke() +{ + if (mbDelete || mbInScheduler ) + return; + + mpScheduler->SetSchedulingPriority(static_cast<sal_Int32>(mpScheduler->GetDefaultPriority())); + mpScheduler->SetDeletionFlags(); + + // invoke it + mbInScheduler = true; + mpScheduler->Invoke(); + mbInScheduler = false; +} + +ImplSchedulerData *ImplSchedulerData::GetMostImportantTask( bool bTimer ) +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplSchedulerData *pMostUrgent = NULL; + + for ( ImplSchedulerData *p = pSVData->mpFirstSchedulerData; p; p = p->mpNext ) + { + if ( !p->mpScheduler || p->mbDelete || p->mnUpdateStack >= pSVData->mnTimerUpdate || !p->mpScheduler->ReadyForSchedule( bTimer ) ) + continue; + if (!pMostUrgent) + pMostUrgent = p; + else + { + // Find the highest priority. + // If the priority of the current idle is higher (numerical value is lower) than + // the priority of the most urgent, the priority of most urgent is increased and + // the current is the new most urgent. So starving is impossible. + if ( p->mpScheduler->GetPriority() < pMostUrgent->mpScheduler->GetPriority() ) + { + pMostUrgent->mpScheduler->SetSchedulingPriority( pMostUrgent->mpScheduler->GetPriority()); + pMostUrgent = p; + } + else + p->mpScheduler->SetSchedulingPriority( p->mpScheduler->GetPriority()); + } + } + + return pMostUrgent; +} + +void Scheduler::SetDeletionFlags() +{ + mpSchedulerData->mbDelete = true; + mbActive = false; +} + +void Scheduler::ImplDeInitScheduler() +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplSchedulerData* pSchedulerData = pSVData->mpFirstSchedulerData; + + if ( pSchedulerData ) + { + do + { + ImplSchedulerData* pTempSchedulerData = pSchedulerData; + if ( pSchedulerData->mpScheduler ) + { + pSchedulerData->mpScheduler->mbActive = false; + pSchedulerData->mpScheduler->mpSchedulerData = NULL; + } + pSchedulerData = pSchedulerData->mpNext; + delete pTempSchedulerData; + } + while ( pSchedulerData ); + + pSVData->mpFirstSchedulerData = NULL; + } +} + +void Scheduler::CallbackTaskScheduling() +{ + Scheduler::ProcessTaskScheduling( true ); +} + +void Scheduler::ProcessTaskScheduling( bool bTimer ) +{ + // process all pending Tasks + ImplSchedulerData* pSchedulerData = NULL; + ImplSchedulerData* pPrevSchedulerData = NULL; + ImplSVData* pSVData = ImplGetSVData(); + pSVData->mnTimerUpdate++; + + if ((pSchedulerData = ImplSchedulerData::GetMostImportantTask(bTimer))) + { + pSchedulerData->mnUpdateTime = tools::Time::GetSystemTicks(); + pSchedulerData->Invoke(); + } + + pSchedulerData = pSVData->mpFirstSchedulerData; + while ( pSchedulerData ) + { + // Should Task be released from scheduling? + if ( pSchedulerData->mbDelete ) + { + if ( pPrevSchedulerData ) + pPrevSchedulerData->mpNext = pSchedulerData->mpNext; + else + pSVData->mpFirstSchedulerData = pSchedulerData->mpNext; + if ( pSchedulerData->mpScheduler ) + pSchedulerData->mpScheduler->mpSchedulerData = NULL; + ImplSchedulerData* pTempSchedulerData = pSchedulerData; + pSchedulerData = pSchedulerData->mpNext; + delete pTempSchedulerData; + } + else + { + if( !pSchedulerData->mbInScheduler ) + pSchedulerData->mnUpdateStack = 0; + pPrevSchedulerData = pSchedulerData; + pSchedulerData = pSchedulerData->mpNext; + } + } + pSVData->mnTimerUpdate--; +} + +void Scheduler::SetPriority( SchedulerPriority ePriority ) +{ + meDefaultPriority = ePriority; +} + +void Scheduler::SetSchedulingPriority( sal_Int32 iPriority ) +{ + miPriority = iPriority; +} + +void Scheduler::Start() +{ + // Mark timer active + mbActive = true; + + ImplSVData* pSVData = ImplGetSVData(); + if ( !mpSchedulerData ) + { + // insert Idle + mpSchedulerData = new ImplSchedulerData; + mpSchedulerData->mpScheduler = this; + mpSchedulerData->mbInScheduler = false; + + // insert last due to SFX! + ImplSchedulerData* pPrev = NULL; + ImplSchedulerData* pData = pSVData->mpFirstSchedulerData; + while ( pData ) + { + pPrev = pData; + pData = pData->mpNext; + } + mpSchedulerData->mpNext = NULL; + if ( pPrev ) + pPrev->mpNext = mpSchedulerData; + else + pSVData->mpFirstSchedulerData = mpSchedulerData; + } + mpSchedulerData->mbDelete = false; + mpSchedulerData->mnUpdateTime = tools::Time::GetSystemTicks(); + mpSchedulerData->mnUpdateStack = pSVData->mnTimerUpdate; +} + +void Scheduler::Stop() +{ + mbActive = false; + + if ( mpSchedulerData ) + mpSchedulerData->mbDelete = true; +} + +Scheduler& Scheduler::operator=( const Scheduler& rScheduler ) +{ + if ( IsActive() ) + Stop(); + + mbActive = false; + miPriority = rScheduler.miPriority; + meDefaultPriority = rScheduler.meDefaultPriority; + + if ( rScheduler.IsActive() ) + Start(); + + return *this; +} + +Scheduler::Scheduler(): + mpSchedulerData(NULL), + miPriority(static_cast<sal_Int32>(SchedulerPriority::HIGH)), + meDefaultPriority(SchedulerPriority::HIGH), + mbActive(false) +{ +} + +Scheduler::Scheduler( const Scheduler& rScheduler ): + mpSchedulerData(NULL), + miPriority(rScheduler.miPriority), + meDefaultPriority(rScheduler.meDefaultPriority), + mbActive(false) +{ + if ( rScheduler.IsActive() ) + Start(); +} + +Scheduler::~Scheduler() +{ + if ( mpSchedulerData ) + { + mpSchedulerData->mbDelete = true; + mpSchedulerData->mpScheduler = NULL; + } +} + diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index f569bf90aece..33fbf0a55c1e 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -45,7 +45,7 @@ #include "vcl/cvtgrf.hxx" #include "vcl/unowrap.hxx" #include "vcl/timer.hxx" -#include "vcl/idle.hxx" +#include "vcl/scheduler.hxx" #include "vcl/unohelp.hxx" #include "vcl/lazydelete.hxx" @@ -343,11 +343,11 @@ inline void ImplYield( bool i_bWait, bool i_bAllEvents ) ImplSVData* pSVData = ImplGetSVData(); // run timers that have timed out - while ( pSVData->mbNotAllTimerCalled ) - Timer::ImplTimerCallbackProc(); + //while ( pSVData->mbNotAllTimerCalled ) + // Timer::ImplTimerCallbackProc(); //Process all idles - Idle::Idle::ProcessAllIdleHandlers(); + Scheduler::ProcessTaskScheduling(false); pSVData->maAppData.mnDispatchLevel++; // do not wait for events if application was already quit; in that @@ -367,11 +367,7 @@ inline void ImplYield( bool i_bWait, bool i_bAllEvents ) // e.g. on OS X; need to trigger timer checks manually if( pSVData->maAppData.mbNoYield ) { - do - { - Timer::ImplTimerCallbackProc( !i_bWait ); - } - while( pSVData->mbNotAllTimerCalled ); + Scheduler::ProcessTaskScheduling(true); } // call post yield listeners diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index 96302e8ca23f..43f76be04b79 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -33,7 +33,7 @@ #include "vcl/svapp.hxx" #include "vcl/wrkwin.hxx" #include "vcl/cvtgrf.hxx" -#include "vcl/idle.hxx" +#include "vcl/scheduler.hxx" #include "vcl/image.hxx" #include "vcl/settings.hxx" #include "vcl/unowrap.hxx" @@ -387,8 +387,8 @@ void DeInitVCL() if ( pSVData->maAppData.mpIdleMgr ) delete pSVData->maAppData.mpIdleMgr; - Timer::ImplDeInitTimer(); - Idle::ImplDeInitIdle(); + //Timer::ImplDeInitTimer(); + Scheduler::ImplDeInitScheduler(); if ( pSVData->maWinData.mpMsgBoxImgList ) { diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx index 97ab45c9fbd9..b8be2d7ef40b 100644 --- a/vcl/source/app/timer.cxx +++ b/vcl/source/app/timer.cxx @@ -18,83 +18,14 @@ */ #include <tools/time.hxx> - -#include <vcl/svapp.hxx> #include <vcl/timer.hxx> - #include <saltimer.hxx> #include <svdata.hxx> #include <salinst.hxx> +#include <vcl/scheduler.hxx> #define MAX_TIMER_PERIOD ((sal_uLong)0xFFFFFFFF) -struct ImplTimerData -{ - ImplTimerData* mpNext; // Pointer to the next Instance - Timer* mpTimer; // Pointer to VCL Timer instance - sal_uLong mnUpdateTime; // Last Update Time - 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; - } -}; - -void Timer::ImplDeInitTimer() -{ - ImplSVData* pSVData = ImplGetSVData(); - ImplTimerData* pTimerData = pSVData->mpFirstTimerData; - - // on WNT the timer queue thread needs killing - if (pSVData->mpSalTimer) - { - pSVData->mpSalTimer->Stop(); - } - - if ( pTimerData ) - { - do - { - ImplTimerData* pTempTimerData = pTimerData; - if ( pTimerData->mpTimer ) - { - pTimerData->mpTimer->mbActive = false; - pTimerData->mpTimer->mpTimerData = NULL; - } - pTimerData = pTimerData->mpNext; - delete pTempTimerData; - } - while ( pTimerData ); - - pSVData->mpFirstTimerData = NULL; - pSVData->mnTimerPeriod = 0; - } - - delete pSVData->mpSalTimer; - pSVData->mpSalTimer = 0; -} - static void ImplStartTimer( ImplSVData* pSVData, sal_uLong nMS ) { if ( !nMS ) @@ -108,159 +39,59 @@ static void ImplStartTimer( ImplSVData* pSVData, sal_uLong nMS ) } } -void Timer::ImplTimerCallbackProc( bool idle ) +void Timer::SetDeletionFlags() { - ImplSVData* pSVData = ImplGetSVData(); - ImplTimerData* pTimerData; - ImplTimerData* pPrevTimerData; - sal_uLong nMinPeriod = MAX_TIMER_PERIOD; - sal_uLong nDeltaTime; - sal_uLong nTime = tools::Time::GetSystemTicks(); - - pSVData->mnTimerUpdate++; - pSVData->mbNotAllTimerCalled = true; - - Timer::CheckExpiredTimer(true); - - // determine new time - sal_uLong nNewTime = tools::Time::GetSystemTicks(); - pPrevTimerData = NULL; - pTimerData = pSVData->mpFirstTimerData; - while ( pTimerData ) - { - // ignore if timer is still in timeout handler - if ( pTimerData->mbInTimeout ) - { - pPrevTimerData = pTimerData; - pTimerData = pTimerData->mpNext; - } - // Was timer destroyed in the meantime? - else if ( pTimerData->mbDelete ) - { - if ( pPrevTimerData ) - pPrevTimerData->mpNext = pTimerData->mpNext; - else - pSVData->mpFirstTimerData = pTimerData->mpNext; - if ( pTimerData->mpTimer ) - pTimerData->mpTimer->mpTimerData = NULL; - ImplTimerData* pTempTimerData = pTimerData; - pTimerData = pTimerData->mpNext; - delete pTempTimerData; - } - else + // if no AutoTimer than stop + if ( !mbAuto ) { - pTimerData->mnTimerUpdate = 0; - // determine smallest time slot - if ( pTimerData->mnUpdateTime == nTime ) - { - nDeltaTime = pTimerData->mpTimer->mnTimeout; - if ( nDeltaTime < nMinPeriod ) - nMinPeriod = nDeltaTime; - } - else - { - nDeltaTime = pTimerData->mnUpdateTime + pTimerData->mpTimer->mnTimeout; - if ( nDeltaTime < nNewTime ) - nMinPeriod = 1; - else - { - nDeltaTime -= nNewTime; - if ( nDeltaTime < nMinPeriod ) - nMinPeriod = nDeltaTime; - } - } - pPrevTimerData = pTimerData; - pTimerData = pTimerData->mpNext; + mpSchedulerData->mbDelete = true; + mbActive = false; } - } - - // delete clock if no more timers available - if ( !pSVData->mpFirstTimerData ) - { - pSVData->mpSalTimer->Stop(); - pSVData->mnTimerPeriod = MAX_TIMER_PERIOD; - } - else - ImplStartTimer( pSVData, nMinPeriod ); - - pSVData->mnTimerUpdate--; - pSVData->mbNotAllTimerCalled = false; } -bool Timer::TimerReady() +bool Timer::ReadyForSchedule( bool bTimer ) { - return Timer::CheckExpiredTimer(false); + (void)bTimer; + return (mpSchedulerData->mnUpdateTime + mnTimeout) <= tools::Time::GetSystemTicks(); } -bool Timer::CheckExpiredTimer(bool bDoInvoke) +Timer::Timer() : Scheduler() { -// find timer where the timer handler needs to be called - ImplSVData* pSVData = ImplGetSVData(); - ImplTimerData* pTimerData = pSVData->mpFirstTimerData; - sal_uLong nTime = tools::Time::GetSystemTicks(); - bool timerExpired = false; - while ( pTimerData ) - { - // If the timer is not new, was not deleted, and if it is not in the timeout handler, then - // call the handler as soon as the time is up. - if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) && - !pTimerData->mbDelete && !pTimerData->mbInTimeout) - { - // time has expired - if ( pTimerData->GetDeadline() <= nTime ) - { - if(bDoInvoke) - { - //Set new update Timer - pTimerData->mnUpdateTime = nTime; - pTimerData->Invoke(); - } - timerExpired = true; - } - } - - pTimerData = pTimerData->mpNext; - } - return timerExpired; + mnTimeout = 1; + mbAuto = false; + miPriority= static_cast<sal_Int32>(SchedulerPriority::HIGHEST); + meDefaultPriority = SchedulerPriority::HIGHEST; } -Timer::Timer(): - mpTimerData(NULL), - mnTimeout(1), - mbActive(false), - mbAuto(false) +Timer::Timer( const Timer& rTimer ) : Scheduler(rTimer) { + mnTimeout = rTimer.mnTimeout; + mbAuto = rTimer.mbAuto; + maTimeoutHdl = rTimer.maTimeoutHdl; } -Timer::Timer( const Timer& rTimer ): - mpTimerData(NULL), - mnTimeout(rTimer.mnTimeout), - mbActive(false), - mbAuto(false), - maTimeoutHdl(rTimer.maTimeoutHdl) +void Timer::Invoke() { - if ( rTimer.IsActive() ) - Start(); + maTimeoutHdl.Call( this ); } -Timer::~Timer() +void Timer::Start() { - if ( mpTimerData ) + Scheduler::Start(); + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->mpSalTimer ) { - mpTimerData->mbDelete = true; - mpTimerData->mpTimer = NULL; - } -} - -void Timer::Timeout() -{ - maTimeoutHdl.Call( this ); + pSVData->mnTimerPeriod = MAX_TIMER_PERIOD; + pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer(); + pSVData->mpSalTimer->SetCallback( CallbackTaskScheduling ); + } + if ( mnTimeout < pSVData->mnTimerPeriod ) + ImplStartTimer( pSVData, mnTimeout ); } void Timer::SetTimeout( sal_uLong nNewTimeout ) { mnTimeout = nNewTimeout; - // if timer is active then renew clock if ( mbActive ) { @@ -270,80 +101,12 @@ void Timer::SetTimeout( sal_uLong nNewTimeout ) } } -void Timer::Start() -{ - mbActive = true; - - ImplSVData* pSVData = ImplGetSVData(); - if ( !mpTimerData ) - { - if ( !pSVData->mpFirstTimerData ) - { - pSVData->mnTimerPeriod = MAX_TIMER_PERIOD; - if( ! pSVData->mpSalTimer ) - { - pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer(); - pSVData->mpSalTimer->SetCallback( ImplTimerCallbackProc ); - } - } - - // insert timer and start - mpTimerData = new ImplTimerData; - mpTimerData->mpTimer = this; - mpTimerData->mnUpdateTime = tools::Time::GetSystemTicks(); - mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate; - mpTimerData->mbDelete = false; - mpTimerData->mbInTimeout = false; - - // insert last due to SFX! - ImplTimerData* pPrev = NULL; - ImplTimerData* pData = pSVData->mpFirstTimerData; - while ( pData ) - { - pPrev = pData; - pData = pData->mpNext; - } - mpTimerData->mpNext = NULL; - if ( pPrev ) - pPrev->mpNext = mpTimerData; - else - pSVData->mpFirstTimerData = mpTimerData; - - if ( mnTimeout < pSVData->mnTimerPeriod ) - ImplStartTimer( pSVData, mnTimeout ); - } - else if( !mpTimerData->mpTimer ) // TODO: remove when guilty found - { - OSL_FAIL( "Timer::Start() on a destroyed Timer!" ); - } - else - { - mpTimerData->mnUpdateTime = tools::Time::GetSystemTicks(); - mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate; - mpTimerData->mbDelete = false; - } -} - -void Timer::Stop() -{ - mbActive = false; - - if ( mpTimerData ) - mpTimerData->mbDelete = true; -} - Timer& Timer::operator=( const Timer& rTimer ) { - if ( IsActive() ) - Stop(); - - mbActive = false; - mnTimeout = rTimer.mnTimeout; - maTimeoutHdl = rTimer.maTimeoutHdl; - - if ( rTimer.IsActive() ) - Start(); - + Scheduler::operator=(rTimer); + maTimeoutHdl = rTimer.maTimeoutHdl; + mnTimeout = rTimer.mnTimeout; + mbAuto = rTimer.mbAuto; return *this; } |