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