Skip to content

Commit

Permalink
Better API for clients to catch up on room list changes
Browse files Browse the repository at this point in the history
joinedRoom() and leftRoom() now pass the preempted Invite state of the
room as well; roomMap() only returns Invite and Join rooms, not Leave.
  • Loading branch information
KitsuneRal committed Sep 14, 2017
1 parent 65b3e8d commit 9195480
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 18 deletions.
57 changes: 42 additions & 15 deletions connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,18 @@ int Connection::millisToReconnect() const
return d->syncJob ? d->syncJob->millisToRetry() : 0;
}

const QHash< QPair<QString, bool>, Room* >& Connection::roomMap() const
QHash< QPair<QString, bool>, Room* > Connection::roomMap() const
{
return d->roomMap;
// Copy-on-write-and-remove-elements is faster than copying elements one by one.
QHash< QPair<QString, bool>, Room* > roomMap = d->roomMap;
for (auto it = roomMap.begin(); it != roomMap.end(); )
{
if (it.value()->joinState() == JoinState::Leave)
it = roomMap.erase(it);
else
++it;
}
return roomMap;
}

const ConnectionData* Connection::connectionData() const
Expand All @@ -290,35 +299,53 @@ Room* Connection::provideRoom(const QString& id, JoinState joinState)
return nullptr;
}

// Room transitions from the Connection standpoint:
// - none -> (new) Invite
// - none -> (new) Join
// - none -> (new) Leave
// - Invite -> (new) Join replaces Invite (deleted)
// - Invite -> (new) Leave (archived) replaces Invite (deleted)
// - Join -> (moves to) Leave
// - Leave -> (new) Invite, Leave
// - Leave -> (moves to) Join
// Room transitions from the user's standpoint (what's seen in signals):
// - none -> Invite: newRoom(Invite)
// - none -> Join: newRoom(Join) or Room::joinStateChanged(Join); joinedRoom
// - Invite -> Invite replaced with Join:
// newRoom(Join); joinedRoom; aboutToDeleteRoom(Invite)
// - Invite -> Invite replaced with Leave (none):
// newRoom(Leave); leftRoom; aboutToDeleteRoom(Invite)
// - Join -> Leave (none): leftRoom
const auto roomKey = qMakePair(id, joinState == JoinState::Invite);
auto* room = d->roomMap.value(roomKey, nullptr);
if (!room)
{
room = createRoom(this, id, joinState);
if (!room)
{
qCritical() << "Failed to create a room!!!" << id;
qCCritical(MAIN) << "Failed to create a room" << id;
return nullptr;
}
qCDebug(MAIN) << "Created Room" << id << ", invited:" << roomKey.second;

d->roomMap.insert(roomKey, room);
emit newRoom(room);
}
else if (room->joinState() != joinState)
{
room->setJoinState(joinState);
if (joinState == JoinState::Leave)
emit leftRoom(room);
else if (joinState == JoinState::Join)
emit joinedRoom(room);
}

if (joinState != JoinState::Invite && d->roomMap.contains({id, true}))
if (joinState != JoinState::Invite)
{
// Preempt the Invite room after it's been acted upon (joined or left).
qCDebug(MAIN) << "Deleting invited state";
delete d->roomMap.take({id, true});
// Preempt the Invite room (if any) with a room in Join/Leave state.
auto prevInvite = d->roomMap.take({id, true});
if (joinState == JoinState::Join)
joinedRoom(room, prevInvite);
else if (joinState == JoinState::Leave)
leftRoom(room, prevInvite);
if (prevInvite)
{
qCDebug(MAIN) << "Deleting Invite state for room" << prevInvite->id();
emit aboutToDeleteRoom(prevInvite);
delete prevInvite;
}
}

return room;
Expand Down
7 changes: 4 additions & 3 deletions connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace QMatrixClient
Connection();
virtual ~Connection();

const QHash<QPair<QString, bool>, Room*>& roomMap() const;
QHash<QPair<QString, bool>, Room*> roomMap() const;

Q_INVOKABLE virtual void resolveServer(const QString& domain);
Q_INVOKABLE virtual void connectToServer(const QString& user,
Expand Down Expand Up @@ -128,8 +128,9 @@ namespace QMatrixClient

void syncDone();
void newRoom(Room* room);
void joinedRoom(Room* room);
void leftRoom(Room* room);
void joinedRoom(Room* room, Room* prevInvite);
void leftRoom(Room* room, Room* prevInvite);
void aboutToDeleteRoom(Room* room);

void loginError(QString error);
void networkError(size_t nextAttempt, int inMilliseconds);
Expand Down

0 comments on commit 9195480

Please sign in to comment.