desktop/inc/lib/init.hxx | 50 +++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-)
New commits: commit 1f278848117080cd6e819f04ba428be52416af7c Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Fri Apr 22 00:32:31 2016 -0400 Timer based LOKit callbacks and smart status tracking The timer-based callback groups notifications together and minimizes roundtrip overheads with clients. A new status tracking for select notification types eliminates duplicates and superfluous messages. Change-Id: I5d27096d51e71afda22ecd71edf6b5735dee7852 Reviewed-on: https://gerrit.libreoffice.org/24290 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 f65c216..4827316 100644 --- a/desktop/inc/lib/init.hxx +++ b/desktop/inc/lib/init.hxx @@ -13,7 +13,7 @@ #include <boost/shared_ptr.hpp> #include <osl/thread.h> -#include <vcl/idle.hxx> +#include <vcl/timer.hxx> #include <LibreOfficeKit/LibreOfficeKit.h> #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <com/sun/star/frame/XStorable.hpp> @@ -27,15 +27,23 @@ class LOKInteractionHandler; namespace desktop { - class CallbackFlushHandler : public Idle + class CallbackFlushHandler : public Timer { public: explicit CallbackFlushHandler(LibreOfficeKitCallback pCallback, void* pData) - : Idle( "lokit idle callback" ), + : Timer( "lokit timer callback" ), m_pCallback(pCallback), m_pData(pData) { - SetPriority(SchedulerPriority::POST_PAINT); + SetTimeout(25); + + // Add the states that is safe to skip duplicates on, + // even when not consequent. + m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_START, ""); + m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_END, ""); + m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, ""); + m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""); + m_states.emplace(LOK_CALLBACK_STATE_CHANGED, ""); } virtual ~CallbackFlushHandler() @@ -62,27 +70,34 @@ namespace desktop { } } - void queue(const int type, const char* payload) + void queue(const int type, const char* data) { + const std::string payload(data ? data : "(nil)"); 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) + const auto stateIt = m_states.find(type); + if (stateIt != m_states.end()) { - if (m_queue.empty() || std::get<0>(m_queue.back()) != type) + // If the state didn't change, it's safe to ignore. + if (stateIt->second == payload) { - m_queue.emplace_back(type, std::string(payload ? payload : "(nil)")); - - if (!IsActive()) - { - Start(); - } + return; } + + stateIt->second = payload; + } + + if (type == LOK_CALLBACK_INVALIDATE_TILES && + !m_queue.empty() && std::get<0>(m_queue.back()) == type && std::get<1>(m_queue.back()) == payload) + { + // Supress duplicate invalidation only when they are in sequence. + return; } - else + + m_queue.emplace_back(type, payload); + if (!IsActive()) { - m_queue.emplace_back(type, std::string(payload ? payload : "(nil)")); - flush(); + Start(); } } @@ -102,6 +117,7 @@ namespace desktop { private: std::vector<std::tuple<int, std::string>> m_queue; + std::map<int, std::string> m_states; LibreOfficeKitCallback m_pCallback; void *m_pData; std::mutex m_mutex; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits