[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.0' - desktop/inc desktop/source

Ashod Nakashian ashod.nakashian at collabora.co.uk
Wed Apr 20 03:30:37 UTC 2016


 desktop/inc/lib/init.hxx                     |   95 +++++++++++++++++++++++++--
 desktop/source/lib/init.cxx                  |   35 ++++-----
 desktop/source/lib/lokinteractionhandler.cxx |    4 -
 3 files changed, 107 insertions(+), 27 deletions(-)

New commits:
commit e6a429770bde5da75239961ae88c06c78cfa5686
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Tue Apr 19 21:26:42 2016 -0400

    New LOKDocument callback queue to flush certain events lazily on idle
    
    Change-Id: I36834d6139b5feb0bab2a40c55b379b6f281d45d
    Reviewed-on: https://gerrit.libreoffice.org/24252
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index b836052..f65c216 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -6,14 +6,19 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
+
+#include <map>
+#include <mutex>
+
+#include <boost/shared_ptr.hpp>
+
+#include <osl/thread.h>
+#include <vcl/idle.hxx>
 #include <LibreOfficeKit/LibreOfficeKit.h>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <com/sun/star/frame/XStorable.hpp>
 #include <com/sun/star/lang/XComponent.hpp>
-#include <boost/shared_ptr.hpp>
-#include <map>
 #include "../../source/inc/desktopdllapi.h"
-#include <osl/thread.h>
 
 using namespace css;
 using namespace boost;
@@ -21,12 +26,92 @@ using namespace boost;
 class LOKInteractionHandler;
 
 namespace desktop {
+
+    class CallbackFlushHandler : public Idle
+    {
+    public:
+        explicit CallbackFlushHandler(LibreOfficeKitCallback pCallback, void* pData)
+            : Idle( "lokit idle callback" ),
+              m_pCallback(pCallback),
+              m_pData(pData)
+        {
+            SetPriority(SchedulerPriority::POST_PAINT);
+        }
+
+        virtual ~CallbackFlushHandler()
+        {
+            Stop();
+
+            // Wait for Invoke to finish, if called.
+            std::unique_lock<std::mutex> lock(m_mutex);
+        }
+
+        virtual void Invoke() override
+        {
+            std::unique_lock<std::mutex> lock(m_mutex);
+            flush();
+        }
+
+        static
+        void callback(const int type, const char* payload, void* data)
+        {
+            CallbackFlushHandler* self = reinterpret_cast<CallbackFlushHandler*>(data);
+            if (self)
+            {
+                self->queue(type, payload);
+            }
+        }
+
+        void queue(const int type, const char* payload)
+        {
+            std::unique_lock<std::mutex> lock(m_mutex);
+
+            // TODO: Add more state tracking and prune superfluous notifications.
+            if (type == LOK_CALLBACK_INVALIDATE_TILES || type == LOK_CALLBACK_TEXT_SELECTION)
+            {
+                if (m_queue.empty() || std::get<0>(m_queue.back()) != type)
+                {
+                    m_queue.emplace_back(type, std::string(payload ? payload : "(nil)"));
+
+                    if (!IsActive())
+                    {
+                        Start();
+                    }
+                }
+            }
+            else
+            {
+                m_queue.emplace_back(type, std::string(payload ? payload : "(nil)"));
+                flush();
+            }
+        }
+
+    private:
+        void flush()
+        {
+            if (m_pCallback)
+            {
+                for (auto& pair : m_queue)
+                {
+                    m_pCallback(std::get<0>(pair), std::get<1>(pair).c_str(), m_pData);
+                }
+            }
+
+            m_queue.clear();
+        }
+
+    private:
+        std::vector<std::tuple<int, std::string>> m_queue;
+        LibreOfficeKitCallback m_pCallback;
+        void *m_pData;
+        std::mutex m_mutex;
+    };
+
     struct DESKTOP_DLLPUBLIC LibLODocument_Impl : public _LibreOfficeKitDocument
     {
         uno::Reference<css::lang::XComponent> mxComponent;
         shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass;
-        LibreOfficeKitCallback mpCallback;
-        void *mpCallbackData;
+        shared_ptr<CallbackFlushHandler> mpCallbackFlushHandler;
 
         explicit LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent);
         ~LibLODocument_Impl();
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index a251adc..bada69f 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -384,8 +384,6 @@ static unsigned char* doc_renderFont(LibreOfficeKitDocument* pThis,
 
 LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent)
     : mxComponent(xComponent)
-    , mpCallback(nullptr)
-    , mpCallbackData(nullptr)
 {
     if (!(m_pDocumentClass = gDocumentClass.lock()))
     {
@@ -950,11 +948,11 @@ static void doc_setPartMode(LibreOfficeKitDocument* pThis,
     }
 }
 
-void doc_paintTile (LibreOfficeKitDocument* pThis,
-                    unsigned char* pBuffer,
-                    const int nCanvasWidth, const int nCanvasHeight,
-                    const int nTilePosX, const int nTilePosY,
-                    const int nTileWidth, const int nTileHeight)
+void doc_paintTile(LibreOfficeKitDocument* pThis,
+                   unsigned char* pBuffer,
+                   const int nCanvasWidth, const int nCanvasHeight,
+                   const int nTilePosX, const int nTilePosY,
+                   const int nTileWidth, const int nTileHeight)
 {
     SAL_INFO( "lok.tiledrendering", "paintTile: painting [" << nTileWidth << "x" << nTileHeight <<
               "]@(" << nTilePosX << ", " << nTilePosY << ") to [" <<
@@ -1099,13 +1097,12 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis,
 {
     LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
 
-    pDocument->mpCallback = pCallback;
-    pDocument->mpCallbackData = pData;
+    pDocument->mpCallbackFlushHandler.reset(new CallbackFlushHandler(pCallback, pData));
 
     if (comphelper::LibreOfficeKit::isViewCallback())
     {
         if (SfxViewShell* pViewShell = SfxViewFrame::Current()->GetViewShell())
-            pViewShell->registerLibreOfficeKitViewCallback(pCallback, pData);
+            pViewShell->registerLibreOfficeKitViewCallback(CallbackFlushHandler::callback, pDocument->mpCallbackFlushHandler.get());
     }
     else
     {
@@ -1116,7 +1113,7 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis,
             return;
         }
 
-        pDoc->registerCallback(pCallback, pData);
+        pDoc->registerCallback(CallbackFlushHandler::callback, pDocument->mpCallbackFlushHandler.get());
     }
 }
 
@@ -1142,14 +1139,12 @@ static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nChar
 class DispatchResultListener : public cppu::WeakImplHelper<css::frame::XDispatchResultListener>
 {
     OString maCommand;                 ///< Command for which this is the result.
-    LibreOfficeKitCallback mpCallback; ///< Callback to call.
-    void* mpCallbackData;              ///< The callback's data.
+    shared_ptr<CallbackFlushHandler> mpCallback; ///< Callback to call.
 
 public:
-    DispatchResultListener(const char* pCommand, LibreOfficeKitCallback pCallback, void* pCallbackData)
+    DispatchResultListener(const char* pCommand, shared_ptr<CallbackFlushHandler>& pCallback)
         : maCommand(pCommand)
         , mpCallback(pCallback)
-        , mpCallbackData(pCallbackData)
     {
         assert(mpCallback);
     }
@@ -1170,7 +1165,7 @@ public:
 
         std::stringstream aStream;
         boost::property_tree::write_json(aStream, aTree);
-        mpCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, strdup(aStream.str().c_str()), mpCallbackData);
+        mpCallback->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, strdup(aStream.str().c_str()));
     }
 
     virtual void SAL_CALL disposing(const css::lang::EventObject&) throw (css::uno::RuntimeException, std::exception) override {}
@@ -1199,10 +1194,10 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
 
     bool bResult = false;
 
-    if (bNotifyWhenFinished && pDocument->mpCallback)
+    if (bNotifyWhenFinished && pDocument->mpCallbackFlushHandler)
     {
         bResult = comphelper::dispatchCommand(aCommand, comphelper::containerToSequence(aPropertyValuesVector),
-                new DispatchResultListener(pCommand, pDocument->mpCallback, pDocument->mpCallbackData));
+                new DispatchResultListener(pCommand, pDocument->mpCallbackFlushHandler));
     }
     else
         bResult = comphelper::dispatchCommand(aCommand, comphelper::containerToSequence(aPropertyValuesVector));
@@ -1234,9 +1229,9 @@ static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX,
     }
 
     LibLODocument_Impl* pLib = static_cast<LibLODocument_Impl*>(pThis);
-    if (pLib->mpCallback && pLib->mpCallbackData)
+    if (pLib->mpCallbackFlushHandler)
     {
-        pLib->mpCallback(LOK_CALLBACK_MOUSE_POINTER, aPointerString.getStr(), pLib->mpCallbackData);
+        pLib->mpCallbackFlushHandler->queue(LOK_CALLBACK_MOUSE_POINTER, aPointerString.getStr());
     }
 }
 
diff --git a/desktop/source/lib/lokinteractionhandler.cxx b/desktop/source/lib/lokinteractionhandler.cxx
index e4c3ee5..a1e5568 100644
--- a/desktop/source/lib/lokinteractionhandler.cxx
+++ b/desktop/source/lib/lokinteractionhandler.cxx
@@ -115,8 +115,8 @@ void LOKInteractionHandler::postError(css::task::InteractionClassification class
     std::stringstream aStream;
     boost::property_tree::write_json(aStream, aTree);
 
-    if (m_pLOKDocument && m_pLOKDocument->mpCallback)
-        m_pLOKDocument->mpCallback(LOK_CALLBACK_ERROR, aStream.str().c_str(), m_pLOKDocument->mpCallbackData);
+    if (m_pLOKDocument && m_pLOKDocument->mpCallbackFlushHandler)
+        m_pLOKDocument->mpCallbackFlushHandler->queue(LOK_CALLBACK_ERROR, aStream.str().c_str());
     else if (m_pLOKit->mpCallback)
         m_pLOKit->mpCallback(LOK_CALLBACK_ERROR, aStream.str().c_str(), m_pLOKit->mpCallbackData);
 }


More information about the Libreoffice-commits mailing list