diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-10-03 19:51:20 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-10-03 19:51:20 +0200 |
commit | df8cbfada237cb4c0467215b55ccb697cc64d568 (patch) | |
tree | 93d00e7528eaf94b6326f748d7f466eb58f295bd /plugins | |
parent | 8f6803c25a46fd95e6e65858f4aaa9131e54c6c5 (diff) |
Matrix: attempt to fix threading issues
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/Matrix.hpp | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index be4a59c..de7d9b8 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -6,11 +6,16 @@ #include <json/value.h> namespace QuickMedia { + struct RoomData; + struct UserInfo { + friend struct RoomData; + std::string user_id; std::string display_name; std::string avatar_url; sf::Color display_name_color; + private: std::string read_marker_event_id; }; @@ -23,8 +28,7 @@ namespace QuickMedia { }; struct Message { - // Index into |RoomData.user_info| - size_t user_id; + std::shared_ptr<UserInfo> user; std::string event_id; std::string body; std::string url; @@ -36,19 +40,38 @@ namespace QuickMedia { }; struct RoomData { + std::shared_ptr<UserInfo> get_user_by_id(const std::string &user_id); + void add_user(std::shared_ptr<UserInfo> user); + + void set_user_read_marker(std::shared_ptr<UserInfo> &user, const std::string &event_id); + std::string get_user_read_marker(std::shared_ptr<UserInfo> &user); + + void prepend_messages_reverse(std::vector<std::shared_ptr<Message>> new_messages); + void append_messages(std::vector<std::shared_ptr<Message>> new_messages); + + std::shared_ptr<Message> get_message_by_id(const std::string &id); + + std::vector<std::shared_ptr<UserInfo>> get_users_excluding_me(const std::string &my_user_id); + + void acquire_room_lock(); + void release_room_lock(); + + const std::vector<std::shared_ptr<Message>>& get_messages_thread_unsafe() const; + std::string id; - // Each room has its own list of user data, even if multiple rooms has the same user - // because users can have different display names and avatars in different rooms. - // The value is an index to |user_info|. - std::unordered_map<std::string, size_t> user_info_by_user_id; - std::vector<UserInfo> user_info; - std::vector<std::shared_ptr<Message>> messages; - std::unordered_map<std::string, std::shared_ptr<Message>> message_by_event_id; std::string name; std::string avatar_url; std::string prev_batch; bool initial_fetch_finished = false; size_t last_read_index = 0; + private: + std::mutex user_mutex; + std::mutex room_mutex; + // Each room has its own list of user data, even if multiple rooms has the same user + // because users can have different display names and avatars in different rooms. + std::unordered_map<std::string, std::shared_ptr<UserInfo>> user_info_by_user_id; + std::vector<std::shared_ptr<Message>> messages; + std::unordered_map<std::string, std::shared_ptr<Message>> message_by_event_id; }; enum class MessageDirection { @@ -64,7 +87,7 @@ namespace QuickMedia { std::string content_uri; }; - using RoomSyncMessages = std::unordered_map<RoomData*, std::vector<std::shared_ptr<Message>>>; + using RoomSyncMessages = std::unordered_map<std::shared_ptr<RoomData>, std::vector<std::shared_ptr<Message>>>; class Matrix : public Plugin { public: @@ -106,27 +129,30 @@ namespace QuickMedia { PluginResult set_read_marker(const std::string &room_id, const Message *message); // |message| is from |BodyItem.userdata| and is of type |Message*| - bool was_message_posted_by_me(const std::string &room_id, void *message) const; + bool was_message_posted_by_me(void *message); - std::string message_get_author_displayname(RoomData *room_data, Message *message) const; + std::string message_get_author_displayname(Message *message) const; // Cached PluginResult get_config(int *upload_size); - // Note: the returned UserInfo is o - const UserInfo* get_me(const std::string &room_id) const; + std::shared_ptr<UserInfo> get_me(const std::string &room_id); private: PluginResult sync_response_to_body_items(const Json::Value &root, RoomSyncMessages &room_messages); - PluginResult get_previous_room_messages(const std::string &room_id, RoomData *room_data); + PluginResult get_previous_room_messages(std::shared_ptr<RoomData> &room_data); void events_add_user_info(const Json::Value &events_json, RoomData *room_data); void events_add_user_read_markers(const Json::Value &events_json, RoomData *room_data); - void events_add_messages(const Json::Value &events_json, RoomData *room_data, MessageDirection message_dir, RoomSyncMessages *room_messages, bool has_unread_notifications); + void events_add_messages(const Json::Value &events_json, std::shared_ptr<RoomData> &room_data, MessageDirection message_dir, RoomSyncMessages *room_messages, bool has_unread_notifications); void events_set_room_name(const Json::Value &events_json, RoomData *room_data); PluginResult upload_file(const std::string &room_id, const std::string &filepath, UploadInfo &file_info, UploadInfo &thumbnail_info, std::string &err_msg); std::shared_ptr<Message> get_edited_message_original_message(RoomData *room_data, std::shared_ptr<Message> message); + + std::shared_ptr<RoomData> get_room_by_id(const std::string &id); + void add_room(std::shared_ptr<RoomData> room); private: - std::unordered_map<std::string, std::unique_ptr<RoomData>> room_data_by_id; + std::unordered_map<std::string, std::shared_ptr<RoomData>> room_data_by_id; + std::mutex room_data_mutex; std::string user_id; std::string username; std::string access_token; |