fix: take indices to messages as a hint (#5683)
This commit is contained in:
+17
-5
@@ -253,21 +253,33 @@ void Channel::fillInMissingMessages(const std::vector<MessagePtr> &messages)
|
||||
}
|
||||
}
|
||||
|
||||
void Channel::replaceMessage(MessagePtr message, MessagePtr replacement)
|
||||
void Channel::replaceMessage(const MessagePtr &message,
|
||||
const MessagePtr &replacement)
|
||||
{
|
||||
int index = this->messages_.replaceItem(message, replacement);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
this->messageReplaced.invoke((size_t)index, replacement);
|
||||
this->messageReplaced.invoke((size_t)index, message, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
void Channel::replaceMessage(size_t index, MessagePtr replacement)
|
||||
void Channel::replaceMessage(size_t index, const MessagePtr &replacement)
|
||||
{
|
||||
if (this->messages_.replaceItem(index, replacement))
|
||||
MessagePtr prev;
|
||||
if (this->messages_.replaceItem(index, replacement, &prev))
|
||||
{
|
||||
this->messageReplaced.invoke(index, replacement);
|
||||
this->messageReplaced.invoke(index, prev, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
void Channel::replaceMessage(size_t hint, const MessagePtr &message,
|
||||
const MessagePtr &replacement)
|
||||
{
|
||||
auto index = this->messages_.replaceItem(hint, message, replacement);
|
||||
if (index >= 0)
|
||||
{
|
||||
this->messageReplaced.invoke(hint, message, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,9 @@ public:
|
||||
pajlada::Signals::Signal<MessagePtr &, std::optional<MessageFlags>>
|
||||
messageAppended;
|
||||
pajlada::Signals::Signal<std::vector<MessagePtr> &> messagesAddedAtStart;
|
||||
pajlada::Signals::Signal<size_t, MessagePtr &> messageReplaced;
|
||||
/// (index, prev-message, replacement)
|
||||
pajlada::Signals::Signal<size_t, const MessagePtr &, const MessagePtr &>
|
||||
messageReplaced;
|
||||
/// Invoked when some number of messages were filled in using time received
|
||||
pajlada::Signals::Signal<const std::vector<MessagePtr> &> filledInMessages;
|
||||
pajlada::Signals::NoArgSignal destroyed;
|
||||
@@ -96,8 +98,11 @@ public:
|
||||
|
||||
void addOrReplaceTimeout(MessagePtr message);
|
||||
void disableAllMessages();
|
||||
void replaceMessage(MessagePtr message, MessagePtr replacement);
|
||||
void replaceMessage(size_t index, MessagePtr replacement);
|
||||
void replaceMessage(const MessagePtr &message,
|
||||
const MessagePtr &replacement);
|
||||
void replaceMessage(size_t index, const MessagePtr &replacement);
|
||||
void replaceMessage(size_t hint, const MessagePtr &message,
|
||||
const MessagePtr &replacement);
|
||||
void deleteMessage(QString messageID);
|
||||
|
||||
/// Removes all messages from this channel and invokes #messagesCleared
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace chatterino {
|
||||
@@ -212,9 +213,10 @@ public:
|
||||
*
|
||||
* @param[in] index the index of the item to replace
|
||||
* @param[in] replacement the item to put in place of the item at index
|
||||
* @param[out] prev (optional) the item located at @a index before replacing
|
||||
* @return true if a replacement took place
|
||||
*/
|
||||
bool replaceItem(size_t index, const T &replacement)
|
||||
bool replaceItem(size_t index, const T &replacement, T *prev = nullptr)
|
||||
{
|
||||
std::unique_lock lock(this->mutex_);
|
||||
|
||||
@@ -223,10 +225,46 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
this->buffer_[index] = replacement;
|
||||
if (prev)
|
||||
{
|
||||
*prev = std::exchange(this->buffer_[index], replacement);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->buffer_[index] = replacement;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Replace the needle with the given item
|
||||
*
|
||||
* @param hint A hint on where the needle _might_ be
|
||||
* @param[in] needle the item to search for
|
||||
* @param[in] replacement the item to replace needle with
|
||||
* @return the index of the replaced item, or -1 if no replacement took place
|
||||
*/
|
||||
int replaceItem(size_t hint, const T &needle, const T &replacement)
|
||||
{
|
||||
std::unique_lock lock(this->mutex_);
|
||||
|
||||
if (hint < this->buffer_.size() && this->buffer_[hint] == needle)
|
||||
{
|
||||
this->buffer_[hint] = replacement;
|
||||
return static_cast<int>(hint);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < this->buffer_.size(); ++i)
|
||||
{
|
||||
if (this->buffer_[i] == needle)
|
||||
{
|
||||
this->buffer_[i] = replacement;
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts the given item before another item
|
||||
*
|
||||
@@ -315,6 +353,32 @@ public:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find an item with a hint
|
||||
*
|
||||
* @param hint A hint on where the needle _might_ be
|
||||
* @param predicate that will used to find the item
|
||||
* @return the item and its index or none if it's not found
|
||||
*/
|
||||
std::optional<std::pair<size_t, T>> find(size_t hint, auto &&predicate)
|
||||
{
|
||||
std::unique_lock lock(this->mutex_);
|
||||
|
||||
if (hint < this->buffer_.size() && predicate(this->buffer_[hint]))
|
||||
{
|
||||
return std::pair{hint, this->buffer_[hint]};
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < this->buffer_.size(); i++)
|
||||
{
|
||||
if (predicate(this->buffer_[i]))
|
||||
{
|
||||
return std::pair{i, this->buffer_[i]};
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the first item matching a predicate, checking in reverse
|
||||
*
|
||||
|
||||
@@ -967,10 +967,10 @@ void ChannelView::setChannel(const ChannelPtr &underlyingChannel)
|
||||
|
||||
this->channelConnections_.managedConnect(
|
||||
underlyingChannel->messageReplaced,
|
||||
[this](auto index, const auto &replacement) {
|
||||
[this](auto index, const auto &prev, const auto &replacement) {
|
||||
if (this->shouldIncludeMessage(replacement))
|
||||
{
|
||||
this->channel_->replaceMessage(index, replacement);
|
||||
this->channel_->replaceMessage(index, prev, replacement);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1051,8 +1051,9 @@ void ChannelView::setChannel(const ChannelPtr &underlyingChannel)
|
||||
// on message replaced
|
||||
this->channelConnections_.managedConnect(
|
||||
this->channel_->messageReplaced,
|
||||
[this](size_t index, MessagePtr replacement) {
|
||||
this->messageReplaced(index, replacement);
|
||||
[this](size_t index, const MessagePtr &prev,
|
||||
const MessagePtr &replacement) {
|
||||
this->messageReplaced(index, prev, replacement);
|
||||
});
|
||||
|
||||
// on messages filled in
|
||||
@@ -1258,19 +1259,21 @@ void ChannelView::messageAddedAtStart(std::vector<MessagePtr> &messages)
|
||||
this->queueLayout();
|
||||
}
|
||||
|
||||
void ChannelView::messageReplaced(size_t index, MessagePtr &replacement)
|
||||
void ChannelView::messageReplaced(size_t hint, const MessagePtr &prev,
|
||||
const MessagePtr &replacement)
|
||||
{
|
||||
auto oMessage = this->messages_.get(index);
|
||||
if (!oMessage)
|
||||
auto optItem = this->messages_.find(hint, [&](const auto &it) {
|
||||
return it->getMessagePtr() == prev;
|
||||
});
|
||||
if (!optItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto message = *oMessage;
|
||||
const auto &[index, oldItem] = *optItem;
|
||||
|
||||
auto newItem = std::make_shared<MessageLayout>(replacement);
|
||||
|
||||
if (message->flags.has(MessageLayoutFlag::AlternateBackground))
|
||||
if (oldItem->flags.has(MessageLayoutFlag::AlternateBackground))
|
||||
{
|
||||
newItem->flags.set(MessageLayoutFlag::AlternateBackground);
|
||||
}
|
||||
@@ -1278,7 +1281,7 @@ void ChannelView::messageReplaced(size_t index, MessagePtr &replacement)
|
||||
this->scrollBar_->replaceHighlight(index,
|
||||
replacement->getScrollBarHighlight());
|
||||
|
||||
this->messages_.replaceItem(message, newItem);
|
||||
this->messages_.replaceItem(index, newItem);
|
||||
this->queueLayout();
|
||||
}
|
||||
|
||||
|
||||
@@ -268,7 +268,8 @@ private:
|
||||
std::optional<MessageFlags> overridingFlags);
|
||||
void messageAddedAtStart(std::vector<MessagePtr> &messages);
|
||||
void messageRemoveFromStart(MessagePtr &message);
|
||||
void messageReplaced(size_t index, MessagePtr &replacement);
|
||||
void messageReplaced(size_t hint, const MessagePtr &prev,
|
||||
const MessagePtr &replacement);
|
||||
void messagesUpdated();
|
||||
|
||||
void performLayout(bool causedByScrollbar = false,
|
||||
|
||||
Reference in New Issue
Block a user