aboutsummaryrefslogtreecommitdiff
path: root/room.h
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2017-03-03 12:29:53 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2017-03-10 13:05:29 +0900
commit22ea325ef03cdc15f2c36b1e0c82c84dec01cfb5 (patch)
treef75509dca94447ce65aec5763c0e89a98f63f70a /room.h
parentc8d31ab28db19a7e1f1ca9cf1a35de17158c43fb (diff)
downloadlibquotient-22ea325ef03cdc15f2c36b1e0c82c84dec01cfb5.tar.gz
libquotient-22ea325ef03cdc15f2c36b1e0c82c84dec01cfb5.zip
Use special indices instead of iterators for persistent pointers into timeline + no more discarding read markers to events that haven't arrived yet
When using deque::const_reverse_iterator for read markers and eventsIndex, I didn't realise that insertions into std::deque invalidate iterators (though preserve references and pointers). Therefore, a small TimelineItem class has been introduced that stores an event together with a persistent index that is generated upon insertion into the timeline (timeline.back()+1 for newer events, timeline.front()-1 for older events). Using such indices, we can still reach an event by it's index in constant time, while avoiding a problem with invalidating iterators. While rewriting the code, another problem has been detected with read markers to events that haven't yet arrived to the timeline (in particular, older events). The old code simply discarded such read markers. The new code stores such read markers anyway, so that when that event arrives, it could be matched against the stored last-read-event id.
Diffstat (limited to 'room.h')
-rw-r--r--room.h29
1 files changed, 22 insertions, 7 deletions
diff --git a/room.h b/room.h
index ff76b25a..b2e56502 100644
--- a/room.h
+++ b/room.h
@@ -18,6 +18,9 @@
#pragma once
+#include <memory>
+#include <deque>
+
#include <QtCore/QList>
#include <QtCore/QStringList>
#include <QtCore/QObject>
@@ -26,8 +29,6 @@
#include "jobs/syncjob.h"
#include "joinstate.h"
-#include <deque>
-
namespace QMatrixClient
{
class Event;
@@ -35,12 +36,28 @@ namespace QMatrixClient
class User;
class MemberSorter;
+ class TimelineItem
+ {
+ public:
+ using index_t = int; // For compatibility with Qt containers
+
+ TimelineItem(Event* e, index_t number) : evt(e), idx(number) { }
+
+ Event* event() const { return evt.get(); }
+ Event* operator->() const { return event(); } //< Synonym for event()
+ index_t index() const { return idx; }
+
+ private:
+ std::unique_ptr<Event> evt;
+ index_t idx;
+ };
+
class Room: public QObject
{
Q_OBJECT
- Q_PROPERTY(QString readMarkerEventId READ readMarkerEventId WRITE markMessagesAsRead NOTIFY readMarkerPromoted)
+ Q_PROPERTY(QString readMarkerEventId READ readMarkerEventId WRITE markMessagesAsRead NOTIFY readMarkerMoved)
public:
- using Timeline = Owning< std::deque<Event*> >;
+ using Timeline = std::deque<TimelineItem>;
Room(Connection* connection, QString id);
virtual ~Room();
@@ -119,7 +136,7 @@ namespace QMatrixClient
void highlightCountChanged(Room* room);
void notificationCountChanged(Room* room);
void lastReadEventChanged(User* user);
- void readMarkerPromoted();
+ void readMarkerMoved();
void unreadMessagesChanged(Room* room);
protected:
@@ -135,8 +152,6 @@ namespace QMatrixClient
void addNewMessageEvents(Events events);
void addHistoricalMessageEvents(Events events);
-
- void setLastReadEvent(User* user, Event* event);
};
class MemberSorter