1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: timer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
37 #include <vcl/saltimer.hxx>
38 #include <tools/time.hxx>
39 #include <vcl/svdata.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/salinst.hxx>
42 #include <tools/debug.hxx>
43 #include <vcl/timer.hxx>
47 // =======================================================================
49 #define MAX_TIMER_PERIOD ((ULONG)0xFFFFFFFF)
51 // ---------------------
52 // - TimeManager-Types -
53 // ---------------------
57 ImplTimerData
* mpNext
; // Pointer to the next Instance
58 Timer
* mpSVTimer
; // Pointer to SV Timer instance
59 ULONG mnUpdateTime
; // Last Update Time
60 ULONG mnTimerUpdate
; // TimerCallbackProcs on stack
61 BOOL mbDelete
; // Wurde Timer waehren Update() geloescht
62 BOOL mbInTimeout
; // Befinden wir uns im Timeout-Handler
65 // =======================================================================
67 void Timer::ImplDeInitTimer()
69 ImplSVData
* pSVData
= ImplGetSVData();
70 ImplTimerData
* pTimerData
= pSVData
->mpFirstTimerData
;
76 ImplTimerData
* pTempTimerData
= pTimerData
;
77 if ( pTimerData
->mpSVTimer
)
79 pTimerData
->mpSVTimer
->mbActive
= FALSE
;
80 pTimerData
->mpSVTimer
->mpTimerData
= NULL
;
82 pTimerData
= pTimerData
->mpNext
;
83 delete pTempTimerData
;
87 pSVData
->mpFirstTimerData
= NULL
;
88 pSVData
->mnTimerPeriod
= 0;
89 delete pSVData
->mpSalTimer
;
90 pSVData
->mpSalTimer
= NULL
;
94 // -----------------------------------------------------------------------
96 static void ImplStartTimer( ImplSVData
* pSVData
, ULONG nMS
)
101 if ( nMS
!= pSVData
->mnTimerPeriod
)
103 pSVData
->mnTimerPeriod
= nMS
;
104 pSVData
->mpSalTimer
->Start( nMS
);
108 // -----------------------------------------------------------------------
110 void Timer::ImplTimerCallbackProc()
112 ImplSVData
* pSVData
= ImplGetSVData();
113 ImplTimerData
* pTimerData
;
114 ImplTimerData
* pPrevTimerData
;
115 ULONG nMinPeriod
= MAX_TIMER_PERIOD
;
117 ULONG nTime
= Time::GetSystemTicks();
119 if ( pSVData
->mbNoCallTimer
)
122 pSVData
->mnTimerUpdate
++;
123 pSVData
->mbNotAllTimerCalled
= TRUE
;
125 // Suche Timer raus, wo der Timeout-Handler gerufen werden muss
126 pTimerData
= pSVData
->mpFirstTimerData
;
129 // Wenn Timer noch nicht neu ist und noch nicht geloescht wurde
130 // und er sich nicht im Timeout-Handler befindet,
131 // dann den Handler rufen, wenn die Zeit abgelaufen ist
132 if ( (pTimerData
->mnTimerUpdate
< pSVData
->mnTimerUpdate
) &&
133 !pTimerData
->mbDelete
&& !pTimerData
->mbInTimeout
)
136 if ( (pTimerData
->mnUpdateTime
+pTimerData
->mpSVTimer
->mnTimeout
) <= nTime
)
138 // Neue Updatezeit setzen
139 pTimerData
->mnUpdateTime
= nTime
;
141 // kein AutoTimer, dann anhalten
142 if ( !pTimerData
->mpSVTimer
->mbAuto
)
144 pTimerData
->mpSVTimer
->mbActive
= FALSE
;
145 pTimerData
->mbDelete
= TRUE
;
149 pTimerData
->mbInTimeout
= TRUE
;
150 pTimerData
->mpSVTimer
->Timeout();
151 pTimerData
->mbInTimeout
= FALSE
;
155 pTimerData
= pTimerData
->mpNext
;
158 // Neue Zeit ermitteln
159 ULONG nNewTime
= Time::GetSystemTicks();
160 pPrevTimerData
= NULL
;
161 pTimerData
= pSVData
->mpFirstTimerData
;
164 // Befindet sich Timer noch im Timeout-Handler, dann ignorieren
165 if ( pTimerData
->mbInTimeout
)
167 pPrevTimerData
= pTimerData
;
168 pTimerData
= pTimerData
->mpNext
;
170 // Wurde Timer zwischenzeitlich zerstoert ?
171 else if ( pTimerData
->mbDelete
)
173 if ( pPrevTimerData
)
174 pPrevTimerData
->mpNext
= pTimerData
->mpNext
;
176 pSVData
->mpFirstTimerData
= pTimerData
->mpNext
;
177 if ( pTimerData
->mpSVTimer
)
178 pTimerData
->mpSVTimer
->mpTimerData
= NULL
;
179 ImplTimerData
* pTempTimerData
= pTimerData
;
180 pTimerData
= pTimerData
->mpNext
;
181 delete pTempTimerData
;
185 pTimerData
->mnTimerUpdate
= 0;
186 // kleinste Zeitspanne ermitteln
187 if ( pTimerData
->mnUpdateTime
== nTime
)
189 nDeltaTime
= pTimerData
->mpSVTimer
->mnTimeout
;
190 if ( nDeltaTime
< nMinPeriod
)
191 nMinPeriod
= nDeltaTime
;
195 nDeltaTime
= pTimerData
->mnUpdateTime
+ pTimerData
->mpSVTimer
->mnTimeout
;
196 if ( nDeltaTime
< nNewTime
)
200 nDeltaTime
-= nNewTime
;
201 if ( nDeltaTime
< nMinPeriod
)
202 nMinPeriod
= nDeltaTime
;
205 pPrevTimerData
= pTimerData
;
206 pTimerData
= pTimerData
->mpNext
;
210 // Wenn keine Timer mehr existieren, dann Clock loeschen
211 if ( !pSVData
->mpFirstTimerData
)
213 pSVData
->mpSalTimer
->Stop();
214 pSVData
->mnTimerPeriod
= MAX_TIMER_PERIOD
;
217 ImplStartTimer( pSVData
, nMinPeriod
);
219 pSVData
->mnTimerUpdate
--;
220 pSVData
->mbNotAllTimerCalled
= FALSE
;
223 // =======================================================================
233 // -----------------------------------------------------------------------
235 Timer::Timer( const Timer
& rTimer
)
238 mnTimeout
= rTimer
.mnTimeout
;
241 maTimeoutHdl
= rTimer
.maTimeoutHdl
;
243 if ( rTimer
.IsActive() )
247 // -----------------------------------------------------------------------
253 mpTimerData
->mbDelete
= TRUE
;
254 mpTimerData
->mpSVTimer
= NULL
;
258 // -----------------------------------------------------------------------
260 void Timer::Timeout()
262 maTimeoutHdl
.Call( this );
265 // -----------------------------------------------------------------------
267 void Timer::SetTimeout( ULONG nNewTimeout
)
269 mnTimeout
= nNewTimeout
;
271 // Wenn Timer aktiv, dann Clock erneuern
274 ImplSVData
* pSVData
= ImplGetSVData();
275 if ( !pSVData
->mnTimerUpdate
&& (mnTimeout
< pSVData
->mnTimerPeriod
) )
276 ImplStartTimer( pSVData
, mnTimeout
);
280 // -----------------------------------------------------------------------
286 ImplSVData
* pSVData
= ImplGetSVData();
289 if ( !pSVData
->mpFirstTimerData
)
291 pSVData
->mnTimerPeriod
= MAX_TIMER_PERIOD
;
292 if( ! pSVData
->mpSalTimer
)
294 pSVData
->mpSalTimer
= pSVData
->mpDefInst
->CreateSalTimer();
295 pSVData
->mpSalTimer
->SetCallback( ImplTimerCallbackProc
);
299 // insert timer and start
300 mpTimerData
= new ImplTimerData
;
301 mpTimerData
->mpSVTimer
= this;
302 mpTimerData
->mnUpdateTime
= Time::GetSystemTicks();
303 mpTimerData
->mnTimerUpdate
= pSVData
->mnTimerUpdate
;
304 mpTimerData
->mbDelete
= FALSE
;
305 mpTimerData
->mbInTimeout
= FALSE
;
307 // !!!!! Wegen SFX hinten einordnen !!!!!
308 ImplTimerData
* pPrev
= NULL
;
309 ImplTimerData
* pData
= pSVData
->mpFirstTimerData
;
313 pData
= pData
->mpNext
;
315 mpTimerData
->mpNext
= NULL
;
317 pPrev
->mpNext
= mpTimerData
;
319 pSVData
->mpFirstTimerData
= mpTimerData
;
321 if ( mnTimeout
< pSVData
->mnTimerPeriod
)
322 ImplStartTimer( pSVData
, mnTimeout
);
324 else if( !mpTimerData
->mpSVTimer
) // TODO: remove when guilty found
326 DBG_ERROR( "Timer::Start() on a destroyed Timer!" );
330 mpTimerData
->mnUpdateTime
= Time::GetSystemTicks();
331 mpTimerData
->mnTimerUpdate
= pSVData
->mnTimerUpdate
;
332 mpTimerData
->mbDelete
= FALSE
;
336 // -----------------------------------------------------------------------
343 mpTimerData
->mbDelete
= TRUE
;
346 // -----------------------------------------------------------------------
348 Timer
& Timer::operator=( const Timer
& rTimer
)
354 mnTimeout
= rTimer
.mnTimeout
;
355 maTimeoutHdl
= rTimer
.maTimeoutHdl
;
357 if ( rTimer
.IsActive() )
363 // =======================================================================
365 AutoTimer::AutoTimer()
370 // -----------------------------------------------------------------------
372 AutoTimer::AutoTimer( const AutoTimer
& rTimer
) : Timer( rTimer
)
377 // -----------------------------------------------------------------------
379 AutoTimer
& AutoTimer::operator=( const AutoTimer
& rTimer
)
381 Timer::operator=( rTimer
);