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