2003/12/17 16:03:31 mt 1.3.4.1: #i23061# header cleanup, remove #ifdef ???_CXX and #define ???_CXX, also removed .impl files and fixed soke windows compiler warnings
425 lines
12 KiB
C++
425 lines
12 KiB
C++
/*************************************************************************
|
|
*
|
|
* $RCSfile: timer.cxx,v $
|
|
*
|
|
* $Revision: 1.4 $
|
|
*
|
|
* last change: $Author: vg $ $Date: 2004-01-06 13:15:29 $
|
|
*
|
|
* The Contents of this file are made available subject to the terms of
|
|
* either of the following licenses
|
|
*
|
|
* - GNU Lesser General Public License Version 2.1
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
*
|
|
* Sun Microsystems Inc., October, 2000
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
*
|
|
* Sun Industry Standards Source License Version 1.1
|
|
* =================================================
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
* Source License Version 1.1 (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.openoffice.org/license.html.
|
|
*
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
* See the License for the specific provisions governing your rights and
|
|
* obligations concerning the Software.
|
|
*
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
*
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s): _______________________________________
|
|
*
|
|
*
|
|
************************************************************************/
|
|
|
|
#ifndef _SV_SVSYS_HXX
|
|
#include <svsys.h>
|
|
#endif
|
|
|
|
#ifndef _SV_SALTIMER_HXX
|
|
#include <saltimer.hxx>
|
|
#endif
|
|
|
|
#ifndef _TIME_HXX
|
|
#include <tools/time.hxx>
|
|
#endif
|
|
|
|
#ifndef _SV_SVDATA_HXX
|
|
#include <svdata.hxx>
|
|
#endif
|
|
#ifndef _SV_SVAPP_HXX
|
|
#include <svapp.hxx>
|
|
#endif
|
|
#ifndef _SV_SALINST_HXX
|
|
#include <salinst.hxx>
|
|
#endif
|
|
|
|
#define protected public
|
|
#ifndef _SV_TIMER_HXX
|
|
#include <timer.hxx>
|
|
#endif
|
|
#undef protected
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
#define MAX_TIMER_PERIOD ((ULONG)0xFFFFFFFF)
|
|
|
|
// ---------------------
|
|
// - TimeManager-Types -
|
|
// ---------------------
|
|
|
|
struct ImplTimerData
|
|
{
|
|
ImplTimerData* mpNext; // Pointer to the next Instance
|
|
Timer* mpSVTimer; // Pointer to SV Timer instance
|
|
ULONG mnUpdateTime; // Last Update Time
|
|
ULONG mnTimerUpdate; // TimerCallbackProcs on stack
|
|
BOOL mbDelete; // Wurde Timer waehren Update() geloescht
|
|
BOOL mbInTimeout; // Befinden wir uns im Timeout-Handler
|
|
};
|
|
|
|
// =======================================================================
|
|
|
|
void ImplDeInitTimer()
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
ImplTimerData* pTimerData = pSVData->mpFirstTimerData;
|
|
|
|
if ( pTimerData )
|
|
{
|
|
do
|
|
{
|
|
ImplTimerData* pTempTimerData = pTimerData;
|
|
if ( pTimerData->mpSVTimer )
|
|
{
|
|
pTimerData->mpSVTimer->mbActive = FALSE;
|
|
pTimerData->mpSVTimer->mpTimerData = NULL;
|
|
}
|
|
pTimerData = pTimerData->mpNext;
|
|
delete pTempTimerData;
|
|
}
|
|
while ( pTimerData );
|
|
|
|
pSVData->mpFirstTimerData = NULL;
|
|
pSVData->mnTimerPeriod = 0;
|
|
delete pSVData->mpSalTimer;
|
|
pSVData->mpSalTimer = NULL;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
static void ImplStartTimer( ImplSVData* pSVData, ULONG nMS )
|
|
{
|
|
if ( !nMS )
|
|
nMS = 1;
|
|
|
|
if ( nMS != pSVData->mnTimerPeriod )
|
|
{
|
|
pSVData->mnTimerPeriod = nMS;
|
|
pSVData->mpSalTimer->Start( nMS );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImplTimerCallbackProc()
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
ImplTimerData* pTimerData;
|
|
ImplTimerData* pPrevTimerData;
|
|
ULONG nMinPeriod = MAX_TIMER_PERIOD;
|
|
ULONG nDeltaTime;
|
|
ULONG nTime = Time::GetSystemTicks();
|
|
|
|
if ( pSVData->mbNoCallTimer )
|
|
return;
|
|
|
|
pSVData->mnTimerUpdate++;
|
|
pSVData->mbNotAllTimerCalled = TRUE;
|
|
|
|
// Suche Timer raus, wo der Timeout-Handler gerufen werden muss
|
|
pTimerData = pSVData->mpFirstTimerData;
|
|
while ( pTimerData )
|
|
{
|
|
// Wenn Timer noch nicht neu ist und noch nicht geloescht wurde
|
|
// und er sich nicht im Timeout-Handler befindet,
|
|
// dann den Handler rufen, wenn die Zeit abgelaufen ist
|
|
if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) &&
|
|
!pTimerData->mbDelete && !pTimerData->mbInTimeout )
|
|
{
|
|
// Zeit abgelaufen
|
|
if ( (pTimerData->mnUpdateTime+pTimerData->mpSVTimer->mnTimeout) <= nTime )
|
|
{
|
|
// Neue Updatezeit setzen
|
|
pTimerData->mnUpdateTime = nTime;
|
|
|
|
// kein AutoTimer, dann anhalten
|
|
if ( !pTimerData->mpSVTimer->mbAuto )
|
|
{
|
|
pTimerData->mpSVTimer->mbActive = FALSE;
|
|
pTimerData->mbDelete = TRUE;
|
|
}
|
|
|
|
// call Timeout
|
|
pTimerData->mbInTimeout = TRUE;
|
|
pTimerData->mpSVTimer->Timeout();
|
|
pTimerData->mbInTimeout = FALSE;
|
|
}
|
|
}
|
|
|
|
pTimerData = pTimerData->mpNext;
|
|
}
|
|
|
|
// Neue Zeit ermitteln
|
|
ULONG nNewTime = Time::GetSystemTicks();
|
|
pPrevTimerData = NULL;
|
|
pTimerData = pSVData->mpFirstTimerData;
|
|
while ( pTimerData )
|
|
{
|
|
// Befindet sich Timer noch im Timeout-Handler, dann ignorieren
|
|
if ( pTimerData->mbInTimeout )
|
|
{
|
|
pPrevTimerData = pTimerData;
|
|
pTimerData = pTimerData->mpNext;
|
|
}
|
|
// Wurde Timer zwischenzeitlich zerstoert ?
|
|
else if ( pTimerData->mbDelete )
|
|
{
|
|
if ( pPrevTimerData )
|
|
pPrevTimerData->mpNext = pTimerData->mpNext;
|
|
else
|
|
pSVData->mpFirstTimerData = pTimerData->mpNext;
|
|
if ( pTimerData->mpSVTimer )
|
|
pTimerData->mpSVTimer->mpTimerData = NULL;
|
|
ImplTimerData* pTempTimerData = pTimerData;
|
|
pTimerData = pTimerData->mpNext;
|
|
delete pTempTimerData;
|
|
}
|
|
else
|
|
{
|
|
pTimerData->mnTimerUpdate = 0;
|
|
// kleinste Zeitspanne ermitteln
|
|
if ( pTimerData->mnUpdateTime == nTime )
|
|
{
|
|
nDeltaTime = pTimerData->mpSVTimer->mnTimeout;
|
|
if ( nDeltaTime < nMinPeriod )
|
|
nMinPeriod = nDeltaTime;
|
|
}
|
|
else
|
|
{
|
|
nDeltaTime = pTimerData->mnUpdateTime + pTimerData->mpSVTimer->mnTimeout;
|
|
if ( nDeltaTime < nNewTime )
|
|
nMinPeriod = 1;
|
|
else
|
|
{
|
|
nDeltaTime -= nNewTime;
|
|
if ( nDeltaTime < nMinPeriod )
|
|
nMinPeriod = nDeltaTime;
|
|
}
|
|
}
|
|
pPrevTimerData = pTimerData;
|
|
pTimerData = pTimerData->mpNext;
|
|
}
|
|
}
|
|
|
|
// Wenn keine Timer mehr existieren, dann Clock loeschen
|
|
if ( !pSVData->mpFirstTimerData )
|
|
{
|
|
pSVData->mpSalTimer->Stop();
|
|
pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
|
|
}
|
|
else
|
|
ImplStartTimer( pSVData, nMinPeriod );
|
|
|
|
pSVData->mnTimerUpdate--;
|
|
pSVData->mbNotAllTimerCalled = FALSE;
|
|
}
|
|
|
|
// =======================================================================
|
|
|
|
Timer::Timer()
|
|
{
|
|
mpTimerData = NULL;
|
|
mnTimeout = 1;
|
|
mbAuto = FALSE;
|
|
mbActive = FALSE;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Timer::Timer( const Timer& rTimer )
|
|
{
|
|
mpTimerData = NULL;
|
|
mnTimeout = rTimer.mnTimeout;
|
|
mbAuto = FALSE;
|
|
mbActive = FALSE;
|
|
maTimeoutHdl = rTimer.maTimeoutHdl;
|
|
|
|
if ( rTimer.IsActive() )
|
|
Start();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Timer::~Timer()
|
|
{
|
|
if ( mpTimerData )
|
|
{
|
|
mpTimerData->mbDelete = TRUE;
|
|
mpTimerData->mpSVTimer = NULL;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void Timer::Timeout()
|
|
{
|
|
maTimeoutHdl.Call( this );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void Timer::SetTimeout( ULONG nNewTimeout )
|
|
{
|
|
mnTimeout = nNewTimeout;
|
|
|
|
// Wenn Timer aktiv, dann Clock erneuern
|
|
if ( mbActive )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
if ( !pSVData->mnTimerUpdate && (mnTimeout < pSVData->mnTimerPeriod) )
|
|
ImplStartTimer( pSVData, mnTimeout );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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->mpSVTimer = this;
|
|
mpTimerData->mnUpdateTime = Time::GetSystemTicks();
|
|
mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate;
|
|
mpTimerData->mbDelete = FALSE;
|
|
mpTimerData->mbInTimeout = FALSE;
|
|
|
|
// !!!!! Wegen SFX hinten einordnen !!!!!
|
|
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
|
|
{
|
|
mpTimerData->mnUpdateTime = 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();
|
|
|
|
return *this;
|
|
}
|
|
|
|
// =======================================================================
|
|
|
|
AutoTimer::AutoTimer()
|
|
{
|
|
mbAuto = TRUE;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
AutoTimer::AutoTimer( const AutoTimer& rTimer ) : Timer( rTimer )
|
|
{
|
|
mbAuto = TRUE;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer )
|
|
{
|
|
Timer::operator=( rTimer );
|
|
return *this;
|
|
}
|