aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-11-22 13:00:33 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2018-11-22 16:53:57 +0900
commit0c3a45356a803baa0eb5e553262a85cac897ac4f (patch)
treefea3f4964ff8de340b63e5c289cc64bc7c5d7a3b
parent7f6dec0676123629d2cdf9da7640c1e17566ed3d (diff)
downloadlibquotient-0c3a45356a803baa0eb5e553262a85cac897ac4f.tar.gz
libquotient-0c3a45356a803baa0eb5e553262a85cac897ac4f.zip
Room: Change enum, Changes flag set, and changed() signal
This allows to batch updates into signals being emitted only once per sync. Also supercedes emitNamesChanged flag used in a few places.
-rw-r--r--lib/room.cpp49
-rw-r--r--lib/room.h28
2 files changed, 54 insertions, 23 deletions
diff --git a/lib/room.cpp b/lib/room.cpp
index e5653258..55923ed8 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -192,7 +192,7 @@ class Room::Private
is<RoomMessageEvent>(*ti);
}
- bool addNewMessageEvents(RoomEvents&& events);
+ Changes addNewMessageEvents(RoomEvents&& events);
void addHistoricalMessageEvents(RoomEvents&& events);
/** Move events into the timeline
@@ -1116,7 +1116,7 @@ void Room::updateData(SyncRoomData&& data)
for (auto&& event: data.accountData)
processAccountDataEvent(move(event));
- bool emitNamesChanged = false;
+ Changes roomChanges = Change::NoChange;
if (!data.state.empty())
{
et.restart();
@@ -1125,7 +1125,7 @@ void Room::updateData(SyncRoomData&& data)
const auto& evt = *eptr;
Q_ASSERT(evt.isStateEvent());
d->baseState[{evt.matrixType(),evt.stateKey()}] = move(eptr);
- emitNamesChanged |= processStateEvent(evt);
+ roomChanges |= processStateEvent(evt);
}
if (data.state.size() > 9 || et.nsecsElapsed() >= profilerMinNsecs())
@@ -1135,13 +1135,17 @@ void Room::updateData(SyncRoomData&& data)
if (!data.timeline.empty())
{
et.restart();
- emitNamesChanged |= d->addNewMessageEvents(move(data.timeline));
+ roomChanges |= d->addNewMessageEvents(move(data.timeline));
if (data.timeline.size() > 9 || et.nsecsElapsed() >= profilerMinNsecs())
qCDebug(PROFILER) << "*** Room::addNewMessageEvents():"
<< data.timeline.size() << "event(s)," << et;
}
- if (emitNamesChanged)
+ if (roomChanges&TopicChange)
+ emit topicChanged();
+
+ if (roomChanges&NameChange)
emit namesChanged(this);
+
d->updateDisplayname();
for( auto&& ephemeralEvent: data.ephemeral )
@@ -1165,6 +1169,8 @@ void Room::updateData(SyncRoomData&& data)
d->notificationCount = data.notificationCount;
emit notificationCountChanged(this);
}
+ if (roomChanges != Change::NoChange)
+ emit changed(roomChanges);
}
QString Room::Private::sendEvent(RoomEventPtr&& event)
@@ -1670,11 +1676,11 @@ inline bool isRedaction(const RoomEventPtr& ep)
return is<RedactionEvent>(*ep);
}
-bool Room::Private::addNewMessageEvents(RoomEvents&& events)
+Room::Changes Room::Private::addNewMessageEvents(RoomEvents&& events)
{
dropDuplicateEvents(events);
if (events.empty())
- return false;
+ return Change::NoChange;
// Pre-process redactions so that events that get redacted in the same
// batch landed in the timeline already redacted.
@@ -1704,9 +1710,9 @@ bool Room::Private::addNewMessageEvents(RoomEvents&& events)
// clients historically expect. This may eventually change though if we
// postulate that the current state is only current between syncs but not
// within a sync.
- bool emitNamesChanged = false;
+ Changes stateChanges = Change::NoChange;
for (const auto& eptr: events)
- emitNamesChanged |= q->processStateEvent(*eptr);
+ stateChanges |= q->processStateEvent(*eptr);
auto timelineSize = timeline.size();
auto totalInserted = 0;
@@ -1775,7 +1781,7 @@ bool Room::Private::addNewMessageEvents(RoomEvents&& events)
}
Q_ASSERT(timeline.size() == timelineSize + totalInserted);
- return emitNamesChanged;
+ return stateChanges;
}
void Room::Private::addHistoricalMessageEvents(RoomEvents&& events)
@@ -1819,10 +1825,10 @@ void Room::Private::addHistoricalMessageEvents(RoomEvents&& events)
<< insertedSize << "event(s)," << et;
}
-bool Room::processStateEvent(const RoomEvent& e)
+Room::Changes Room::processStateEvent(const RoomEvent& e)
{
if (!e.isStateEvent())
- return false;
+ return Change::NoChange;
d->currentState[{e.matrixType(),e.stateKey()}] =
static_cast<const StateEventBase*>(&e);
@@ -1831,23 +1837,22 @@ bool Room::processStateEvent(const RoomEvent& e)
return visit(e
, [] (const RoomNameEvent&) {
- return true;
+ return NameChange;
}
, [] (const RoomAliasesEvent&) {
- return true;
+ return OtherChange;
}
, [this] (const RoomCanonicalAliasEvent& evt) {
setObjectName(evt.alias().isEmpty() ? d->id : evt.alias());
- return true;
+ return CanonicalAliasChange;
}
- , [this] (const RoomTopicEvent&) {
- emit topicChanged();
- return false;
+ , [] (const RoomTopicEvent&) {
+ return TopicChange;
}
, [this] (const RoomAvatarEvent& evt) {
if (d->avatar.updateUrl(evt.url()))
emit avatarChanged();
- return false;
+ return AvatarChange;
}
, [this] (const RoomMemberEvent& evt) {
auto* u = user(evt.userId());
@@ -1886,11 +1891,11 @@ bool Room::processStateEvent(const RoomEvent& e)
emit userRemoved(u);
}
}
- return false;
+ return MembersChange;
}
, [this] (const EncryptionEvent&) {
- emit encryption();
- return false;
+ emit encryption(); // It can only be done once, so emit it here.
+ return EncryptionOn;
}
);
}
diff --git a/lib/room.h b/lib/room.h
index b741e229..ab8298d4 100644
--- a/lib/room.h
+++ b/lib/room.h
@@ -104,6 +104,24 @@ namespace QMatrixClient
using rev_iter_t = Timeline::const_reverse_iterator;
using timeline_iter_t = Timeline::const_iterator;
+ enum Change : uint {
+ NoChange = 0x0,
+ NameChange = 0x1,
+ CanonicalAliasChange = 0x2,
+ TopicChange = 0x4,
+ UnreadNotifsChange = 0x8,
+ AvatarChange = 0x10,
+ JoinStateChange = 0x20,
+ TagsChange = 0x40,
+ MembersChange = 0x80,
+ EncryptionOn = 0x100,
+ AccountDataChange = 0x200,
+ OtherChange = 0x1000,
+ AnyChange = 0x1FFF
+ };
+ Q_DECLARE_FLAGS(Changes, Change)
+ Q_FLAG(Changes)
+
Room(Connection* connection, QString id, JoinState initialJoinState);
~Room() override;
@@ -382,6 +400,13 @@ namespace QMatrixClient
void pendingEventDiscarded();
void pendingEventChanged(int pendingEventIndex);
+ /** A common signal for various kinds of changes in the room
+ * Aside from all changes in the room state
+ * @param changes a set of flags describing what changes occured
+ * upon the last sync
+ * \sa StateChange
+ */
+ void changed(Changes changes);
/**
* \brief The room name, the canonical alias or other aliases changed
*
@@ -441,7 +466,7 @@ namespace QMatrixClient
protected:
/// Returns true if any of room names/aliases has changed
- virtual bool processStateEvent(const RoomEvent& e);
+ virtual Changes processStateEvent(const RoomEvent& e);
virtual void processEphemeralEvent(EventPtr&& event);
virtual void processAccountDataEvent(EventPtr&& event);
virtual void onAddNewTimelineEvents(timeline_iter_t /*from*/) { }
@@ -474,3 +499,4 @@ namespace QMatrixClient
};
} // namespace QMatrixClient
Q_DECLARE_METATYPE(QMatrixClient::FileTransferInfo)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMatrixClient::Room::Changes)