aboutsummaryrefslogtreecommitdiff
path: root/connection.cpp
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2017-09-16 20:39:36 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2017-09-16 20:40:12 +0900
commit726f8d464f4b29f6fd3dc92fa5493e239970b209 (patch)
tree523a3b9e1629cb63e40284a28d5fafbd72bd1a9b /connection.cpp
parent6b40c313f8e4a0964e857973d8f9636a9f833f9d (diff)
downloadlibquotient-726f8d464f4b29f6fd3dc92fa5493e239970b209.tar.gz
libquotient-726f8d464f4b29f6fd3dc92fa5493e239970b209.zip
provideRoom: Added invitedRoom() signal; fixed issues with some transitions
Notably: * setJoinState() invocation has been missing from the previous code * processing invites did not take into account that a Leave state may already exist, thereby forcing clients that display left rooms to look through their records just in case they have to replace a Leave with Invite. * joinedRoom() was emitted even when the room is not newly joined.
Diffstat (limited to 'connection.cpp')
-rw-r--r--connection.cpp57
1 files changed, 32 insertions, 25 deletions
diff --git a/connection.cpp b/connection.cpp
index fdf58e9e..513d9242 100644
--- a/connection.cpp
+++ b/connection.cpp
@@ -299,26 +299,28 @@ 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
+ // Room transitions:
+ // 1. none -> Invite: r=createRoom, emit invitedRoom(r,null)
+ // 2. none -> Join: r=createRoom, emit joinedRoom(r,null)
+ // 3. none -> Leave: r=createRoom, emit leftRoom(r,null)
+ // 4. inv=Invite -> Join: r=createRoom, emit joinedRoom(r,inv), delete Invite
+ // 4a. Leave, inv=Invite -> Join: change state, emit joinedRoom(r,inv), delete Invite
+ // 5. inv=Invite -> Leave: r=createRoom, emit leftRoom(r,inv), delete Invite
+ // 5a. r=Leave, inv=Invite -> Leave: emit leftRoom(r,inv), delete Invite
+ // 6. Join -> Leave: change state
+ // 7. r=Leave -> Invite: inv=createRoom, emit invitedRoom(inv,r)
+ // 8. Leave -> (changes to) Join
const auto roomKey = qMakePair(id, joinState == JoinState::Invite);
auto* room = d->roomMap.value(roomKey, nullptr);
- if (!room)
+ if (room)
+ {
+ // Leave is a special case because in transition (5a) above
+ // joinState == room->joinState but we still have to preempt the Invite
+ // and emit a signal. For Invite and Join, there's no such problem.
+ if (room->joinState() == joinState && joinState != JoinState::Leave)
+ return room;
+ }
+ else
{
room = createRoom(this, id, joinState);
if (!room)
@@ -326,20 +328,25 @@ Room* Connection::provideRoom(const QString& id, JoinState joinState)
qCCritical(MAIN) << "Failed to create a room" << id;
return nullptr;
}
- qCDebug(MAIN) << "Created Room" << id << ", invited:" << roomKey.second;
-
d->roomMap.insert(roomKey, room);
+ qCDebug(MAIN) << "Created Room" << id << ", invited:" << roomKey.second;
emit newRoom(room);
}
-
- if (joinState != JoinState::Invite)
+ if (joinState == JoinState::Invite)
+ {
+ // prev is either Leave or nullptr
+ auto* prev = d->roomMap.value({id, false}, nullptr);
+ emit invitedRoom(room, prev);
+ }
+ else
{
+ room->setJoinState(joinState);
// Preempt the Invite room (if any) with a room in Join/Leave state.
- auto prevInvite = d->roomMap.take({id, true});
+ auto* prevInvite = d->roomMap.take({id, true});
if (joinState == JoinState::Join)
- joinedRoom(room, prevInvite);
+ emit joinedRoom(room, prevInvite);
else if (joinState == JoinState::Leave)
- leftRoom(room, prevInvite);
+ emit leftRoom(room, prevInvite);
if (prevInvite)
{
qCDebug(MAIN) << "Deleting Invite state for room" << prevInvite->id();