include/svx/sdr/animation/scheduler.hxx | 49 +++++++- svx/source/sdr/animation/scheduler.cxx | 182 ++++++++++++++++++++++++-------- 2 files changed, 184 insertions(+), 47 deletions(-)
New commits: commit 0e0e3ea312dc09de6726318c3579671fec7de7ee Author: Caolán McNamara <caol...@redhat.com> Date: Wed Nov 9 10:21:49 2016 +0000 Revert "convert sdr::animation::EventList to o3tl::sorted_vector" This reverts commit c0c69ccd2aac45e4cca0de7d4deaa6d02ec27f4d. because soffice --headless --convert-to odp ooo75571-1.odp crashes after this change diff --git a/include/svx/sdr/animation/scheduler.hxx b/include/svx/sdr/animation/scheduler.hxx index 15eaa34..1d1c16a 100644 --- a/include/svx/sdr/animation/scheduler.hxx +++ b/include/svx/sdr/animation/scheduler.hxx @@ -23,24 +23,31 @@ #include <sal/types.h> #include <vcl/timer.hxx> #include <svx/svxdllapi.h> -#include <o3tl/sorted_vector.hxx> +// event class + namespace sdr { namespace animation { - class SVX_DLLPUBLIC Event { // time of event in ms sal_uInt32 mnTime; + // pointer for linked list sorted by mnTime + Event* mpNext; + public: // constructor/destructor SAL_DLLPRIVATE explicit Event(); virtual ~Event(); + // access to mpNext + SAL_DLLPRIVATE Event* GetNext() const { return mpNext; } + SAL_DLLPRIVATE void SetNext(Event* pNew); + // get/set time SAL_DLLPRIVATE sal_uInt32 GetTime() const { return mnTime; } void SetTime(sal_uInt32 nNew); @@ -48,12 +55,43 @@ namespace sdr // execute event virtual void Trigger(sal_uInt32 nTime) = 0; }; + } // end of namespace animation +} // end of namespace sdr + - struct CompareEvent +// eventlist class + +namespace sdr +{ + namespace animation + { + class SVX_DLLPUBLIC EventList { - bool operator()(Event* const& lhs, Event* const& rhs) const; + // pointer to first entry + Event* mpHead; + + public: + // constructor/destructor + SAL_DLLPRIVATE EventList(); + virtual ~EventList(); + + // insert/remove time dependent + SAL_DLLPRIVATE void Insert(Event* pNew); + SAL_DLLPRIVATE void Remove(Event* pOld); + + // get first + SAL_DLLPRIVATE Event* GetFirst() { return mpHead; } }; + } // end of namespace animation +} // end of namespace sdr + +// scheduler class + +namespace sdr +{ + namespace animation + { class SVX_DLLPUBLIC Scheduler : public Timer { // time in ms @@ -63,7 +101,7 @@ namespace sdr sal_uInt32 mnDeltaTime; // list of events - o3tl::sorted_vector<Event*, CompareEvent> maList; + EventList maList; // Flag which remembers if this timer is paused. Default // is false. @@ -97,7 +135,6 @@ namespace sdr SAL_DLLPRIVATE bool IsPaused() const { return mbIsPaused; } SAL_DLLPRIVATE void SetPaused(bool bNew); }; - } // end of namespace animation } // end of namespace sdr diff --git a/svx/source/sdr/animation/scheduler.cxx b/svx/source/sdr/animation/scheduler.cxx index ea6bb83..3841272 100644 --- a/svx/source/sdr/animation/scheduler.cxx +++ b/svx/source/sdr/animation/scheduler.cxx @@ -28,7 +28,9 @@ namespace sdr { namespace animation { - Event::Event() : mnTime(0) + Event::Event() + : mnTime(0), + mpNext(nullptr) { } @@ -37,6 +39,15 @@ namespace sdr } + void Event::SetNext(Event* pNew) + { + if(pNew != mpNext) + { + mpNext = pNew; + } + } + + void Event::SetTime(sal_uInt32 nNew) { if(mnTime != nNew) @@ -44,13 +55,93 @@ namespace sdr mnTime = nNew; } } + } // end of namespace animation +} // end of namespace sdr + + +// eventlist class - bool CompareEvent::operator()(Event* const& lhs, Event* const& rhs) const +namespace sdr +{ + namespace animation + { + EventList::EventList() + : mpHead(nullptr) { - return lhs->GetTime() < rhs->GetTime(); } + EventList::~EventList() + { + while(mpHead) + { + Event* pNext = mpHead->GetNext(); + mpHead->SetNext(nullptr); + mpHead = pNext; + } + } + + void EventList::Insert(Event* pNew) + { + if(pNew) + { + Event* pCurrent = mpHead; + Event* pPrev = nullptr; + + while(pCurrent && pCurrent->GetTime() < pNew->GetTime()) + { + pPrev = pCurrent; + pCurrent = pCurrent->GetNext(); + } + + if(pPrev) + { + pNew->SetNext(pPrev->GetNext()); + pPrev->SetNext(pNew); + } + else + { + pNew->SetNext(mpHead); + mpHead = pNew; + } + } + } + + void EventList::Remove(Event* pOld) + { + if(pOld && mpHead) + { + Event* pCurrent = mpHead; + Event* pPrev = nullptr; + + while(pCurrent && pCurrent != pOld) + { + pPrev = pCurrent; + pCurrent = pCurrent->GetNext(); + } + + if(pPrev) + { + pPrev->SetNext(pOld->GetNext()); + } + else + { + mpHead = pOld->GetNext(); + } + + pOld->SetNext(nullptr); + } + } + + } // end of namespace animation +} // end of namespace sdr + + +// scheduler class +namespace sdr +{ + namespace animation + { Scheduler::Scheduler() : mnTime(0L), mnDeltaTime(0L), @@ -78,36 +169,38 @@ namespace sdr void Scheduler::triggerEvents() { - if (maList.empty()) - return; + Event* pNextEvent = maList.GetFirst(); - // copy events which need to be executed to a vector. Remove them from - // the scheduler - ::std::vector< Event* > aToBeExecutedList; - - while(!maList.empty() && maList[0]->GetTime() <= mnTime) + if(pNextEvent) { - Event* pNextEvent = maList.front(); - maList.erase(maList.begin()); - aToBeExecutedList.push_back(pNextEvent); - } + // copy events which need to be executed to a vector. Remove them from + // the scheduler + ::std::vector< Event* > EventPointerVector; - // execute events from the vector - ::std::vector< Event* >::const_iterator aEnd = aToBeExecutedList.end(); - for(::std::vector< Event* >::iterator aCandidate = aToBeExecutedList.begin(); - aCandidate != aEnd; ++aCandidate) - { - // trigger event. This may re-insert the event to the scheduler again - (*aCandidate)->Trigger(mnTime); + while(pNextEvent && pNextEvent->GetTime() <= mnTime) + { + maList.Remove(pNextEvent); + EventPointerVector.push_back(pNextEvent); + pNextEvent = maList.GetFirst(); + } + + // execute events from the vector + ::std::vector< Event* >::const_iterator aEnd = EventPointerVector.end(); + for(::std::vector< Event* >::iterator aCandidate = EventPointerVector.begin(); + aCandidate != aEnd; ++aCandidate) + { + // trigger event. This may re-insert the event to the scheduler again + (*aCandidate)->Trigger(mnTime); + } } } void Scheduler::checkTimeout() { // re-start or stop timer according to event list - if(!IsPaused() && !maList.empty()) + if(!IsPaused() && maList.GetFirst()) { - mnDeltaTime = maList.front()->GetTime() - mnTime; + mnDeltaTime = maList.GetFirst()->GetTime() - mnTime; if(0L != mnDeltaTime) { @@ -129,36 +222,43 @@ namespace sdr Stop(); mnTime = nTime; - if (maList.empty()) - return; + // get event pointer + Event* pEvent = maList.GetFirst(); - // reset event time points - for (auto & rEvent : maList) + if(pEvent) { - rEvent->SetTime(nTime); - } + // retet event time points + while(pEvent) + { + pEvent->SetTime(nTime); + pEvent = pEvent->GetNext(); + } - if(!IsPaused()) - { - // without delta time, init events by triggering them. This will invalidate - // painted objects and add them to the scheduler again - mnDeltaTime = 0L; - triggerEvents(); - checkTimeout(); - } + if(!IsPaused()) + { + // without delta time, init events by triggering them. This will invalidate + // painted objects and add them to the scheduler again + mnDeltaTime = 0L; + triggerEvents(); + checkTimeout(); + } + } } void Scheduler::InsertEvent(Event* pNew) { - maList.insert(pNew); - checkTimeout(); + if(pNew) + { + maList.Insert(pNew); + checkTimeout(); + } } void Scheduler::RemoveEvent(Event* pOld) { - if(!maList.empty()) + if(pOld && maList.GetFirst()) { - maList.erase(maList.find(pOld)); + maList.Remove(pOld); checkTimeout(); } }
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits