diff options
Diffstat (limited to 'src/Body.cpp')
-rw-r--r-- | src/Body.cpp | 132 |
1 files changed, 85 insertions, 47 deletions
diff --git a/src/Body.cpp b/src/Body.cpp index 812840d..08ef690 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -23,7 +23,8 @@ namespace QuickMedia { thumbnail_is_local(false), title_color(sf::Color::White), author_color(sf::Color::White), - userdata(nullptr) + userdata(nullptr), + last_drawn_time(0) { if(!_title.empty()) set_title(std::move(_title)); @@ -58,6 +59,7 @@ namespace QuickMedia { title_color = other.title_color; author_color = other.author_color; userdata = other.userdata; + last_drawn_time = other.last_drawn_time; } Body::Body(Program *program, sf::Font *font, sf::Font *bold_font, sf::Font *cjk_font) : @@ -279,6 +281,8 @@ namespace QuickMedia { sf::Vector2f scissor_size = size; const float start_y = pos.y; + const sf::Int32 elapsed_time = draw_timer.getElapsedTime().asMilliseconds(); + if(thumbnail_resize_target_size.x != 0 && thumbnail_resize_target_size.y != 0) { image_max_height = thumbnail_resize_target_size.y; } @@ -294,11 +298,9 @@ namespace QuickMedia { int num_items = items.size(); if(num_items == 0 || size.y <= 0.0f) { - for(auto it = item_thumbnail_textures.begin(); it != item_thumbnail_textures.end();) { - if(!it->second->referenced) - it = item_thumbnail_textures.erase(it); - else - ++it; + item_thumbnail_textures.clear(); + for(auto &body_item : items) { + clear_body_item_cache(body_item.get()); } return; } @@ -307,41 +309,6 @@ namespace QuickMedia { thumbnail_it.second->referenced = false; } - for(auto &body_item : items) { - if(body_item->dirty) { - body_item->dirty = false; - // TODO: Find a way to optimize fromUtf8 - sf::String str = sf::String::fromUtf8(body_item->get_title().data(), body_item->get_title().data() + body_item->get_title().size()); - if(body_item->title_text) - body_item->title_text->setString(std::move(str)); - else - body_item->title_text = std::make_unique<Text>(std::move(str), font, cjk_font, 16, size.x - 50 - image_padding_x * 2.0f); - body_item->title_text->setFillColor(body_item->title_color); - body_item->title_text->updateGeometry(); - } - - if(body_item->dirty_description) { - body_item->dirty_description = false; - sf::String str = sf::String::fromUtf8(body_item->get_description().data(), body_item->get_description().data() + body_item->get_description().size()); - if(body_item->description_text) - body_item->description_text->setString(std::move(str)); - else - body_item->description_text = std::make_unique<Text>(std::move(str), font, cjk_font, 14, size.x - 50 - image_padding_x * 2.0f); - body_item->description_text->updateGeometry(); - } - - if(body_item->dirty_author) { - body_item->dirty_author = false; - sf::String str = sf::String::fromUtf8(body_item->get_author().data(), body_item->get_author().data() + body_item->get_author().size()); - if(body_item->author_text) - body_item->author_text->setString(std::move(str)); - else - body_item->author_text = std::make_unique<Text>(std::move(str), bold_font, cjk_font, 14, size.x - 50 - image_padding_x * 2.0f); - body_item->author_text->setFillColor(body_item->author_color); - body_item->author_text->updateGeometry(); - } - } - if(prev_selected_item < 0 || prev_selected_item >= (int)items.size()) { prev_selected_item = selected_item; } @@ -384,8 +351,6 @@ namespace QuickMedia { pos.y += page_scroll; sf::Vector2u window_size = window.getSize(); - glEnable(GL_SCISSOR_TEST); - glScissor(scissor_pos.x, (int)window_size.y - (int)scissor_pos.y - (int)scissor_size.y, scissor_size.x, scissor_size.y); sf::Vector2f prev_pos = pos; for(int i = selected_item - 1; i >= 0; --i) { @@ -395,13 +360,20 @@ namespace QuickMedia { if(!item->visible) continue; + update_dirty_state(item.get(), size); + float item_height = get_item_height(item.get()); prev_pos.y -= (item_height + spacing_y); if(prev_pos.y + item_height + spacing_y < start_y) break; + item->last_drawn_time = elapsed_time; + // This is needed here rather than above the loop, since update_dirty_text cant be called inside scissor because it corrupts the text for some reason + glEnable(GL_SCISSOR_TEST); + glScissor(scissor_pos.x, (int)window_size.y - (int)scissor_pos.y - (int)scissor_size.y, scissor_size.x, scissor_size.y); draw_item(window, item.get(), prev_pos, size, item_height, i, content_progress); + glDisable(GL_SCISSOR_TEST); ++num_visible_items; } @@ -413,6 +385,8 @@ namespace QuickMedia { if(!item->visible) continue; + update_dirty_state(item.get(), size); + float item_height = get_item_height(item.get()); if((after_pos.y - start_y) + item_height + spacing_y > size.y) @@ -423,7 +397,12 @@ namespace QuickMedia { if(after_pos.y - start_y >= size.y) break; + item->last_drawn_time = elapsed_time; + // This is needed here rather than above the loop, since update_dirty_text cant be called inside scissor because it corrupts the text for some reason + glEnable(GL_SCISSOR_TEST); + glScissor(scissor_pos.x, (int)window_size.y - (int)scissor_pos.y - (int)scissor_size.y, scissor_size.x, scissor_size.y); draw_item(window, item.get(), after_pos, size, item_height, i, content_progress); + glDisable(GL_SCISSOR_TEST); after_pos.y += item_height + spacing_y; ++num_visible_items; } @@ -431,17 +410,76 @@ namespace QuickMedia { if(last_fully_visible_item == -1) last_fully_visible_item = selected_item; - glDisable(GL_SCISSOR_TEST); - for(auto it = item_thumbnail_textures.begin(); it != item_thumbnail_textures.end();) { if(!it->second->referenced) it = item_thumbnail_textures.erase(it); else ++it; } + + // TODO: Only do this for items that are not visible, do not loop all items. + // TODO: Verify if this only runs for items that are not visible, and only once + // TODO: Improve performance! right now it can use up to 5-7% cpu with a lot of items! + for(auto &body_item : items) { + if(elapsed_time - body_item->last_drawn_time >= 1500) { + clear_body_item_cache(body_item.get()); + } + } + } + + void Body::update_dirty_state(BodyItem *body_item, sf::Vector2f size) { + if(body_item->dirty) { + body_item->dirty = false; + // TODO: Find a way to optimize fromUtf8 + sf::String str = sf::String::fromUtf8(body_item->get_title().data(), body_item->get_title().data() + body_item->get_title().size()); + if(body_item->title_text) + body_item->title_text->setString(std::move(str)); + else + body_item->title_text = std::make_unique<Text>(std::move(str), font, cjk_font, 16, size.x - 50 - image_padding_x * 2.0f); + body_item->title_text->setFillColor(body_item->title_color); + body_item->title_text->updateGeometry(); + } + + if(body_item->dirty_description) { + body_item->dirty_description = false; + sf::String str = sf::String::fromUtf8(body_item->get_description().data(), body_item->get_description().data() + body_item->get_description().size()); + if(body_item->description_text) + body_item->description_text->setString(std::move(str)); + else + body_item->description_text = std::make_unique<Text>(std::move(str), font, cjk_font, 14, size.x - 50 - image_padding_x * 2.0f); + body_item->description_text->updateGeometry(); + } + + if(body_item->dirty_author) { + body_item->dirty_author = false; + sf::String str = sf::String::fromUtf8(body_item->get_author().data(), body_item->get_author().data() + body_item->get_author().size()); + if(body_item->author_text) + body_item->author_text->setString(std::move(str)); + else + body_item->author_text = std::make_unique<Text>(std::move(str), bold_font, cjk_font, 14, size.x - 50 - image_padding_x * 2.0f); + body_item->author_text->setFillColor(body_item->author_color); + body_item->author_text->updateGeometry(); + } + } + + void Body::clear_body_item_cache(BodyItem *body_item) { + if(body_item->title_text) { + body_item->title_text.reset(); + body_item->dirty = true; + } + if(body_item->description_text) { + body_item->description_text.reset(); + body_item->dirty_description = true; + } + if(body_item->author_text) { + body_item->author_text.reset(); + body_item->dirty_author = true; + } } void Body::draw_item(sf::RenderWindow &window, BodyItem *item, sf::Vector2f pos, sf::Vector2f size) { + update_dirty_state(item, size); + item->last_drawn_time = draw_timer.getElapsedTime().asMilliseconds(); sf::Vector2u window_size = window.getSize(); glEnable(GL_SCISSOR_TEST); glScissor(pos.x, (int)window_size.y - (int)pos.y - (int)size.y, size.x, size.y); @@ -574,10 +612,10 @@ namespace QuickMedia { float Body::get_item_height(BodyItem *item) { float item_height = 0.0f; - if(!item->get_title().empty()) { + if(item->title_text) { item_height += item->title_text->getHeight() - 2.0f; } - if(!item->get_author().empty()) { + if(item->author_text) { item_height += item->author_text->getHeight() - 2.0f; } if(item->description_text) { |