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.nakash...@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 <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@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); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits