From 7ce2139650012d4c571c7e7600924853ab7032bb Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 5 Aug 2019 22:25:52 +0200 Subject: Load thumbnails in separate thread --- include/Body.hpp | 7 ++++++- src/Body.cpp | 31 ++++++++++++++++++++----------- src/QuickMedia.cpp | 2 +- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/include/Body.hpp b/include/Body.hpp index c27ecf0..e09017d 100644 --- a/include/Body.hpp +++ b/include/Body.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace QuickMedia { class BodyItem { @@ -43,6 +44,10 @@ namespace QuickMedia { sf::Text title_text; int selected_item; std::vector> items; - std::vector> item_thumbnail_textures; + std::vector> item_thumbnail_textures; + std::thread thumbnail_load_thread; + private: + std::shared_ptr load_thumbnail_from_url(const std::string &url); + bool loading_thumbnail; }; } \ No newline at end of file diff --git a/src/Body.cpp b/src/Body.cpp index b9dd050..d391e87 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -9,7 +9,7 @@ const sf::Color front_color(43, 45, 47); const sf::Color back_color(33, 35, 37); namespace QuickMedia { - Body::Body(sf::Font &font) : title_text("", font, 14), selected_item(0) { + Body::Body(sf::Font &font) : title_text("", font, 14), selected_item(0), loading_thumbnail(false) { title_text.setFillColor(sf::Color::White); } @@ -81,21 +81,27 @@ namespace QuickMedia { } } - static std::unique_ptr load_texture_from_url(const std::string &url) { - auto result = std::make_unique(); + std::shared_ptr Body::load_thumbnail_from_url(const std::string &url) { + auto result = std::make_shared(); result->setSmooth(true); - std::string texture_data; - if(download_to_string(url, texture_data) == DownloadResult::OK) { - if(result->loadFromMemory(texture_data.data(), texture_data.size())) - result->generateMipmap(); - } + assert(!loading_thumbnail); + loading_thumbnail = true; + thumbnail_load_thread = std::thread([this, result, url]() { + std::string texture_data; + if(download_to_string(url, texture_data) == DownloadResult::OK) { + if(result->loadFromMemory(texture_data.data(), texture_data.size())) + result->generateMipmap(); + } + loading_thumbnail = false; + }); + thumbnail_load_thread.detach(); return result; } // TODO: Skip drawing the rows that are outside the window. // TODO: Use a render target for the whole body so all images can be put into one. // TODO: Only load images once they are visible on the screen. - // TODO: Load images asynchronously to prevent scroll lag and to improve load time of suggestions. + // TODO: Load thumbnails with more than one thread. void Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size) { const float font_height = title_text.getCharacterSize() + 8.0f; const float image_height = 100.0f; @@ -129,8 +135,8 @@ namespace QuickMedia { float row_height = font_height; if(draw_thumbnail) { row_height = image_height; - if(!item_thumbnail) - item_thumbnail = load_texture_from_url(item->thumbnail_url); + if(!item_thumbnail && !loading_thumbnail) + item_thumbnail = load_thumbnail_from_url(item->thumbnail_url); } sf::Vector2f item_pos = pos; @@ -152,6 +158,8 @@ namespace QuickMedia { float text_offset_x = 0.0f; if(draw_thumbnail) { + // TODO: Verify if this is safe. The thumbnail is being modified in another thread + // and it might not be fully finished before the native handle is set? if(item_thumbnail && item_thumbnail->getNativeHandle() != 0) { image.setTexture(*item_thumbnail, true); auto image_size = image.getTexture()->getSize(); @@ -166,6 +174,7 @@ namespace QuickMedia { } else { image_fallback.setPosition(item_pos); window.draw(image_fallback); + text_offset_x = image_fallback.getSize().x; } } diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index ed3ad77..3285eb9 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -370,7 +370,7 @@ namespace QuickMedia { sf::Text chapter_text(std::string("Page ") + std::to_string(image_index + 1) + "/" + std::to_string(num_images), font, 14); if(image_index == num_images) - chapter_text.setString("end"); + chapter_text.setString("End"); chapter_text.setFillColor(sf::Color::White); sf::RectangleShape chapter_text_background; chapter_text_background.setFillColor(sf::Color(0, 0, 0, 150)); -- cgit v1.2.3