From 0446e717ec655359aa3337beec90c6a3bca68f83 Mon Sep 17 00:00:00 2001 From: Stepland <10530295-Buggyroom@users.noreply.gitlab.com> Date: Thu, 13 Jul 2023 02:31:05 +0200 Subject: [PATCH] WIP deferred marker loading --- src/editor_state.cpp | 10 ++++- src/editor_state.hpp | 2 +- src/main.cpp | 101 +++++++++++++++++++++++++++---------------- 3 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/editor_state.cpp b/src/editor_state.cpp index 6423e5d..9191213 100644 --- a/src/editor_state.cpp +++ b/src/editor_state.cpp @@ -434,7 +434,7 @@ Fraction EditorState::get_snap_step() const { return Fraction{1, snap}; }; -void EditorState::display_playfield(const Marker& marker, Judgement markerEndingState) { +void EditorState::display_playfield(const std::optional>& opt_marker, Judgement markerEndingState) { ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_Once); ImGui::SetNextWindowSizeConstraints( ImVec2(0, 0), @@ -457,7 +457,8 @@ void EditorState::display_playfield(const Marker& marker, Judgement markerEnding float TitlebarHeight = ImGui::GetWindowSize().y - ImGui::GetWindowSize().x; int ImGuiIndex = 0; - if (chart_state) { + if (chart_state and opt_marker) { + const auto& marker = **opt_marker; playfield.resize(static_cast(ImGui::GetWindowSize().x)); if (chart_state->long_note_being_created) { playfield.draw_tail_and_receptor( @@ -549,6 +550,11 @@ void EditorState::display_playfield(const Marker& marker, Judgement markerEnding } } + if (not opt_marker) { + ImGui::SetCursorPos({0.5f * squareSize, 0.5f * squareSize}); + ImGui::TextUnformatted("Loading marker ..."); + } + if (chart_state) { // Check for real (+ potential if requested) collisions // then display them diff --git a/src/editor_state.hpp b/src/editor_state.hpp index 1f36660..8e9f2c1 100644 --- a/src/editor_state.hpp +++ b/src/editor_state.hpp @@ -142,7 +142,7 @@ public: Fraction get_snap_step() const; bool show_playfield = true; - void display_playfield(const Marker& marker, Judgement markerEndingState); + void display_playfield(const std::optional>& marker, Judgement markerEndingState); bool show_file_properties = false; void display_file_properties(); diff --git a/src/main.cpp b/src/main.cpp index 58a1aae..cdd5f23 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,18 +1,23 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include @@ -74,41 +79,47 @@ int main() { IO.ConfigWindowsMoveFromTitleBarOnly = true; // Loading markers preview - std::map> markers; - - for (const auto& folder : - std::filesystem::directory_iterator(markers_folder)) { - try { - const auto marker = load_marker_from(folder); - const auto relative_folder = std::filesystem::relative(folder, markers_folder); - markers.emplace(relative_folder, marker); - } catch (const std::exception& e) { - } - } - - if (markers.size() == 0) { - fmt::print("Couldn't load any markers, aborting"); - return -1; - } - - auto marker = markers.begin()->second; - if (config.marker.folder) { - const auto folder = *config.marker.folder; - if (folder.is_relative()) { - const auto it = markers.find(folder); - if (it != markers.end()) { - marker = it->second; - } else { - try { - const auto new_marker = load_marker_from(markers_folder / folder); - auto [it, _] = markers.emplace(folder, new_marker); - marker = it->second; - } catch (const std::exception& e) { - fmt::print("Failed to load marker from preferences"); + std::map>> marker_previews_loaders; + std::map> marker_previews; + for (const auto& dir_entry : std::filesystem::directory_iterator(markers_folder)) { + const auto folder = std::filesystem::relative(dir_entry, markers_folder); + marker_previews_loaders[folder] = std::async( + std::launch::async, + [](const std::filesystem::path& folder) -> std::optional { + for (const auto& file : {"preview.png", "ma15.png"}) { + const auto preview_path = folder / file; + if (std::filesystem::exists(preview_path)) { + feis::Texture preview; + if (preview.load_from_path(preview_path)) { + return preview; + } + } } + return {}; + }, + dir_entry.path() + ); + } + + using MarkerTuple = std::tuple>>; + std::future marker_loader; + const auto load_marker_async = [&](const std::filesystem::path& folder) -> MarkerTuple { + try { + return {folder, load_marker_from(markers_folder / folder)}; + } catch (const std::exception& e) { + return {folder, {}}; + } + }; + std::shared_ptr marker = [&](const std::optional& folder){ + if (folder and folder->is_relative()) { + try { + return load_marker_from(markers_folder / *folder); + } catch (const std::exception& e) { + fmt::print("Failed to load marker from preferences"); } } - } + return first_available_marker_in(markers_folder); + }(config.marker.folder); if (not config.marker.ending_state) { config.marker.ending_state = Judgement::Perfect; @@ -479,7 +490,7 @@ int main() { editor_state->display_history(); } if (editor_state->chart_state and editor_state->show_playfield) { - editor_state->display_playfield(*marker, markerEndingState); + editor_state->display_playfield(marker, markerEndingState); } if (editor_state->show_linear_view) { editor_state->display_linear_view(); @@ -770,13 +781,17 @@ int main() { } if (ImGui::BeginMenu("Marker")) { int i = 0; - for (const auto& [path, marker_ptr] : markers) { + for (const auto& [path, opt_preview] : marker_previews) { ImGui::PushID(path.c_str()); - const auto preview = marker_ptr->approach_preview(); - if (ImGui::ImageButton(preview, {100, 100})) { - marker = marker_ptr; - config.marker.folder = path; + if (opt_preview) { + if (ImGui::ImageButton(*opt_preview, {100, 100})) { + + marker_loader = std::async + marker = marker_ptr; + config.marker.folder = path; + } } + ImGui::PopID(); i++; if (i % 4 != 0) { @@ -812,6 +827,16 @@ int main() { ImGui::SFML::Render(window); window.display(); + + for (auto& [path, future] : marker_previews_loaders) { + if (future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { + marker_previews[path] = future.get(); + } + } + for (auto& future : ) + if (marker_loader.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { + marker = marker_loader.get(); + } } ImGui::SFML::Shutdown();