LCOV - code coverage report
Current view: top level - vcl/source/app - timer.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 11 156 7.1 %
Date: 2014-04-14 Functions: 3 15 20.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <tools/time.hxx>
      21             : 
      22             : #include <vcl/svapp.hxx>
      23             : #include <vcl/timer.hxx>
      24             : 
      25             : #include <saltimer.hxx>
      26             : #include <svdata.hxx>
      27             : #include <salinst.hxx>
      28             : 
      29             : #define MAX_TIMER_PERIOD    ((sal_uLong)0xFFFFFFFF)
      30             : 
      31             : struct ImplTimerData
      32             : {
      33             :     ImplTimerData*  mpNext;         // Pointer to the next Instance
      34             :     Timer*          mpTimer;        // Pointer to VCL Timer instance
      35             :     sal_uLong       mnUpdateTime;   // Last Update Time
      36             :     sal_uLong       mnTimerUpdate;  // TimerCallbackProcs on stack
      37             :     bool            mbDelete;       // Was timer deleted during Update()?
      38             :     bool            mbInTimeout;    // Are we in a timeout handler?
      39             : };
      40             : 
      41           1 : void Timer::ImplDeInitTimer()
      42             : {
      43           1 :     ImplSVData*     pSVData = ImplGetSVData();
      44           1 :     ImplTimerData*  pTimerData = pSVData->mpFirstTimerData;
      45             : 
      46           1 :     if ( pTimerData )
      47             :     {
      48           0 :         do
      49             :         {
      50           0 :             ImplTimerData* pTempTimerData = pTimerData;
      51           0 :             if ( pTimerData->mpTimer )
      52             :             {
      53           0 :                 pTimerData->mpTimer->mbActive = false;
      54           0 :                 pTimerData->mpTimer->mpTimerData = NULL;
      55             :             }
      56           0 :             pTimerData = pTimerData->mpNext;
      57           0 :             delete pTempTimerData;
      58             :         }
      59             :         while ( pTimerData );
      60             : 
      61           0 :         pSVData->mpFirstTimerData   = NULL;
      62           0 :         pSVData->mnTimerPeriod      = 0;
      63           0 :         delete pSVData->mpSalTimer;
      64           0 :         pSVData->mpSalTimer = NULL;
      65             :     }
      66           1 : }
      67             : 
      68           0 : static void ImplStartTimer( ImplSVData* pSVData, sal_uLong nMS )
      69             : {
      70           0 :     if ( !nMS )
      71           0 :         nMS = 1;
      72             : 
      73           0 :     if ( nMS != pSVData->mnTimerPeriod )
      74             :     {
      75           0 :         pSVData->mnTimerPeriod = nMS;
      76           0 :         pSVData->mpSalTimer->Start( nMS );
      77             :     }
      78           0 : }
      79             : 
      80           0 : void Timer::ImplTimerCallbackProc()
      81             : {
      82           0 :     ImplSVData*     pSVData = ImplGetSVData();
      83             :     ImplTimerData*  pTimerData;
      84             :     ImplTimerData*  pPrevTimerData;
      85           0 :     sal_uLong       nMinPeriod = MAX_TIMER_PERIOD;
      86             :     sal_uLong       nDeltaTime;
      87           0 :     sal_uLong       nTime = Time::GetSystemTicks();
      88             : 
      89           0 :     if ( pSVData->mbNoCallTimer )
      90           0 :         return;
      91             : 
      92           0 :     pSVData->mnTimerUpdate++;
      93           0 :     pSVData->mbNotAllTimerCalled = true;
      94             : 
      95             :     // find timer where the timer handler needs to be called
      96           0 :     pTimerData = pSVData->mpFirstTimerData;
      97           0 :     while ( pTimerData )
      98             :     {
      99             :         // If the timer is not new, was not deleted, and if it is not in the timeout handler, then
     100             :         // call the handler as soon as the time is up.
     101           0 :         if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) &&
     102           0 :              !pTimerData->mbDelete && !pTimerData->mbInTimeout )
     103             :         {
     104             :             // time has expired
     105           0 :             if ( (pTimerData->mnUpdateTime+pTimerData->mpTimer->mnTimeout) <= nTime )
     106             :             {
     107             :                 // set new update time
     108           0 :                 pTimerData->mnUpdateTime = nTime;
     109             : 
     110             :                 // if no AutoTimer than stop
     111           0 :                 if ( !pTimerData->mpTimer->mbAuto )
     112             :                 {
     113           0 :                     pTimerData->mpTimer->mbActive = false;
     114           0 :                     pTimerData->mbDelete = true;
     115             :                 }
     116             : 
     117             :                 // call Timeout
     118           0 :                 pTimerData->mbInTimeout = true;
     119           0 :                 pTimerData->mpTimer->Timeout();
     120           0 :                 pTimerData->mbInTimeout = false;
     121             :             }
     122             :         }
     123             : 
     124           0 :         pTimerData = pTimerData->mpNext;
     125             :     }
     126             : 
     127             :     // determine new time
     128           0 :     sal_uLong nNewTime = Time::GetSystemTicks();
     129           0 :     pPrevTimerData = NULL;
     130           0 :     pTimerData = pSVData->mpFirstTimerData;
     131           0 :     while ( pTimerData )
     132             :     {
     133             :         // ignore if timer is still in timeout handler
     134           0 :         if ( pTimerData->mbInTimeout )
     135             :         {
     136           0 :             pPrevTimerData = pTimerData;
     137           0 :             pTimerData = pTimerData->mpNext;
     138             :         }
     139             :         // Was timer destroyed in the meantime?
     140           0 :         else if ( pTimerData->mbDelete )
     141             :         {
     142           0 :             if ( pPrevTimerData )
     143           0 :                 pPrevTimerData->mpNext = pTimerData->mpNext;
     144             :             else
     145           0 :                 pSVData->mpFirstTimerData = pTimerData->mpNext;
     146           0 :             if ( pTimerData->mpTimer )
     147           0 :                 pTimerData->mpTimer->mpTimerData = NULL;
     148           0 :             ImplTimerData* pTempTimerData = pTimerData;
     149           0 :             pTimerData = pTimerData->mpNext;
     150           0 :             delete pTempTimerData;
     151             :         }
     152             :         else
     153             :         {
     154           0 :             pTimerData->mnTimerUpdate = 0;
     155             :             // determine smallest time slot
     156           0 :             if ( pTimerData->mnUpdateTime == nTime )
     157             :             {
     158           0 :                 nDeltaTime = pTimerData->mpTimer->mnTimeout;
     159           0 :                 if ( nDeltaTime < nMinPeriod )
     160           0 :                     nMinPeriod = nDeltaTime;
     161             :             }
     162             :             else
     163             :             {
     164           0 :                 nDeltaTime = pTimerData->mnUpdateTime + pTimerData->mpTimer->mnTimeout;
     165           0 :                 if ( nDeltaTime < nNewTime )
     166           0 :                     nMinPeriod = 1;
     167             :                 else
     168             :                 {
     169           0 :                     nDeltaTime -= nNewTime;
     170           0 :                     if ( nDeltaTime < nMinPeriod )
     171           0 :                         nMinPeriod = nDeltaTime;
     172             :                 }
     173             :             }
     174           0 :             pPrevTimerData = pTimerData;
     175           0 :             pTimerData = pTimerData->mpNext;
     176             :         }
     177             :     }
     178             : 
     179             :     // delete clock if no more timers available
     180           0 :     if ( !pSVData->mpFirstTimerData )
     181             :     {
     182           0 :         pSVData->mpSalTimer->Stop();
     183           0 :         pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
     184             :     }
     185             :     else
     186           0 :         ImplStartTimer( pSVData, nMinPeriod );
     187             : 
     188           0 :     pSVData->mnTimerUpdate--;
     189           0 :     pSVData->mbNotAllTimerCalled = false;
     190             : }
     191             : 
     192           1 : Timer::Timer():
     193             :     mpTimerData(NULL),
     194             :     mnTimeout(1),
     195             :     mbActive(false),
     196           1 :     mbAuto(false)
     197             : {
     198           1 : }
     199             : 
     200           0 : Timer::Timer( const Timer& rTimer ):
     201             :     mpTimerData(NULL),
     202             :     mnTimeout(rTimer.mnTimeout),
     203             :     mbActive(false),
     204             :     mbAuto(false),
     205           0 :     maTimeoutHdl(rTimer.maTimeoutHdl)
     206             : {
     207           0 :     if ( rTimer.IsActive() )
     208           0 :         Start();
     209           0 : }
     210             : 
     211           1 : Timer::~Timer()
     212             : {
     213           1 :     if ( mpTimerData )
     214             :     {
     215           0 :         mpTimerData->mbDelete = true;
     216           0 :         mpTimerData->mpTimer = NULL;
     217             :      }
     218           1 : }
     219             : 
     220           0 : void Timer::Timeout()
     221             : {
     222           0 :     maTimeoutHdl.Call( this );
     223           0 : }
     224             : 
     225           0 : void Timer::SetTimeout( sal_uLong nNewTimeout )
     226             : {
     227           0 :     mnTimeout = nNewTimeout;
     228             : 
     229             :     // if timer is active then renew clock
     230           0 :     if ( mbActive )
     231             :     {
     232           0 :         ImplSVData* pSVData = ImplGetSVData();
     233           0 :         if ( !pSVData->mnTimerUpdate && (mnTimeout < pSVData->mnTimerPeriod) )
     234           0 :             ImplStartTimer( pSVData, mnTimeout );
     235             :     }
     236           0 : }
     237             : 
     238           0 : void Timer::Start()
     239             : {
     240           0 :     mbActive = true;
     241             : 
     242           0 :     ImplSVData* pSVData = ImplGetSVData();
     243           0 :     if ( !mpTimerData )
     244             :     {
     245           0 :         if ( !pSVData->mpFirstTimerData )
     246             :         {
     247           0 :             pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
     248           0 :             if( ! pSVData->mpSalTimer )
     249             :             {
     250           0 :                 pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer();
     251           0 :                 pSVData->mpSalTimer->SetCallback( ImplTimerCallbackProc );
     252             :             }
     253             :         }
     254             : 
     255             :         // insert timer and start
     256           0 :         mpTimerData = new ImplTimerData;
     257           0 :         mpTimerData->mpTimer        = this;
     258           0 :         mpTimerData->mnUpdateTime   = Time::GetSystemTicks();
     259           0 :         mpTimerData->mnTimerUpdate  = pSVData->mnTimerUpdate;
     260           0 :         mpTimerData->mbDelete       = false;
     261           0 :         mpTimerData->mbInTimeout    = false;
     262             : 
     263             :         // insert last due to SFX!
     264           0 :         ImplTimerData* pPrev = NULL;
     265           0 :         ImplTimerData* pData = pSVData->mpFirstTimerData;
     266           0 :         while ( pData )
     267             :         {
     268           0 :             pPrev = pData;
     269           0 :             pData = pData->mpNext;
     270             :         }
     271           0 :         mpTimerData->mpNext = NULL;
     272           0 :         if ( pPrev )
     273           0 :             pPrev->mpNext = mpTimerData;
     274             :         else
     275           0 :             pSVData->mpFirstTimerData = mpTimerData;
     276             : 
     277           0 :         if ( mnTimeout < pSVData->mnTimerPeriod )
     278           0 :             ImplStartTimer( pSVData, mnTimeout );
     279             :     }
     280           0 :     else if( !mpTimerData->mpTimer ) // TODO: remove when guilty found
     281             :     {
     282             :         OSL_FAIL( "Timer::Start() on a destroyed Timer!" );
     283             :     }
     284             :     else
     285             :     {
     286           0 :         mpTimerData->mnUpdateTime    = Time::GetSystemTicks();
     287           0 :         mpTimerData->mnTimerUpdate   = pSVData->mnTimerUpdate;
     288           0 :         mpTimerData->mbDelete        = false;
     289             :     }
     290           0 : }
     291             : 
     292           0 : void Timer::Stop()
     293             : {
     294           0 :     mbActive = false;
     295             : 
     296           0 :     if ( mpTimerData )
     297           0 :         mpTimerData->mbDelete = true;
     298           0 : }
     299             : 
     300           0 : Timer& Timer::operator=( const Timer& rTimer )
     301             : {
     302           0 :     if ( IsActive() )
     303           0 :         Stop();
     304             : 
     305           0 :     mbActive        = false;
     306           0 :     mnTimeout       = rTimer.mnTimeout;
     307           0 :     maTimeoutHdl    = rTimer.maTimeoutHdl;
     308             : 
     309           0 :     if ( rTimer.IsActive() )
     310           0 :         Start();
     311             : 
     312           0 :     return *this;
     313             : }
     314             : 
     315           0 : AutoTimer::AutoTimer()
     316             : {
     317           0 :     mbAuto = true;
     318           0 : }
     319             : 
     320           0 : AutoTimer::AutoTimer( const AutoTimer& rTimer ) : Timer( rTimer )
     321             : {
     322           0 :     mbAuto = true;
     323           0 : }
     324             : 
     325           0 : AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer )
     326             : {
     327           0 :     Timer::operator=( rTimer );
     328           0 :     return *this;
     329             : }
     330             : 
     331             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10