Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render display names of users and rooms according to the spec - take 2 #4

Merged
merged 9 commits into from
May 3, 2016
Merged

Render display names of users and rooms according to the spec - take 2 #4

merged 9 commits into from
May 3, 2016

Conversation

KitsuneRal
Copy link
Member

Though it's yet incomplete (room names are on the way), I think you can start reviewing this. As you asked, I have split one big commit into smaller ones (and this is only the lib part, naturally). The code is backwards-compatible; however, I had to lay some leftovers for that - namely, User::displayname() and User::nameChanged(). Probably, they should be marked as deprecated in the /** docs */. I'll submit a separate PR on Quaternion later to reflect the newly introduced functionality in the UI.

@KitsuneRal
Copy link
Member Author

Revisiting the topic of user renaming and moving the signal to Connection:

  1. User::avatarChanged() is in the same position as User::nameChanged(), so the approach should be common for both.
  2. When moving the signal to Connection, as I've just realized, UserListModel will be spammed with unneeded signals from non-members of the room (in case such events arrive, though - but I wouldn't rule this out). On the other hand, this provides additional flexibility - we might want to use UserListModel, e.g., to display all users on the server at some point in time; the room context is irrelevant in such case.
  3. Using a signal on User level makes perfect sense when showing a window for that user. Sorry that I run too fast; User::nameChanged/avatarChanged should stay as well. I guess the right way would be to connect User::nameChanged to Connection::userRenamed in that case.

Therefore I'll remove the last commit (about deprecating User::nameChanged), connect the two signals and add Connection::avatarChanged "mediation signal" in a similar fashion - in the same PR, if you don't mind.

@KitsuneRal
Copy link
Member Author

Just a notice: because I force-pushed the branch, some commits shifted later than comments referring to them. In case you already started reviewing - I amended 8d56fcf to only emit one signal.

}

Room* room = roomMap.value(id, nullptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be easier to read this way:

if( roomMap.contains(id) )
    return roomMap.value(id);

It might be a bit slower than your version, but I don't think it matters much (it's a hashmap, so we have O(1) complexity)

What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a matter of personal taste, as for me. Since you drive the car, I willingly comply :)

@Fxrh
Copy link
Contributor

Fxrh commented May 1, 2016

FIrst: Thanks for the PR and sorry it took so long!

I'm not quite sure about moving the nameChanged and avatarChanged signals to the Connection class. Imho that belongs to the User class and I'd like to make sure Connection doesn't evolve into a god class (it is already quite big).
It is correct that this would reduce the number of connections, but I don't think they are that expensive. Do you have any information here?

@KitsuneRal
Copy link
Member Author

Regarding signal connections - basically, it's memory that we are wasting. Since connections are stored in hash map, access time doesn't really change when this map grows. As for memory - each connection is at least four pointers big, which (with 32 bit pointers) brings at least 4x4x(number of connections) bytes needed to store the map (not counting the map's own overhead). Probably, 8Mb+ is not so much these days - but still looks quite a waste.
And yeah, Connection is a bit of a god class already. Gotta do something with it.
To summarise, I don't have a clear solution here. I'd still prefer to save on multiplying connections, but it needs some mediator class (if not Connection).

@KitsuneRal
Copy link
Member Author

I rebased and amended the branch according to the minor comments. Regarding connections and Connection (pun intended :) ) - let's discuss separately (it might be a good idea to separate this part into another PR).

In particular, this will be needed to render room names according to the CS spec.
…CS spec.

According to section 11.2.2.3 of the CS spec, clients SHOULD follow a certain algorithm of making a non-ambiguous display name of a user in the room context. This algorithm implies checking whether other room members have the same display name. This commit prepares for implementation of the algorithm:

1. Use a hash map instead of a list to store room members. The external Room::users() API is kept intact.
2. Convenience CRUD methods are implemented to deal with the hash map.
3. An additional slot for user renaming is introduced (because renaming affects the hash map). Binding of actual signals is left for the next commit.
4. nullptr is the recommended representation of a null pointer since C++11. Use that and mandate compiler support of that.
…red on a displayname update.

This changes the way displayname is supplied to a client application - instead of calculating immediately, displayname becomes a separate stored value that is refreshed with every change of the list of members, or the name, or the canonical alias. displaynameChanged signal is supplied to subscribe to these updates: in case of displaying a room in the roomlist a client should use this new signal instead of Room::namesChanged.
The displaname calculation algorithm is described in section 11.2.2.5 of the CS spec: https://matrix.org/docs/spec/r0.0.1/client_server.html#calculating-the-display-name-for-a-room
@KitsuneRal
Copy link
Member Author

Reworked the branch once more to remove two commits about Connection:: signals and connections to them. A PR for organising signals for user events will come separately, and probably not soon - I'll think how to consolidate signals through another mediator than Connection. Therefore, the current PR should be clear to merge with respect to all your comments.

…named signal, which clients should use in the room context.

Processing changes of user displaynames is tricky: we have to not only deal with the currently renamed user but also with its past and new namesakes which might change representation due to that renaming. So in the worst case a single User::nameChanged signal may lead to three Room::memberRenamed references (and 3 user displaynames updated in the UI, respectively). And the newly added users should be taken care of in a similar manner, of course.
@KitsuneRal
Copy link
Member Author

KitsuneRal commented May 2, 2016

Here's one more commit to take care of user renamings. Turned out to be quite non-trivial; the good news though is that solving this problem also solved the question regarding signals mediator. As it turns out, every room has to process each renaming anyway because it causes potential disambiguations (even for users that did not rename themselves). So the best thing to do here for consolidation is to throw all user renaming signals into all rooms which is quite a bit of signal-slot spam (and it's worse than having additional megabytes of memory consumed instead). So, there you have it - no consolidated signals. The updated PR for the Quaternion part will come later.

@Fxrh
Copy link
Contributor

Fxrh commented May 3, 2016

Looks all good now :) Thanks for your work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants