[Libreoffice-commits] core.git: include/svx svx/source

Caolán McNamara caolanm at redhat.com
Wed Nov 9 10:29:19 UTC 2016


 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 <caolanm at 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();
             }
         }


More information about the Libreoffice-commits mailing list