diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-10-21 21:32:51 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-10-21 22:31:36 +0200 |
commit | 0d8293a5647c2bb10228658f0910515b38ff0d64 (patch) | |
tree | e97c10442c73e330672277940aaf0b38d2fc63eb /src/QuickMedia.cpp | |
parent | 87fb6e5c0cce6e6aba8f646329af6f8070d27c63 (diff) |
Workaround sfml image loading thread race condition
See: https://github.com/SFML/SFML/issues/1711
Also some other smaller changes
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r-- | src/QuickMedia.cpp | 67 |
1 files changed, 49 insertions, 18 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index f944e7d..48ef01b 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -19,6 +19,7 @@ #include "../include/base64_url.hpp" #include "../include/Entry.hpp" #include "../include/NetUtils.hpp" +#include "../include/SfmlFixes.hpp" #include <assert.h> #include <cmath> @@ -926,7 +927,7 @@ namespace QuickMedia { } for(Tab &tab : tabs) { - tab.body->thumbnail_resize_target_size = tab.page->get_max_thumbnail_size(); + tab.body->thumbnail_max_size = tab.page->get_thumbnail_max_size(); } const Json::Value *json_chapters = &Json::Value::nullSingleton(); @@ -1837,7 +1838,7 @@ namespace QuickMedia { if(get_file_type(image_path) == FileType::REGULAR && upscaled_ok) { sf::Image image; - if(image.loadFromFile(image_path.data)) { + if(load_image_from_file(image, image_path.data)) { if(image_texture.loadFromImage(image)) { image_texture.setSmooth(true); image_texture.generateMipmap(); @@ -2346,7 +2347,8 @@ namespace QuickMedia { DownloadResult download_image_result = download_to_string(challenge_info.payload_url, payload_image_data, {}, is_tor_enabled()); if(download_image_result == DownloadResult::OK) { std::lock_guard<std::mutex> lock(captcha_image_mutex); - if(captcha_texture.loadFromMemory(payload_image_data.data(), payload_image_data.size())) { + sf::Image captcha_image; + if(load_image_from_memory(captcha_image, payload_image_data.data(), payload_image_data.size()) && captcha_texture.loadFromImage(captcha_image)) { captcha_texture.setSmooth(true); captcha_sprite.setTexture(captcha_texture, true); challenge_description_text.setString(challenge_info.description); @@ -2704,7 +2706,8 @@ namespace QuickMedia { downloading_image = false; image_data = load_image_future.get(); - if(attached_image_texture->loadFromMemory(image_data.data(), image_data.size())) { + sf::Image attached_image; + if(load_image_from_memory(attached_image, image_data.data(), image_data.size()) && attached_image_texture->loadFromImage(attached_image)) { attached_image_texture->setSmooth(true); //attached_image_texture->generateMipmap(); attached_image_sprite.setTexture(*attached_image_texture, true); @@ -2943,7 +2946,7 @@ namespace QuickMedia { messages_tab.type = ChatTabType::MESSAGES; messages_tab.body = std::make_unique<Body>(this, font.get(), bold_font.get(), cjk_font.get(), loading_icon); messages_tab.body->draw_thumbnails = true; - messages_tab.body->thumbnail_resize_target_size = CHAT_MESSAGE_THUMBNAIL_MAX_SIZE; + messages_tab.body->thumbnail_max_size = CHAT_MESSAGE_THUMBNAIL_MAX_SIZE; messages_tab.body->thumbnail_mask_shader = &circle_mask_shader; //messages_tab.body->line_separator_color = sf::Color::Transparent; messages_tab.text = sf::Text("Messages", *font, tab_text_size); @@ -2967,8 +2970,28 @@ namespace QuickMedia { RoomData *current_room = nullptr; bool is_window_focused = window.hasFocus(); + // Returns -1 if no rooms or no unread rooms + auto find_top_body_position_for_unread_room = [&tabs](BodyItem *item_to_swap, int start_index) { + for(int i = start_index; i < (int)tabs[ROOMS_TAB_INDEX].body->items.size(); ++i) { + const auto &body_item = tabs[ROOMS_TAB_INDEX].body->items[i]; + if(static_cast<RoomData*>(body_item->userdata)->last_message_read || body_item.get() == item_to_swap) + return i; + } + return -1; + }; + + // Returns -1 if no rooms or all rooms have unread mentions + auto find_top_body_position_for_mentioned_room = [&tabs](BodyItem *item_to_swap, int start_index) { + for(int i = start_index; i < (int)tabs[ROOMS_TAB_INDEX].body->items.size(); ++i) { + const auto &body_item = tabs[ROOMS_TAB_INDEX].body->items[i]; + if(!static_cast<RoomData*>(body_item->userdata)->has_unread_mention || body_item.get() == item_to_swap) + return i; + } + return -1; + }; + auto process_new_room_messages = - [this, &selected_tab, ¤t_room, &is_window_focused, &tabs] + [this, &selected_tab, ¤t_room, &is_window_focused, &tabs, &find_top_body_position_for_unread_room, &find_top_body_position_for_mentioned_room] (RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable { for(auto &[room, messages] : room_sync_messages) { @@ -2982,7 +3005,6 @@ namespace QuickMedia { } } - bool has_unread_messages = false; for(auto &[room, messages] : room_sync_messages) { if(messages.empty()) continue; @@ -3010,13 +3032,32 @@ namespace QuickMedia { assert(room_body_item); if(last_unread_message) { - has_unread_messages = true; std::string room_desc = "Unread: " + matrix->message_get_author_displayname(last_unread_message) + ": " + extract_first_line(last_unread_message->body, 150); if(room->has_unread_mention) room_desc += "\n** You were mentioned **"; // TODO: Better notification? room_body_item->set_description(std::move(room_desc)); room_body_item->set_title_color(sf::Color(255, 100, 100)); room->last_message_read = false; + + // Swap order of rooms in body list to put rooms with mentions at the top and then unread messages and then all the other rooms + // TODO: Optimize with hash map instead of linear search? or cache the index + Body *rooms_body = tabs[ROOMS_TAB_INDEX].body.get(); + int room_body_index = rooms_body->get_index_by_body_item(room_body_item); + if(room_body_index != -1) { + std::shared_ptr<BodyItem> body_item = rooms_body->items[room_body_index]; + int body_swap_index = -1; + if(room->has_unread_mention) + body_swap_index = find_top_body_position_for_mentioned_room(body_item.get(), 0); + else if(!room->last_message_read) + body_swap_index = find_top_body_position_for_unread_room(body_item.get(), 0); + if(body_swap_index != -1 && body_swap_index != room_body_index) { + rooms_body->items.erase(rooms_body->items.begin() + room_body_index); + if(body_swap_index < room_body_index) + rooms_body->items.insert(rooms_body->items.begin() + body_swap_index, std::move(body_item)); + else + rooms_body->items.insert(rooms_body->items.begin() + (body_swap_index - 1), std::move(body_item)); + } + } } else if(is_first_sync) { Message *last_unread_message = nullptr; for(auto it = messages.rbegin(), end = messages.rend(); it != end; ++it) { @@ -3029,16 +3070,6 @@ namespace QuickMedia { room_body_item->set_description(matrix->message_get_author_displayname(last_unread_message) + ": " + extract_first_line(last_unread_message->body, 150)); } } - - if(has_unread_messages) { - std::sort(tabs[ROOMS_TAB_INDEX].body->items.begin(), tabs[ROOMS_TAB_INDEX].body->items.end(), [](std::shared_ptr<BodyItem> &item1, std::shared_ptr<BodyItem> &item2) { - RoomData *item1_room = static_cast<RoomData*>(item1->userdata); - RoomData *item2_room = static_cast<RoomData*>(item2->userdata); - int item1_presence_sum = (int)!item1_room->last_message_read + (int)item1_room->has_unread_mention; - int item2_presence_sum = (int)!item2_room->last_message_read + (int)item2_room->has_unread_mention; - return item1_presence_sum > item2_presence_sum; - }); - } }; enum class ChatState { |