[Libreoffice-commits] online.git: common/MessageQueue.cpp
Ashod Nakashian (via logerrit)
logerrit at kemper.freedesktop.org
Thu Jul 2 19:49:52 UTC 2020
common/MessageQueue.cpp | 342 +++++++++++++++++++++++++-----------------------
1 file changed, 184 insertions(+), 158 deletions(-)
New commits:
commit 39d34cbab4715ba10d5bab10c82746cb4605baca
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Tue Jun 2 23:16:47 2020 -0400
Commit: Ashod Nakashian <ashnakash at 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 <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Ashod Nakashian <ashnakash at 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();
}
More information about the Libreoffice-commits
mailing list