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