common/MessageQueue.cpp |  342 +++++++++++++++++++++++++-----------------------
 1 file changed, 184 insertions(+), 158 deletions(-)

New commits:
commit 39d34cbab4715ba10d5bab10c82746cb4605baca
Author:     Ashod Nakashian <ashod.nakash...@collabora.co.uk>
AuthorDate: Tue Jun 2 23:16:47 2020 -0400
Commit:     Ashod Nakashian <ashnak...@gmail.com>
CommitDate: Thu Jul 2 21:49:31 2020 +0200

    wsd: match LOK callback type as integer
    
    String comparisons are costly and much
    less readable. Now we have a fast switch
    with LOK_CALLBACK enum values.
    
    Change-Id: Icc24b91b174cd9bbb7e0d64039df080c0a4338f2
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/96375
    Tested-by: Jenkins
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Ashod Nakashian <ashnak...@gmail.com>

diff --git a/common/MessageQueue.cpp b/common/MessageQueue.cpp
index 064a27717..f239a2e9c 100644
--- a/common/MessageQueue.cpp
+++ b/common/MessageQueue.cpp
@@ -192,207 +192,233 @@ std::string TileQueue::removeCallbackDuplicate(const 
std::string& callbackMsg)
         return std::string();
 
     // the message is "callback <view> <id> ..."
-    const std::string& callbackType = tokens[2];
-
-    // FIXME: Good grief, why don't we use the symbolic LOK_CALLBACK_FOO names 
here? Doing it this
-    // way is somewhat fragile and certainly bad style.
-    if (callbackType == "0")        // invalidation
-    {
-        int msgX, msgY, msgW, msgH, msgPart;
-
-        if (!extractRectangle(tokens, msgX, msgY, msgW, msgH, msgPart))
-            return std::string();
+    const auto pair = Util::i32FromString(tokens[2]);
+    if (!pair.second)
+        return std::string();
 
-        bool performedMerge = false;
+    const auto callbackType = 
static_cast<LibreOfficeKitCallbackType>(pair.first);
 
-        // we always travel the entire queue
-        size_t i = 0;
-        while (i < getQueue().size())
+    switch (callbackType)
+    {
+        case LOK_CALLBACK_INVALIDATE_TILES: // invalidation
         {
-            auto& it = getQueue()[i];
+            int msgX, msgY, msgW, msgH, msgPart;
 
-            StringVector queuedTokens = Util::tokenize(it.data(), it.size());
-            if (queuedTokens.size() < 3)
-            {
-                ++i;
-                continue;
-            }
-
-            // not a invalidation callback
-            if (queuedTokens[0] != tokens[0] || queuedTokens[1] != tokens[1] 
|| queuedTokens[2] != tokens[2])
-            {
-                ++i;
-                continue;
-            }
+            if (!extractRectangle(tokens, msgX, msgY, msgW, msgH, msgPart))
+                return std::string();
 
-            int queuedX, queuedY, queuedW, queuedH, queuedPart;
+            bool performedMerge = false;
 
-            if (!extractRectangle(queuedTokens, queuedX, queuedY, queuedW, 
queuedH, queuedPart))
+            // we always travel the entire queue
+            std::size_t i = 0;
+            while (i < getQueue().size())
             {
-                ++i;
-                continue;
-            }
+                auto& it = getQueue()[i];
 
-            if (msgPart != queuedPart)
-            {
-                ++i;
-                continue;
-            }
+                StringVector queuedTokens = Util::tokenize(it.data(), 
it.size());
+                if (queuedTokens.size() < 3)
+                {
+                    ++i;
+                    continue;
+                }
 
-            // the invalidation in the queue is fully covered by the message,
-            // just remove it
-            if (msgX <= queuedX && queuedX + queuedW <= msgX + msgW && msgY <= 
queuedY && queuedY + queuedH <= msgY + msgH)
-            {
-                LOG_TRC("Removing smaller invalidation: "
-                        << std::string(it.data(), it.size()) << " -> " << 
tokens[0] << ' '
-                        << tokens[1] << ' ' << tokens[2] << ' ' << msgX << ' ' 
<< msgY << ' '
-                        << msgW << ' ' << msgH << ' ' << msgPart);
-
-                // remove from the queue
-                getQueue().erase(getQueue().begin() + i);
-                continue;
-            }
+                // not a invalidation callback
+                if (queuedTokens[0] != tokens[0] || queuedTokens[1] != 
tokens[1]
+                    || queuedTokens[2] != tokens[2])
+                {
+                    ++i;
+                    continue;
+                }
 
-            // the invalidation just intersects, join those (if the result is
-            // small)
-            if (TileDesc::rectanglesIntersect(msgX, msgY, msgW, msgH, queuedX, 
queuedY, queuedW, queuedH))
-            {
-                int joinX = std::min(msgX, queuedX);
-                int joinY = std::min(msgY, queuedY);
-                int joinW = std::max(msgX + msgW, queuedX + queuedW) - joinX;
-                int joinH = std::max(msgY + msgH, queuedY + queuedH) - joinY;
-
-                const int reasonableSizeX = 4*3840; // 4x tile at 100% zoom
-                const int reasonableSizeY = 2*3840; // 2x tile at 100% zoom
-                if (joinW > reasonableSizeX || joinH > reasonableSizeY)
+                int queuedX, queuedY, queuedW, queuedH, queuedPart;
+
+                if (!extractRectangle(queuedTokens, queuedX, queuedY, queuedW, 
queuedH, queuedPart))
                 {
                     ++i;
                     continue;
                 }
 
-                LOG_TRC("Merging invalidations: "
-                        << std::string(it.data(), it.size()) << " and " << 
tokens[0] << ' '
-                        << tokens[1] << ' ' << tokens[2] << ' ' << msgX << ' ' 
<< msgY << ' '
-                        << msgW << ' ' << msgH << ' ' << msgPart << " -> " << 
tokens[0] << ' '
-                        << tokens[1] << ' ' << tokens[2] << ' ' << joinX << ' 
' << joinY << ' '
-                        << joinW << ' ' << joinH << ' ' << msgPart);
-
-                msgX = joinX;
-                msgY = joinY;
-                msgW = joinW;
-                msgH = joinH;
-                performedMerge = true;
-
-                // remove from the queue
-                getQueue().erase(getQueue().begin() + i);
-                continue;
-            }
+                if (msgPart != queuedPart)
+                {
+                    ++i;
+                    continue;
+                }
 
-            ++i;
-        }
+                // the invalidation in the queue is fully covered by the 
message,
+                // just remove it
+                if (msgX <= queuedX && queuedX + queuedW <= msgX + msgW && 
msgY <= queuedY
+                    && queuedY + queuedH <= msgY + msgH)
+                {
+                    LOG_TRC("Removing smaller invalidation: "
+                            << std::string(it.data(), it.size()) << " -> " << 
tokens[0] << ' '
+                            << tokens[1] << ' ' << tokens[2] << ' ' << msgX << 
' ' << msgY << ' '
+                            << msgW << ' ' << msgH << ' ' << msgPart);
 
-        if (performedMerge)
-        {
-            size_t pre = tokens[0].size() + tokens[1].size() + 
tokens[2].size() + 3;
-            size_t post = pre + tokens[3].size() + tokens[4].size() + 
tokens[5].size() + tokens[6].size() + 4;
+                    // remove from the queue
+                    getQueue().erase(getQueue().begin() + i);
+                    continue;
+                }
 
-            std::string result = callbackMsg.substr(0, pre) +
-                std::to_string(msgX) + ", " +
-                std::to_string(msgY) + ", " +
-                std::to_string(msgW) + ", " +
-                std::to_string(msgH) + ", " + callbackMsg.substr(post);
+                // the invalidation just intersects, join those (if the result 
is
+                // small)
+                if (TileDesc::rectanglesIntersect(msgX, msgY, msgW, msgH, 
queuedX, queuedY, queuedW,
+                                                  queuedH))
+                {
+                    int joinX = std::min(msgX, queuedX);
+                    int joinY = std::min(msgY, queuedY);
+                    int joinW = std::max(msgX + msgW, queuedX + queuedW) - 
joinX;
+                    int joinH = std::max(msgY + msgH, queuedY + queuedH) - 
joinY;
+
+                    const int reasonableSizeX = 4 * 3840; // 4x tile at 100% 
zoom
+                    const int reasonableSizeY = 2 * 3840; // 2x tile at 100% 
zoom
+                    if (joinW > reasonableSizeX || joinH > reasonableSizeY)
+                    {
+                        ++i;
+                        continue;
+                    }
 
-            LOG_TRC("Merge result: " << result);
+                    LOG_TRC("Merging invalidations: "
+                            << std::string(it.data(), it.size()) << " and " << 
tokens[0] << ' '
+                            << tokens[1] << ' ' << tokens[2] << ' ' << msgX << 
' ' << msgY << ' '
+                            << msgW << ' ' << msgH << ' ' << msgPart << " -> " 
<< tokens[0] << ' '
+                            << tokens[1] << ' ' << tokens[2] << ' ' << joinX 
<< ' ' << joinY << ' '
+                            << joinW << ' ' << joinH << ' ' << msgPart);
 
-            return result;
-        }
-    }
-    else if (callbackType == "8")        // state changed
-    {
-        if (tokens.size() < 4)
-            return std::string();
+                    msgX = joinX;
+                    msgY = joinY;
+                    msgW = joinW;
+                    msgH = joinH;
+                    performedMerge = true;
 
-        std::string unoCommand = extractUnoCommand(tokens[3]);
-        if (unoCommand.empty())
-            return std::string();
+                    // remove from the queue
+                    getQueue().erase(getQueue().begin() + i);
+                    continue;
+                }
 
-        // remove obsolete states of the same .uno: command
-        for (size_t i = 0; i < getQueue().size(); ++i)
-        {
-            auto& it = getQueue()[i];
+                ++i;
+            }
 
-            StringVector queuedTokens = Util::tokenize(it.data(), it.size());
-            if (queuedTokens.size() < 4)
-                continue;
+            if (performedMerge)
+            {
+                std::size_t pre = tokens[0].size() + tokens[1].size() + 
tokens[2].size() + 3;
+                std::size_t post = pre + tokens[3].size() + tokens[4].size() + 
tokens[5].size()
+                              + tokens[6].size() + 4;
 
-            if (queuedTokens[0] != tokens[0] || queuedTokens[1] != tokens[1] 
|| queuedTokens[2] != tokens[2])
-                continue;
+                std::string result = callbackMsg.substr(0, pre) + 
std::to_string(msgX) + ", "
+                                     + std::to_string(msgY) + ", " + 
std::to_string(msgW) + ", "
+                                     + std::to_string(msgH) + ", " + 
callbackMsg.substr(post);
 
-            // callback, the same target, state changed; now check it's
-            // the same .uno: command
-            std::string queuedUnoCommand = extractUnoCommand(queuedTokens[3]);
-            if (queuedUnoCommand.empty())
-                continue;
+                LOG_TRC("Merge result: " << result);
 
-            if (unoCommand == queuedUnoCommand)
-            {
-                LOG_TRC("Remove obsolete uno command: " << 
std::string(it.data(), it.size()) << " -> " << 
LOOLProtocol::getAbbreviatedMessage(callbackMsg));
-                getQueue().erase(getQueue().begin() + i);
-                break;
+                return result;
             }
         }
-    }
-    else if (callbackType == "1" || // the cursor has moved
-            callbackType == "5" ||  // the cursor visibility has changed
-            callbackType == "10" || // setting the indicator value
-            callbackType == "13" || // setting the document size
-            callbackType == "17" || // the cell cursor has moved
-            callbackType == "24" || // the view cursor has moved
-            callbackType == "26" || // the view cell cursor has moved
-            callbackType == "28")   // the view cursor visibility has changed
-    {
-        const bool isViewCallback = (callbackType == "24" || callbackType == 
"26" || callbackType == "28");
+        break;
 
-        std::string viewId;
-        if (isViewCallback)
+        case LOK_CALLBACK_STATE_CHANGED: // state changed
         {
-            viewId = extractViewId(callbackMsg, tokens);
-        }
+            if (tokens.size() < 4)
+                return std::string();
 
-        for (size_t i = 0; i < getQueue().size(); ++i)
-        {
-            const auto& it = getQueue()[i];
+            std::string unoCommand = extractUnoCommand(tokens[3]);
+            if (unoCommand.empty())
+                return std::string();
 
-            // skip non-callbacks quickly
-            if (!LOOLProtocol::matchPrefix("callback", it))
-                continue;
+            // remove obsolete states of the same .uno: command
+            for (std::size_t i = 0; i < getQueue().size(); ++i)
+            {
+                auto& it = getQueue()[i];
 
-            StringVector queuedTokens = Util::tokenize(it.data(), it.size());
-            if (queuedTokens.size() < 3)
-                continue;
+                StringVector queuedTokens = Util::tokenize(it.data(), 
it.size());
+                if (queuedTokens.size() < 4)
+                    continue;
 
-            if (!isViewCallback && (queuedTokens.equals(1, tokens, 1) && 
queuedTokens.equals(2, tokens, 2)))
-            {
-                LOG_TRC("Remove obsolete callback: " << std::string(it.data(), 
it.size()) << " -> " << LOOLProtocol::getAbbreviatedMessage(callbackMsg));
-                getQueue().erase(getQueue().begin() + i);
-                break;
+                if (queuedTokens[0] != tokens[0] || queuedTokens[1] != 
tokens[1]
+                    || queuedTokens[2] != tokens[2])
+                    continue;
+
+                // callback, the same target, state changed; now check it's
+                // the same .uno: command
+                std::string queuedUnoCommand = 
extractUnoCommand(queuedTokens[3]);
+                if (queuedUnoCommand.empty())
+                    continue;
+
+                if (unoCommand == queuedUnoCommand)
+                {
+                    LOG_TRC("Remove obsolete uno command: "
+                            << std::string(it.data(), it.size()) << " -> "
+                            << 
LOOLProtocol::getAbbreviatedMessage(callbackMsg));
+                    getQueue().erase(getQueue().begin() + i);
+                    break;
+                }
             }
-            else if (isViewCallback && (queuedTokens.equals(1, tokens, 1) && 
queuedTokens.equals(2, tokens, 2)))
+        }
+        break;
+
+        case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: // the cursor has moved
+        case LOK_CALLBACK_CURSOR_VISIBLE: // the cursor visibility has changed
+        case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE: // setting the indicator 
value
+        case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: // setting the document size
+        case LOK_CALLBACK_CELL_CURSOR: // the cell cursor has moved
+        case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR: // the view cursor has moved
+        case LOK_CALLBACK_CELL_VIEW_CURSOR: // the view cell cursor has moved
+        case LOK_CALLBACK_VIEW_CURSOR_VISIBLE: // the view cursor visibility 
has changed
+        {
+            const bool isViewCallback = (callbackType == 
LOK_CALLBACK_INVALIDATE_VIEW_CURSOR
+                                         || callbackType == 
LOK_CALLBACK_CELL_VIEW_CURSOR
+                                         || callbackType == 
LOK_CALLBACK_VIEW_CURSOR_VISIBLE);
+
+            const std::string viewId
+                = (isViewCallback ? extractViewId(callbackMsg, tokens) : 
std::string());
+
+            for (std::size_t i = 0; i < getQueue().size(); ++i)
             {
-                // we additionally need to ensure that the payload is about
-                // the same viewid (otherwise we'd merge them all views into
-                // one)
-                const std::string queuedViewId = 
extractViewId(std::string(it.data(), it.size()), queuedTokens);
+                const auto& it = getQueue()[i];
+
+                // skip non-callbacks quickly
+                if (!LOOLProtocol::matchPrefix("callback", it))
+                    continue;
+
+                StringVector queuedTokens = Util::tokenize(it.data(), 
it.size());
+                if (queuedTokens.size() < 3)
+                    continue;
 
-                if (viewId == queuedViewId)
+                if (!isViewCallback
+                    && (queuedTokens.equals(1, tokens, 1) && 
queuedTokens.equals(2, tokens, 2)))
                 {
-                    LOG_TRC("Remove obsolete view callback: " << 
std::string(it.data(), it.size()) << " -> " << 
LOOLProtocol::getAbbreviatedMessage(callbackMsg));
+                    LOG_TRC("Remove obsolete callback: "
+                            << std::string(it.data(), it.size()) << " -> "
+                            << 
LOOLProtocol::getAbbreviatedMessage(callbackMsg));
                     getQueue().erase(getQueue().begin() + i);
                     break;
                 }
+                else if (isViewCallback
+                         && (queuedTokens.equals(1, tokens, 1)
+                             && queuedTokens.equals(2, tokens, 2)))
+                {
+                    // we additionally need to ensure that the payload is about
+                    // the same viewid (otherwise we'd merge them all views 
into
+                    // one)
+                    const std::string queuedViewId
+                        = extractViewId(std::string(it.data(), it.size()), 
queuedTokens);
+
+                    if (viewId == queuedViewId)
+                    {
+                        LOG_TRC("Remove obsolete view callback: "
+                                << std::string(it.data(), it.size()) << " -> "
+                                << 
LOOLProtocol::getAbbreviatedMessage(callbackMsg));
+                        getQueue().erase(getQueue().begin() + i);
+                        break;
+                    }
+                }
             }
         }
-    }
+        break;
+
+        default:
+        break;
+
+    } // switch
 
     return std::string();
 }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to