mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
added limited queue
This commit is contained in:
parent
5390272279
commit
93660233fd
22
channel.cpp
22
channel.cpp
|
@ -128,23 +128,17 @@ Channel::reloadFfzEmotes()
|
|||
});
|
||||
}
|
||||
|
||||
QVector<std::shared_ptr<messages::Message>>
|
||||
Channel::getMessagesClone()
|
||||
{
|
||||
this->messageMutex.lock();
|
||||
QVector<std::shared_ptr<messages::Message>> M(this->messages);
|
||||
M.detach();
|
||||
this->messageMutex.unlock();
|
||||
return M;
|
||||
}
|
||||
|
||||
void
|
||||
Channel::addMessage(std::shared_ptr<messages::Message> message)
|
||||
{
|
||||
this->messageMutex.lock();
|
||||
this->messages.append(message);
|
||||
this->messageMutex.unlock();
|
||||
std::shared_ptr<messages::Message> deleted;
|
||||
|
||||
Windows::repaintVisibleChatWidgets();
|
||||
if (this->messages.appendItem(message, deleted)) {
|
||||
this->messageRemovedFromStart(deleted);
|
||||
}
|
||||
|
||||
this->messageAppended(message);
|
||||
|
||||
Windows::repaintVisibleChatWidgets(this);
|
||||
}
|
||||
}
|
||||
|
|
25
channel.h
25
channel.h
|
@ -3,11 +3,13 @@
|
|||
|
||||
#include "concurrentmap.h"
|
||||
#include "messages/lazyloadedimage.h"
|
||||
#include "messages/limitedqueue.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <boost/signals2.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace chatterino {
|
||||
|
@ -20,6 +22,11 @@ class Channel
|
|||
public:
|
||||
Channel(const QString &channel);
|
||||
|
||||
boost::signals2::signal<void(std::shared_ptr<messages::Message> &)>
|
||||
messageRemovedFromStart;
|
||||
boost::signals2::signal<void(std::shared_ptr<messages::Message> &)>
|
||||
messageAppended;
|
||||
|
||||
// properties
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &
|
||||
getBttvChannelEmotes()
|
||||
|
@ -95,25 +102,23 @@ public:
|
|||
}
|
||||
|
||||
// methods
|
||||
void addMessage(std::shared_ptr<messages::Message> message);
|
||||
|
||||
QVector<std::shared_ptr<messages::Message>> getMessagesClone();
|
||||
|
||||
QVector<std::shared_ptr<messages::Message>> &
|
||||
getMessages()
|
||||
messages::LimitedQueueSnapshot<std::shared_ptr<messages::Message>>
|
||||
getMessageSnapshot()
|
||||
{
|
||||
return messages;
|
||||
return messages.getSnapshot();
|
||||
}
|
||||
|
||||
void addMessage(std::shared_ptr<messages::Message> message);
|
||||
|
||||
void
|
||||
reloadChannelEmotes()
|
||||
{
|
||||
reloadBttvEmotes();
|
||||
reloadFfzEmotes();
|
||||
this->reloadBttvEmotes();
|
||||
this->reloadFfzEmotes();
|
||||
}
|
||||
|
||||
private:
|
||||
QVector<std::shared_ptr<messages::Message>> messages;
|
||||
messages::LimitedQueue<std::shared_ptr<messages::Message>> messages;
|
||||
|
||||
QString name;
|
||||
int roomID;
|
||||
|
|
|
@ -95,7 +95,9 @@ HEADERS += account.h \
|
|||
windows.h \
|
||||
widgets/resizingtextedit.h \
|
||||
settingssnapshot.h \
|
||||
logging.h
|
||||
logging.h \
|
||||
messages/limitedqueue.h \
|
||||
messages/limitedqueuesnapshot.h
|
||||
|
||||
PRECOMPILED_HEADER =
|
||||
|
||||
|
|
97
messages/limitedqueue.h
Normal file
97
messages/limitedqueue.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
#ifndef LIMITEDQUEUE_H
|
||||
#define LIMITEDQUEUE_H
|
||||
|
||||
#include "messages/limitedqueuesnapshot.h"
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace chatterino {
|
||||
namespace messages {
|
||||
|
||||
template <typename T>
|
||||
class LimitedQueue
|
||||
{
|
||||
public:
|
||||
LimitedQueue(int limit = 10, int buffer = 5)
|
||||
: vector(new std::vector<T>(limit + buffer))
|
||||
, vectorPtr(this->vector)
|
||||
, mutex()
|
||||
, offset(0)
|
||||
, length(0)
|
||||
, limit(limit)
|
||||
, buffer(buffer)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// return true if an item was deleted
|
||||
// deleted will be set if the item was deleted
|
||||
bool
|
||||
appendItem(const T &item, T &deleted)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->mutex);
|
||||
|
||||
if (this->length == this->limit) {
|
||||
// vector is full
|
||||
if (this->offset == this->buffer) {
|
||||
deleted = this->vector->at(this->offset);
|
||||
|
||||
// create new vector
|
||||
auto *vector = new std::vector<T>(this->limit + this->buffer);
|
||||
|
||||
for (int i = 0; i < this->limit; i++) {
|
||||
vector->at(i) = this->vector->at(i + this->offset);
|
||||
}
|
||||
|
||||
vector->at(limit - 1) = item;
|
||||
|
||||
this->offset = 0;
|
||||
|
||||
this->vector = vector;
|
||||
this->vectorPtr = std::shared_ptr<std::vector<T>>(vector);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// append item and remove first
|
||||
deleted = this->vector->at(this->offset);
|
||||
|
||||
this->vector->at(this->length + this->offset) = item;
|
||||
this->offset++;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// append item
|
||||
this->vector->at(this->length) = item;
|
||||
this->length++;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
messages::LimitedQueueSnapshot<T>
|
||||
getSnapshot()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
return LimitedQueueSnapshot<T>(vectorPtr, offset, length);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> *vector;
|
||||
std::shared_ptr<std::vector<T>> vectorPtr;
|
||||
|
||||
std::mutex mutex;
|
||||
|
||||
int offset;
|
||||
int length;
|
||||
int limit;
|
||||
int buffer;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LIMITEDQUEUE_H
|
48
messages/limitedqueuesnapshot.h
Normal file
48
messages/limitedqueuesnapshot.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#ifndef LIMITEDQUEUESNAPSHOT_H
|
||||
#define LIMITEDQUEUESNAPSHOT_H
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace chatterino {
|
||||
namespace messages {
|
||||
|
||||
template <typename T>
|
||||
class LimitedQueueSnapshot
|
||||
{
|
||||
public:
|
||||
LimitedQueueSnapshot(std::shared_ptr<std::vector<T>> ptr, int offset,
|
||||
int length)
|
||||
: vectorPtr(ptr)
|
||||
, vector(ptr.get())
|
||||
, offset(offset)
|
||||
, length(length)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
T const &operator[](int index) const
|
||||
{
|
||||
assert(index >= 0);
|
||||
assert(index < length);
|
||||
|
||||
return vector->at(index + offset);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::vector<T>> vectorPtr;
|
||||
std::vector<T> *vector;
|
||||
|
||||
int offset;
|
||||
int length;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LIMITEDQUEUESNAPSHOT_H
|
|
@ -16,7 +16,7 @@ class Message
|
|||
{
|
||||
public:
|
||||
Message(const QString &text);
|
||||
Message(const IrcPrivateMessage &ircMessage, Channel &Channel,
|
||||
Message(const IrcPrivateMessage &ircMessage, Channel &channel,
|
||||
bool enablePingSound = true, bool isReceivedWhisper = false,
|
||||
bool isSentWhisper = false, bool includeChannel = false);
|
||||
|
||||
|
|
|
@ -47,17 +47,19 @@ ChatWidgetView::layoutMessages()
|
|||
|
||||
bool showScrollbar = false;
|
||||
|
||||
auto messages = c->getMessagesClone();
|
||||
auto messages = c->getMessageSnapshot();
|
||||
|
||||
bool redraw = false;
|
||||
|
||||
for (std::shared_ptr<messages::Message> &message : messages) {
|
||||
redraw |= message.get()->layout(this->width(), true);
|
||||
}
|
||||
// for (std::shared_ptr<messages::Message> &message : messages) {
|
||||
// redraw |= message.get()->layout(this->width(), true);
|
||||
// }
|
||||
|
||||
redraw = true;
|
||||
|
||||
int h = this->height() - 8;
|
||||
|
||||
for (int i = messages.size() - 1; i >= 0; i--) {
|
||||
for (int i = messages.getLength() - 1; i >= 0; i--) {
|
||||
auto *message = messages[i].get();
|
||||
|
||||
message->layout(this->width(), true);
|
||||
|
@ -65,7 +67,7 @@ ChatWidgetView::layoutMessages()
|
|||
h -= message->getHeight();
|
||||
|
||||
if (h < 0) {
|
||||
this->scrollbar.setLargeChange((messages.size() - i) +
|
||||
this->scrollbar.setLargeChange((messages.getLength() - i) +
|
||||
(qreal)h / message->getHeight());
|
||||
this->scrollbar.setDesiredValue(this->scrollbar.getDesiredValue());
|
||||
|
||||
|
@ -76,7 +78,7 @@ ChatWidgetView::layoutMessages()
|
|||
|
||||
this->scrollbar.setVisible(showScrollbar);
|
||||
|
||||
this->scrollbar.setMaximum(c->getMessages().size());
|
||||
this->scrollbar.setMaximum(messages.getLength());
|
||||
|
||||
return redraw;
|
||||
}
|
||||
|
@ -138,18 +140,18 @@ ChatWidgetView::paintEvent(QPaintEvent *)
|
|||
if (c == NULL)
|
||||
return;
|
||||
|
||||
auto messages = c->getMessagesClone();
|
||||
auto messages = c->getMessageSnapshot();
|
||||
|
||||
int start = this->scrollbar.getCurrentValue();
|
||||
|
||||
if (start >= messages.length()) {
|
||||
if (start >= messages.getLength()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int y = -(messages[start].get()->getHeight() *
|
||||
(fmod(this->scrollbar.getCurrentValue(), 1)));
|
||||
|
||||
for (int i = start; i < messages.size(); ++i) {
|
||||
for (int i = start; i < messages.getLength(); ++i) {
|
||||
messages::Message *message = messages[i].get();
|
||||
|
||||
for (messages::WordPart const &wordPart : message->getWordParts()) {
|
||||
|
|
|
@ -133,12 +133,8 @@ Notebook::tabAt(QPoint point, int &index)
|
|||
void
|
||||
Notebook::rearrangePage(NotebookPage *page, int index)
|
||||
{
|
||||
int i1 = pages.indexOf(page);
|
||||
|
||||
pages.move(pages.indexOf(page), index);
|
||||
|
||||
int i2 = pages.indexOf(page);
|
||||
|
||||
performLayout();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,11 @@ ScrollBar::ScrollBar(QWidget *widget)
|
|||
, currentValueChanged()
|
||||
, currentValue()
|
||||
{
|
||||
resize(16, 100);
|
||||
this->resize(16, 100);
|
||||
|
||||
currentValueAnimation.setDuration(300);
|
||||
currentValueAnimation.setEasingCurve(QEasingCurve(QEasingCurve::OutCubic));
|
||||
this->currentValueAnimation.setDuration(300);
|
||||
this->currentValueAnimation.setEasingCurve(
|
||||
QEasingCurve(QEasingCurve::OutCubic));
|
||||
|
||||
this->setMouseTracking(true);
|
||||
}
|
||||
|
@ -211,7 +212,7 @@ ScrollBar::updateScroll()
|
|||
|
||||
this->thumbRect =
|
||||
QRect(0,
|
||||
(int)(this->desiredValue / this->maximum * this->trackHeight) +
|
||||
(int)(this->currentValue / this->maximum * this->trackHeight) +
|
||||
1 + this->buttonHeight,
|
||||
width(),
|
||||
(int)(this->largeChange / this->maximum * this->trackHeight) +
|
||||
|
|
|
@ -63,8 +63,6 @@ public:
|
|||
value = std::max(this->minimum,
|
||||
std::min(this->maximum - this->largeChange, value));
|
||||
|
||||
this->desiredValue = value;
|
||||
|
||||
if (this->desiredValue != value) {
|
||||
if (animated) {
|
||||
this->currentValueAnimation.stop();
|
||||
|
@ -78,6 +76,8 @@ public:
|
|||
this->setCurrentValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
this->desiredValue = value;
|
||||
}
|
||||
|
||||
qreal
|
||||
|
|
Loading…
Reference in a new issue