[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - 2 commits - slideshow/source

Sarper Akdemir (via logerrit) logerrit at kemper.freedesktop.org
Thu Aug 13 03:42:22 UTC 2020


Rebased ref, commits from common ancestor:
commit ca8bc047298e59e598c631d4c93d374793054067
Author:     Sarper Akdemir <q.sarperakdemir at gmail.com>
AuthorDate: Thu Aug 13 03:40:25 2020 +0300
Commit:     Sarper Akdemir <q.sarperakdemir at gmail.com>
CommitDate: Thu Aug 13 06:40:50 2020 +0300

    make physics animations handle sequential animations correctly
    
    Change-Id: Ie8bb8b32588f4c7bf16317b5229adc5b0334d192

diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx
index bc1848f68435..d6198439b327 100644
--- a/slideshow/source/engine/animationfactory.cxx
+++ b/slideshow/source/engine/animationfactory.cxx
@@ -323,7 +323,9 @@ namespace slideshow::internal
                     {
                         mpShapeManager->notifyShapeUpdate( mpShape );
                         if ( mpBox2DWorld->isInitialized() )
-                            mpBox2DWorld->queuePositionUpdate( mpShape->getXShape(), rOutPos );
+                        {
+                            mpBox2DWorld->queueShapePathAnimationUpdate( mpShape->getXShape(), mpAttrLayer );
+                        }
                     }
 
                     return true;
diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx
index 68ab37fb6868..0dbc7be63f2a 100644
--- a/slideshow/source/engine/box2dtools.cxx
+++ b/slideshow/source/engine/box2dtools.cxx
@@ -203,7 +203,8 @@ box2DWorld::box2DWorld(const ::basegfx::B2DVector& rSlideSize)
     , mbShapesInitialized(false)
     , mbHasWorldStepper(false)
     , mpXShapeToBodyMap()
-    , maShapeUpdateQueue()
+    , maShapeParallelUpdateQueue()
+    , maShapeSequentialUpdate()
 {
 }
 
@@ -253,6 +254,13 @@ void box2DWorld::createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlide
     pStaticBody->CreateFixture(&aFixtureDef);
 }
 
+void box2DWorld::setShapePosition(const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
+                                  const basegfx::B2DPoint& rOutPos)
+{
+    Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second;
+    pBox2DBody->setPosition(rOutPos);
+}
+
 void box2DWorld::setShapePositionByLinearVelocity(
     const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
     const basegfx::B2DPoint& rOutPos, const double fPassedTime)
@@ -274,6 +282,13 @@ void box2DWorld::setShapeLinearVelocity(
     pBox2DBody->setLinearVelocity(rVelocity);
 }
 
+void box2DWorld::setShapeAngle(const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
+                               const double fAngle)
+{
+    Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second;
+    pBox2DBody->setAngle(fAngle);
+}
+
 void box2DWorld::setShapeAngleByAngularVelocity(
     const css::uno::Reference<com::sun::star::drawing::XShape> xShape, const double fAngle,
     const double fPassedTime)
@@ -305,41 +320,75 @@ void box2DWorld::setShapeCollision(
 
 void box2DWorld::processUpdateQueue(const double fPassedTime)
 {
-    while (!maShapeUpdateQueue.empty())
+    if (maShapeSequentialUpdate.empty())
     {
-        Box2DShapeUpdateInformation& aQueueElement = maShapeUpdateQueue.front();
-
-        if (aQueueElement.mnDelayForSteps > 0)
+        while (!maShapeParallelUpdateQueue.empty())
         {
-            // it was queued as a delayed action, skip it, don't pop
-            aQueueElement.mnDelayForSteps--;
+            Box2DDynamicUpdateInformation& aQueueElement = maShapeParallelUpdateQueue.front();
+
+            if (aQueueElement.mnDelayForSteps > 0)
+            {
+                // it was queued as a delayed action, skip it, don't pop
+                aQueueElement.mnDelayForSteps--;
+            }
+            else
+            {
+                switch (aQueueElement.meUpdateType)
+                {
+                    default:
+                    case BOX2D_UPDATE_POSITION:
+                        setShapePositionByLinearVelocity(aQueueElement.mxShape,
+                                                         aQueueElement.maPosition, fPassedTime);
+                        break;
+                    case BOX2D_UPDATE_ANGLE:
+                        setShapeAngleByAngularVelocity(aQueueElement.mxShape, aQueueElement.mfAngle,
+                                                       fPassedTime);
+                        break;
+                    case BOX2D_UPDATE_SIZE:
+                        break;
+                    case BOX2D_UPDATE_VISIBILITY:
+                        setShapeCollision(aQueueElement.mxShape, aQueueElement.mbVisibility);
+                        break;
+                    case BOX2D_UPDATE_LINEAR_VELOCITY:
+                        setShapeLinearVelocity(aQueueElement.mxShape, aQueueElement.maVelocity);
+                        break;
+                    case BOX2D_UPDATE_ANGULAR_VELOCITY:
+                        setShapeAngularVelocity(aQueueElement.mxShape,
+                                                aQueueElement.mfAngularVelocity);
+                }
+                maShapeParallelUpdateQueue.pop();
+            }
         }
-        else
+    }
+    else
+    {
+        // clear the Parallel Update Queue since the updates in it
+        // are not relevant now - if there's any
+        maShapeParallelUpdateQueue = {};
+
+        for (auto aIt : maShapeSequentialUpdate)
         {
-            switch (aQueueElement.meUpdateType)
+            css::uno::Reference<css::drawing::XShape> xShape = aIt.first.first;
+            box2DNonsimulatedShapeUpdateType eUpdateType = aIt.first.second;
+            Box2DStaticUpdateInformation& aUpdateInformation = aIt.second;
+
+            switch (eUpdateType)
             {
                 default:
                 case BOX2D_UPDATE_POSITION:
-                    setShapePositionByLinearVelocity(aQueueElement.mxShape,
-                                                     aQueueElement.maPosition, fPassedTime);
+                    setShapePosition(xShape, aUpdateInformation.maPosition);
                     break;
                 case BOX2D_UPDATE_ANGLE:
-                    setShapeAngleByAngularVelocity(aQueueElement.mxShape, aQueueElement.mfAngle,
-                                                   fPassedTime);
-                    break;
-                case BOX2D_UPDATE_SIZE:
+                    setShapeAngle(xShape, aUpdateInformation.mfAngle);
                     break;
                 case BOX2D_UPDATE_VISIBILITY:
-                    setShapeCollision(aQueueElement.mxShape, aQueueElement.mbVisibility);
-                    break;
-                case BOX2D_UPDATE_LINEAR_VELOCITY:
-                    setShapeLinearVelocity(aQueueElement.mxShape, aQueueElement.maVelocity);
+                    setShapeCollision(xShape, aUpdateInformation.mbVisibility);
                     break;
-                case BOX2D_UPDATE_ANGULAR_VELOCITY:
-                    setShapeAngularVelocity(aQueueElement.mxShape, aQueueElement.mfAngularVelocity);
             }
-            maShapeUpdateQueue.pop();
         }
+
+        // After applying all required updates empty map
+        maShapeSequentialUpdate.clear();
     }
 }
 
@@ -376,47 +425,58 @@ void box2DWorld::setHasWorldStepper(const bool bHasWorldStepper)
     mbHasWorldStepper = bHasWorldStepper;
 }
 
-void box2DWorld::queuePositionUpdate(
+void box2DWorld::queueDynamicPositionUpdate(
     const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
     const basegfx::B2DPoint& rOutPos)
 {
-    Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_POSITION };
+    Box2DDynamicUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_POSITION };
     aQueueElement.maPosition = rOutPos;
-    maShapeUpdateQueue.push(aQueueElement);
+    maShapeParallelUpdateQueue.push(aQueueElement);
 }
 
 void box2DWorld::queueLinearVelocityUpdate(
     const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
-    const basegfx::B2DVector& rVelocity)
+    const basegfx::B2DVector& rVelocity, const int nDelayForSteps)
 {
-    Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_LINEAR_VELOCITY, 1 };
+    Box2DDynamicUpdateInformation aQueueElement
+        = { xShape, {}, BOX2D_UPDATE_LINEAR_VELOCITY, nDelayForSteps };
     aQueueElement.maVelocity = rVelocity;
-    maShapeUpdateQueue.push(aQueueElement);
+    maShapeParallelUpdateQueue.push(aQueueElement);
 }
 
-void box2DWorld::queueRotationUpdate(
+void box2DWorld::queueDynamicRotationUpdate(
     const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, const double fAngle)
 {
-    Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_ANGLE };
+    Box2DDynamicUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_ANGLE };
     aQueueElement.mfAngle = fAngle;
-    maShapeUpdateQueue.push(aQueueElement);
+    maShapeParallelUpdateQueue.push(aQueueElement);
 }
 
 void box2DWorld::queueAngularVelocityUpdate(
     const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
-    const double fAngularVelocity)
+    const double fAngularVelocity, const int nDelayForSteps)
 {
-    Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_ANGULAR_VELOCITY, 1 };
+    Box2DDynamicUpdateInformation aQueueElement
+        = { xShape, {}, BOX2D_UPDATE_ANGULAR_VELOCITY, nDelayForSteps };
     aQueueElement.mfAngularVelocity = fAngularVelocity;
-    maShapeUpdateQueue.push(aQueueElement);
+    maShapeParallelUpdateQueue.push(aQueueElement);
 }
 
 void box2DWorld::queueShapeVisibilityUpdate(
     const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, const bool bVisibility)
 {
-    Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_VISIBILITY };
+    Box2DDynamicUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_VISIBILITY };
     aQueueElement.mbVisibility = bVisibility;
-    maShapeUpdateQueue.push(aQueueElement);
+    maShapeParallelUpdateQueue.push(aQueueElement);
+}
+
+void box2DWorld::queueShapePathAnimationUpdate(
+    const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
+    const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer)
+{
+    // Workaround for PathAnimations since they do not have their own AttributeType
+    // - using PosX makes it register a DynamicPositionUpdate -
+    queueShapeAnimationUpdate(xShape, pAttrLayer, slideshow::internal::AttributeType::PosX);
 }
 
 void box2DWorld::queueShapeAnimationUpdate(
@@ -424,20 +484,50 @@ void box2DWorld::queueShapeAnimationUpdate(
     const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer,
     const slideshow::internal::AttributeType eAttrType)
 {
-    switch (eAttrType)
+    if (mbHasWorldStepper) // if there's a physics animation going on
     {
-        case slideshow::internal::AttributeType::Visibility:
-            queueShapeVisibilityUpdate(xShape, pAttrLayer->getVisibility());
-            return;
-        case slideshow::internal::AttributeType::Rotate:
-            queueRotationUpdate(xShape, pAttrLayer->getRotationAngle());
-            return;
-        case slideshow::internal::AttributeType::PosX:
-        case slideshow::internal::AttributeType::PosY:
-            queuePositionUpdate(xShape, { pAttrLayer->getPosX(), pAttrLayer->getPosY() });
-            return;
-        default:
-            return;
+        switch (eAttrType)
+        {
+            case slideshow::internal::AttributeType::Visibility:
+                queueShapeVisibilityUpdate(xShape, pAttrLayer->getVisibility());
+                return;
+            case slideshow::internal::AttributeType::Rotate:
+                queueDynamicRotationUpdate(xShape, pAttrLayer->getRotationAngle());
+                return;
+            case slideshow::internal::AttributeType::PosX:
+            case slideshow::internal::AttributeType::PosY:
+                queueDynamicPositionUpdate(xShape,
+                                           { pAttrLayer->getPosX(), pAttrLayer->getPosY() });
+                return;
+            default:
+                return;
+        }
+    }
+    else
+    {
+        Box2DStaticUpdateInformation aStaticUpdateInformation;
+        switch (eAttrType)
+        {
+            case slideshow::internal::AttributeType::Visibility:
+                aStaticUpdateInformation.mbVisibility = pAttrLayer->getVisibility();
+                maShapeSequentialUpdate[std::make_pair(xShape, BOX2D_UPDATE_VISIBILITY)]
+                    = aStaticUpdateInformation;
+                return;
+            case slideshow::internal::AttributeType::Rotate:
+                aStaticUpdateInformation.mfAngle = pAttrLayer->getRotationAngle();
+                maShapeSequentialUpdate[std::make_pair(xShape, BOX2D_UPDATE_ANGLE)]
+                    = aStaticUpdateInformation;
+                return;
+            case slideshow::internal::AttributeType::PosX:
+            case slideshow::internal::AttributeType::PosY:
+                aStaticUpdateInformation.maPosition
+                    = basegfx::B2DPoint(pAttrLayer->getPosX(), pAttrLayer->getPosY());
+                maShapeSequentialUpdate[std::make_pair(xShape, BOX2D_UPDATE_POSITION)]
+                    = aStaticUpdateInformation;
+                return;
+            default:
+                return;
+        }
     }
 }
 
@@ -448,11 +538,11 @@ void box2DWorld::queueShapeAnimationEndUpdate(
     switch (eAttrType)
     {
         case slideshow::internal::AttributeType::Rotate:
-            queueAngularVelocityUpdate(xShape, 0.0f);
+            queueAngularVelocityUpdate(xShape, 0.0, 1);
             return;
         case slideshow::internal::AttributeType::PosX:
         case slideshow::internal::AttributeType::PosY:
-            queueLinearVelocityUpdate(xShape, { 0, 0 });
+            queueLinearVelocityUpdate(xShape, { 0, 0 }, 1);
             return;
         default:
             return;
@@ -617,6 +707,12 @@ box2DBody::box2DBody(std::shared_ptr<b2Body> pBox2DBody, double fScaleFactor)
     return ::basegfx::B2DPoint(fX, fY);
 }
 
+void box2DBody::setPosition(const basegfx::B2DPoint& rPos)
+{
+    mpBox2DBody->SetTransform(convertB2DPointToBox2DVec2(rPos, mfScaleFactor),
+                              mpBox2DBody->GetAngle());
+}
+
 void box2DBody::setPositionByLinearVelocity(const basegfx::B2DPoint& rDesiredPos,
                                             const double fPassedTime)
 {
@@ -675,6 +771,11 @@ double box2DBody::getAngle()
     return ::basegfx::rad2deg(-fAngle);
 }
 
+void box2DBody::setAngle(double fAngle)
+{
+    mpBox2DBody->SetTransform(mpBox2DBody->GetPosition(), ::basegfx::deg2rad(-fAngle));
+}
+
 void box2DBody::setType(box2DBodyType eType)
 {
     mpBox2DBody->SetType(getBox2DInternalBodyType(eType));
diff --git a/slideshow/source/inc/box2dtools.hxx b/slideshow/source/inc/box2dtools.hxx
index 7f01f09eb607..e5d9c94577e5 100644
--- a/slideshow/source/inc/box2dtools.hxx
+++ b/slideshow/source/inc/box2dtools.hxx
@@ -12,6 +12,7 @@
 #include "shape.hxx"
 #include "shapeattributelayer.hxx"
 #include "attributemap.hxx"
+#include <map>
 #include <unordered_map>
 #include <queue>
 
@@ -50,7 +51,7 @@ enum box2DNonsimulatedShapeUpdateType
 
 /// Holds required information to perform an update to box2d
 /// body of a shape that was altered by an animation effect
-struct Box2DShapeUpdateInformation
+struct Box2DDynamicUpdateInformation
 {
     css::uno::Reference<css::drawing::XShape> mxShape;
     union {
@@ -64,6 +65,13 @@ struct Box2DShapeUpdateInformation
     int mnDelayForSteps = 0;
 };
 
+union Box2DStaticUpdateInformation {
+    ::basegfx::B2DPoint maPosition;
+    bool mbVisibility;
+    double mfAngle;
+    Box2DStaticUpdateInformation() {}
+};
+
 /** Class that manages the Box2D World
 
     This class is used when there's a simulated animation going on,
@@ -78,15 +86,25 @@ private:
     /// Scale factor for conversions between LO user space coordinates to Box2D World coordinates
     double mfScaleFactor;
     bool mbShapesInitialized;
+    /// Holds whether or not there is a Physics Animation node that
+    /// is stepping the Box2D World
     bool mbHasWorldStepper;
     std::unordered_map<css::uno::Reference<css::drawing::XShape>, Box2DBodySharedPtr>
         mpXShapeToBodyMap;
     /// Holds any information needed to keep LO animations and Box2D world in sync
-    std::queue<Box2DShapeUpdateInformation> maShapeUpdateQueue;
+    /// if they are ongoing on parallel
+    std::queue<Box2DDynamicUpdateInformation> maShapeParallelUpdateQueue;
+    /// Holds necessary information if a shape was altered by an animation update
+    /// while there was no Physics animation going on in parallel
+    std::map<std::pair<css::uno::Reference<css::drawing::XShape>, box2DNonsimulatedShapeUpdateType>,
+             Box2DStaticUpdateInformation>
+        maShapeSequentialUpdate;
 
     /// Creates a static frame in Box2D world that corresponds to the slide borders
     void createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlideSize);
 
+    void setShapePosition(const css::uno::Reference<css::drawing::XShape> xShape,
+                          const ::basegfx::B2DPoint& rOutPos);
     /** Sets shape's corresponding Box2D body to specified position
 
         Sets shape's corresponding Box2D body to specified position as if
@@ -108,6 +126,8 @@ private:
     void setShapeLinearVelocity(const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
                                 const basegfx::B2DVector& rVelocity);
 
+    void setShapeAngle(const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
+                       const double fAngle);
     /** Sets shape's corresponding Box2D body to specified angle
 
         Sets shape's corresponding Box2D body to specified angle as if
@@ -157,14 +177,15 @@ private:
               const int nPositionIterations = 2);
 
     /// Queue a rotation update on the next step of the box2DWorld for the corresponding body
-    void queueRotationUpdate(const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
-                             const double fAngle);
+    void
+    queueDynamicRotationUpdate(const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
+                               const double fAngle);
 
     /// Queue an angular velocity update for the corresponding body
     /// to take place after the next step of the box2DWorld
     void
     queueAngularVelocityUpdate(const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
-                               const double fAngularVelocity);
+                               const double fAngularVelocity, const int nDelayForSteps = 0);
 
     /// Queue an update that changes collision of the corresponding body
     /// on the next step of the box2DWorld, used for animations that change visibility
@@ -244,19 +265,24 @@ public:
     void setHasWorldStepper(const bool bHasWorldStepper);
 
     /// Queue a position update the next step of the box2DWorld for the corresponding body
-    void queuePositionUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
-                             const ::basegfx::B2DPoint& rOutPos);
+    void queueDynamicPositionUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
+                                    const ::basegfx::B2DPoint& rOutPos);
 
     /// Queue a linear velocity update for the corresponding body
     /// to take place after the next step of the box2DWorld
     void queueLinearVelocityUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
-                                   const ::basegfx::B2DVector& rVelocity);
+                                   const ::basegfx::B2DVector& rVelocity,
+                                   const int nDelayForSteps = 0);
 
     void
     queueShapeAnimationUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
                               const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer,
                               const slideshow::internal::AttributeType eAttrType);
 
+    void queueShapePathAnimationUpdate(
+        const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
+        const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer);
+
     void queueShapeAnimationEndUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
                                       const slideshow::internal::AttributeType eAttrType);
 };
@@ -276,6 +302,8 @@ public:
     /// @return current position in LO user space coordinates
     ::basegfx::B2DPoint getPosition();
 
+    void setPosition(const ::basegfx::B2DPoint& rPos);
+
     /** Sets body to specified position
 
         Sets body to specified position as if the body had
@@ -315,6 +343,8 @@ public:
     /// @return current angle of rotation of the body
     double getAngle();
 
+    void setAngle(double fAngle);
+
     /// Set type of the body
     void setType(box2DBodyType eType);
 
commit 3da099c53bac119c8e9542d83891afa10e759d0f
Author:     Sarper Akdemir <q.sarperakdemir at gmail.com>
AuthorDate: Thu Aug 6 10:32:55 2020 +0300
Commit:     Sarper Akdemir <q.sarperakdemir at gmail.com>
CommitDate: Thu Aug 13 06:40:49 2020 +0300

    make physics based animation effects always processed last
    
    Change-Id: I92d436aced6ef3ee2c8b0bf0167c1f7e642ba3b5

diff --git a/slideshow/source/engine/activitiesqueue.cxx b/slideshow/source/engine/activitiesqueue.cxx
index ba982385356e..38825c6b5f06 100644
--- a/slideshow/source/engine/activitiesqueue.cxx
+++ b/slideshow/source/engine/activitiesqueue.cxx
@@ -50,6 +50,8 @@ namespace slideshow::internal
             {
                 for( const auto& pActivity : maCurrentActivitiesWaiting )
                     pActivity->dispose();
+                for( const auto& pActivity : maCurrentActivitiesToBeProcessedLast )
+                    pActivity->dispose();
                 for( const auto& pActivity : maCurrentActivitiesReinsert )
                     pActivity->dispose();
             }
@@ -59,7 +61,7 @@ namespace slideshow::internal
             }
         }
 
-        bool ActivitiesQueue::addActivity( const ActivitySharedPtr& pActivity )
+        bool ActivitiesQueue::addActivity( const ActivitySharedPtr& pActivity, const bool bProcessLast )
         {
             OSL_ENSURE( pActivity, "ActivitiesQueue::addActivity: activity ptr NULL" );
 
@@ -67,7 +69,17 @@ namespace slideshow::internal
                 return false;
 
             // add entry to waiting list
-            maCurrentActivitiesWaiting.push_back( pActivity );
+            if( !bProcessLast )
+            {
+                maCurrentActivitiesWaiting.push_back( pActivity );
+            }
+            else
+            {
+                // Activities that should be processed last are kept in a different
+                // ActivityQueue, and later appended to the end of the maCurrentActivitiesWaiting
+                // on the beginning of ActivitiesQueue::process()
+                maCurrentActivitiesToBeProcessedLast.push_back( pActivity );
+            }
 
             return true;
         }
@@ -76,6 +88,12 @@ namespace slideshow::internal
         {
             SAL_INFO("slideshow.verbose", "ActivitiesQueue: outer loop heartbeat" );
 
+            // If there are activities to be processed last append them to the end of the ActivitiesQueue
+            maCurrentActivitiesWaiting.insert( maCurrentActivitiesWaiting.end(),
+                                               maCurrentActivitiesToBeProcessedLast.begin(),
+                                               maCurrentActivitiesToBeProcessedLast.end() );
+            maCurrentActivitiesToBeProcessedLast.clear();
+
             // accumulate time lag for all activities, and lag time
             // base if necessary:
             double fLag = 0.0;
diff --git a/slideshow/source/engine/animationnodes/animationbasenode.cxx b/slideshow/source/engine/animationnodes/animationbasenode.cxx
index 4dcb640795aa..7999b5a7654a 100644
--- a/slideshow/source/engine/animationnodes/animationbasenode.cxx
+++ b/slideshow/source/engine/animationnodes/animationbasenode.cxx
@@ -23,6 +23,7 @@
 #include <com/sun/star/animations/Timing.hpp>
 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
+#include <com/sun/star/animations/AnimationNodeType.hpp>
 
 #include "nodetools.hxx"
 #include <doctreenode.hxx>
@@ -294,7 +295,10 @@ void AnimationBaseNode::activate_st()
         mpActivity->setTargets( getShape(), maAttributeLayerHolder.get() );
 
         // add to activities queue
-        getContext().mrActivitiesQueue.addActivity( mpActivity );
+        if( mxAnimateNode->getType() == css::animations::AnimationNodeType::ANIMATEPHYSICS )
+            getContext().mrActivitiesQueue.addActivity(mpActivity, true);
+        else
+            getContext().mrActivitiesQueue.addActivity( mpActivity );
     }
     else {
         // Actually, DO generate the event for empty activity,
diff --git a/slideshow/source/inc/activitiesqueue.hxx b/slideshow/source/inc/activitiesqueue.hxx
index b4f88b1b39d1..fff8b67bd779 100644
--- a/slideshow/source/inc/activitiesqueue.hxx
+++ b/slideshow/source/inc/activitiesqueue.hxx
@@ -57,7 +57,7 @@ namespace slideshow
 
             /** Add the given activity to the queue.
              */
-            bool addActivity( const ActivitySharedPtr& pActivity );
+            bool addActivity( const ActivitySharedPtr& pActivity, const bool bProcessLast = false );
 
             /** Process the activities queue.
 
@@ -96,6 +96,9 @@ namespace slideshow
                                                                  // await processing for this
                                                                  // round
 
+            ActivityQueue           maCurrentActivitiesToBeProcessedLast; // activities that will be
+                                                                          // processed last in the queue
+
             ActivityQueue           maCurrentActivitiesReinsert;    // currently running
                                                                       // activities, that are
                                                                       // already processed for


More information about the Libreoffice-commits mailing list