xref: /trunk/main/svx/source/sdr/animation/scheduler.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include <svx/sdr/animation/scheduler.hxx>
31 
32 #include <vector>
33 
34 //////////////////////////////////////////////////////////////////////////////
35 // event class
36 
37 namespace sdr
38 {
39     namespace animation
40     {
41         Event::Event(sal_uInt32 nTime)
42         :   mnTime(nTime),
43             mpNext(0L)
44         {
45         }
46 
47         Event::~Event()
48         {
49         }
50 
51         Event* Event::GetNext() const
52         {
53             return mpNext;
54         }
55 
56         void Event::SetNext(Event* pNew)
57         {
58             if(pNew != mpNext)
59             {
60                 mpNext = pNew;
61             }
62         }
63 
64         sal_uInt32 Event::GetTime() const
65         {
66             return mnTime;
67         }
68 
69         void Event::SetTime(sal_uInt32 nNew)
70         {
71             if(mnTime != nNew)
72             {
73                 mnTime = nNew;
74             }
75         }
76     } // end of namespace animation
77 } // end of namespace sdr
78 
79 //////////////////////////////////////////////////////////////////////////////
80 // eventlist class
81 
82 namespace sdr
83 {
84     namespace animation
85     {
86         EventList::EventList()
87         :   mpHead(0L)
88         {
89         }
90 
91         EventList::~EventList()
92         {
93             Clear();
94         }
95 
96         void EventList::Insert(Event* pNew)
97         {
98             if(pNew)
99             {
100                 Event* pCurrent = mpHead;
101                 Event* pPrev = 0L;
102 
103                 while(pCurrent && pCurrent->GetTime() < pNew->GetTime())
104                 {
105                     pPrev = pCurrent;
106                     pCurrent = pCurrent->GetNext();
107                 }
108 
109                 if(pPrev)
110                 {
111                     pNew->SetNext(pPrev->GetNext());
112                     pPrev->SetNext(pNew);
113                 }
114                 else
115                 {
116                     pNew->SetNext(mpHead);
117                     mpHead = pNew;
118                 }
119             }
120         }
121 
122         void EventList::Remove(Event* pOld)
123         {
124             if(pOld && mpHead)
125             {
126                 Event* pCurrent = mpHead;
127                 Event* pPrev = 0L;
128 
129                 while(pCurrent && pCurrent != pOld)
130                 {
131                     pPrev = pCurrent;
132                     pCurrent = pCurrent->GetNext();
133                 }
134 
135                 if(pPrev)
136                 {
137                     pPrev->SetNext(pOld->GetNext());
138                 }
139                 else
140                 {
141                     mpHead = pOld->GetNext();
142                 }
143 
144                 pOld->SetNext(0L);
145             }
146         }
147 
148         void EventList::Clear()
149         {
150             while(mpHead)
151             {
152                 Event* pNext = mpHead->GetNext();
153                 mpHead->SetNext(0L);
154                 mpHead = pNext;
155             }
156         }
157 
158         Event* EventList::GetFirst()
159         {
160             return mpHead;
161         }
162     } // end of namespace animation
163 } // end of namespace sdr
164 
165 //////////////////////////////////////////////////////////////////////////////
166 // scheduler class
167 
168 namespace sdr
169 {
170     namespace animation
171     {
172         Scheduler::Scheduler()
173         :   mnTime(0L),
174             mnDeltaTime(0L),
175             mbIsPaused(false)
176         {
177         }
178 
179         Scheduler::~Scheduler()
180         {
181             Stop();
182         }
183 
184         void Scheduler::Timeout()
185         {
186             // stop timer and add time
187             Stop();
188             mnTime += mnDeltaTime;
189 
190             // execute events
191             triggerEvents();
192 
193             // re-start or stop timer according to event list
194             checkTimeout();
195         }
196 
197         void Scheduler::triggerEvents()
198         {
199             Event* pNextEvent = maList.GetFirst();
200 
201             if(pNextEvent)
202             {
203                 // copy events which need to be executed to a vector. Remove them from
204                 // the scheduler
205                 ::std::vector< Event* > EventPointerVector;
206 
207                 while(pNextEvent && pNextEvent->GetTime() <= mnTime)
208                 {
209                     maList.Remove(pNextEvent);
210                     EventPointerVector.push_back(pNextEvent);
211                     pNextEvent = maList.GetFirst();
212                 }
213 
214                 // execute events from the vector
215                 for(::std::vector< Event* >::iterator aCandidate = EventPointerVector.begin();
216                     aCandidate != EventPointerVector.end(); aCandidate++)
217                 {
218                     // trigger event. This may re-insert the event to the scheduler again
219                     (*aCandidate)->Trigger(mnTime);
220                 }
221             }
222         }
223 
224         void Scheduler::checkTimeout()
225         {
226             // re-start or stop timer according to event list
227             if(!IsPaused() && maList.GetFirst())
228             {
229                 mnDeltaTime = maList.GetFirst()->GetTime() - mnTime;
230 
231                 if(0L != mnDeltaTime)
232                 {
233                     SetTimeout(mnDeltaTime);
234                     Start();
235                 }
236             }
237             else
238             {
239                 Stop();
240             }
241         }
242 
243         sal_uInt32 Scheduler::GetTime()
244         {
245             return mnTime;
246         }
247 
248         // #i38135#
249         void Scheduler::SetTime(sal_uInt32 nTime)
250         {
251             // reset time
252             Stop();
253             mnTime = nTime;
254 
255             // get event pointer
256             Event* pEvent = maList.GetFirst();
257 
258             if(pEvent)
259             {
260                 // retet event time points
261                 while(pEvent)
262                 {
263                     pEvent->SetTime(nTime);
264                     pEvent = pEvent->GetNext();
265                 }
266 
267                 if(!IsPaused())
268                 {
269                     // without delta time, init events by triggering them. This will invalidate
270                     // painted objects and add them to the scheduler again
271                     mnDeltaTime = 0L;
272                     triggerEvents();
273                     checkTimeout();
274                 }
275             }
276         }
277 
278         void Scheduler::Reset(sal_uInt32 nTime)
279         {
280             mnTime = nTime;
281             mnDeltaTime = 0L;
282             maList.Clear();
283         }
284 
285         void Scheduler::InsertEvent(Event* pNew)
286         {
287             if(pNew)
288             {
289                 maList.Insert(pNew);
290                 checkTimeout();
291             }
292         }
293 
294         void Scheduler::RemoveEvent(Event* pOld)
295         {
296             if(pOld && maList.GetFirst())
297             {
298                 maList.Remove(pOld);
299                 checkTimeout();
300             }
301         }
302 
303         void Scheduler::SetPaused(bool bNew)
304         {
305             if(bNew != mbIsPaused)
306             {
307                 mbIsPaused = bNew;
308                 checkTimeout();
309             }
310         }
311     } // end of namespace animation
312 } // end of namespace sdr
313 
314 //////////////////////////////////////////////////////////////////////////////
315 // eof
316