From d9f048dd6385d037024f79711a141b15fa77de05 Mon Sep 17 00:00:00 2001 From: Radek Dutkiewicz Date: Sun, 11 Feb 2024 12:58:11 +0000 Subject: [PATCH] Async Loader WIP - Add transition queue - Add new transition model --- src/fe_present.cpp | 155 +++++++++++++++++++++++++++++++++++++++++---- src/fe_present.hpp | 30 +++++++-- src/fe_vm.cpp | 25 ++------ src/main.cpp | 9 ++- 4 files changed, 175 insertions(+), 44 deletions(-) diff --git a/src/fe_present.cpp b/src/fe_present.cpp index 0c9bcab9..6a340a2f 100644 --- a/src/fe_present.cpp +++ b/src/fe_present.cpp @@ -92,6 +92,26 @@ BOOL CALLBACK my_mon_enum_proc( HMONITOR, HDC, LPRECT mon_rect, LPARAM data ) } #endif +const char *FeTransitionTypeStrings[] +{ + "StartLayout", + "EndLayout", + "ToNewList", + "ToNewSelection", + "ToEndNavigation", + "NewList", + "NewSelection", + "EndNavigation", + "FromOldSelection", // not used in the new transition model + "ToGame", + "FromGame", + "ShowOverlay", + "HideOverlay", + "NewSelOverlay", + "ChangedTag", + NULL +}; + FeFontContainer::FeFontContainer() : m_needs_reload( false ) { @@ -930,24 +950,124 @@ int FePresent::get_list_limit() const return limit; } +// Used by fe.list.index void FePresent::set_selection_index( int index ) { int new_offset = index - get_selection_index(); if ( new_offset != 0 ) - change_selection( new_offset ); + { + queue_transition( ToNewSelection, new_offset ); + queue_transition( ToEndNavigation ); + } } -void FePresent::change_selection( int step, bool end_navigation ) +void FePresent::queue_transition( FeTransitionType type, int var ) { - on_transition( ToNewSelection, step ); + m_transition_queue.push_back({ type, var }); +} - m_feSettings->step_current_selection( step ); - update( false ); +bool FePresent::is_transition_queue_empty() +{ + return m_transition_queue.empty(); +} - on_transition( FromOldSelection, -step ); +void FePresent::process_transitions() +{ + if ( !m_transition_queue.empty() ) + FeLog() << FeTransitionTypeStrings[m_transition_queue.front().type] << " " << m_transition_queue.front().var << std::endl; + + if ( !m_transition_queue.empty() ) + { + TransitionQueueElement next = m_transition_queue.front(); + switch ( next.type ) + { + case ToNewList: + break; - if ( end_navigation ) - on_end_navigation(); + case ToNewSelection: + on_transition( ToNewSelection, next.var ); + m_transition_queue.pop_front(); + m_transition_queue.push_front({ NewSelection, next.var }); + break; + } + } + + if ( !m_transition_queue.empty() ) + { + TransitionQueueElement next = m_transition_queue.front(); + switch ( next.type ) + { + case NewSelection: + m_feSettings->step_current_selection( next.var ); + update( false ); + on_transition( FromOldSelection, -next.var ); + m_transition_queue.pop_front(); + break; + + case ToEndNavigation: + on_end_navigation(); + m_transition_queue.pop_front(); + break; + } + } +} + +void FePresent::process_transitions_v3() +{ + if ( !m_transition_queue.empty() ) + FeLog() << FeTransitionTypeStrings[m_transition_queue.front().type] << " " << m_transition_queue.front().var << std::endl; + + if ( !m_transition_queue.empty() ) + { + TransitionQueueElement next = m_transition_queue.front(); + switch ( next.type ) + { + case ToNewList: + on_transition( ToNewList, next.var ); + m_transition_queue.pop_front(); + m_transition_queue.push_front({ NewList, next.var }); + break; + + case ToNewSelection: + on_transition( ToNewSelection, next.var ); + m_transition_queue.pop_front(); + m_transition_queue.push_front({ FromOldSelection, next.var }); + break; + + case ToEndNavigation: + on_transition( ToEndNavigation, next.var ); + m_transition_queue.pop_front(); + m_transition_queue.push_front({ ToEndNavigation, 0 }); + break; + } + } + + //if al.done() for new transitions + if ( !m_transition_queue.empty() ) + { + TransitionQueueElement next = m_transition_queue.front(); + switch ( next.type ) + { + case NewList: + on_transition( NewList, next.var ); + m_transition_queue.pop_front(); + break; + + case NewSelection: + m_feSettings->step_current_selection( next.var ); + update( false ); + on_transition( NewSelection, next.var ); + m_transition_queue.pop_front(); + break; + + case EndNavigation: + on_end_navigation(); //replace with + // updates from on_end_navigation() + // on_transition( EndNavigation, 0 ); + m_transition_queue.pop_front(); + break; + } + } } bool FePresent::reset_screen_saver() @@ -964,6 +1084,7 @@ bool FePresent::reset_screen_saver() return false; } +// First press, repeat in main bool FePresent::handle_event( FeInputMap::Command c ) { if ( reset_screen_saver() ) @@ -972,19 +1093,19 @@ bool FePresent::handle_event( FeInputMap::Command c ) switch( c ) { case FeInputMap::NextGame: - change_selection( 1, false ); + queue_transition( ToNewSelection, 1 ); break; case FeInputMap::PrevGame: - change_selection( -1, false ); + queue_transition( ToNewSelection, -1 ); break; case FeInputMap::NextPage: - change_selection( get_page_size(), false ); + queue_transition( ToNewSelection, get_page_size() ); break; case FeInputMap::PrevPage: - change_selection( -get_page_size(), false ); + queue_transition( ToNewSelection, -get_page_size() ); break; case FeInputMap::RandomGame: @@ -994,7 +1115,11 @@ bool FePresent::handle_event( FeInputMap::Command c ) { int step = rand() % ls; if ( step != 0 ) - change_selection( step ); + { + queue_transition( ToNewSelection, step ); + queue_transition( ToEndNavigation ); + } + } } break; @@ -1069,7 +1194,7 @@ bool FePresent::handle_event( FeInputMap::Command c ) } if ( step != 0 ) - change_selection( step, false ); + queue_transition( ToNewSelection, step ); } break; @@ -1235,6 +1360,7 @@ void FePresent::update_to_new_list( int var, bool reset_display, bool suppress_t on_transition( ToNewList, var ); } +// Only called wnen menu is up bool FePresent::tick() { bool ret_val = false; @@ -1266,6 +1392,7 @@ bool FePresent::video_tick() return ret_val; } +// Used by fe.layout.redraw void FePresent::redraw() { // Process tick only when Layout is fully loaded diff --git a/src/fe_present.hpp b/src/fe_present.hpp index ea0a2927..4df5f221 100644 --- a/src/fe_present.hpp +++ b/src/fe_present.hpp @@ -23,6 +23,8 @@ #ifndef FE_PRESENT_HPP #define FE_PRESENT_HPP +#include + #include #include "fe_presentable.hpp" #include "fe_settings.hpp" @@ -49,18 +51,29 @@ enum FeTransitionType { StartLayout=0, // var: FromToScreenSaver, FromToFrontend or FromToNoValue EndLayout, // var: FromToScreenSaver, FromToFrontend or FromToNoValue - ToNewSelection, // var = index_offset of new selection - FromOldSelection, // var = index_offset of old selection - ToGame, // var = 0 - FromGame, // var = 0 ToNewList, // var = filter offset of new filter (if available), otherwise 0 + ToNewSelection, // var = index_offset of new selection + ToEndNavigation, // var = 0 + NewList, // var = filter offset of new filter (if available), otherwise 0 + NewSelection, // var = index_offset of new selection EndNavigation, // var = 0 + FromOldSelection, // var = index_offset of old selection (not used in the new transition model) + ToGame, // var = 0 + FromGame, // var = 0 ShowOverlay, // var = Custom, Exit, Displays, Filters, Tags HideOverlay, // var = 0 NewSelOverlay, // var = index of new selection ChangedTag // var = FeRomInfo::Favourite, FeRomInfo::Tags }; +extern const char *FeTransitionTypeStrings[]; + +struct TransitionQueueElement +{ + FeTransitionType type; + int var; +}; + // // Container class for use in our font pool // @@ -159,6 +172,8 @@ class FePresent FeListBox *m_overlay_lb; bool m_layout_loaded; + std::deque m_transition_queue; + FePresent( const FePresent & ); FePresent &operator=( const FePresent & ); @@ -233,6 +248,11 @@ class FePresent bool video_tick(); // update videos only. return true if redraw required void redraw(); // redraw the screen while doing computationally intensive loops + void queue_transition( FeTransitionType type, int var=0 ); + bool is_transition_queue_empty(); + void process_transitions(); + void process_transitions_v3(); + bool saver_activation_check(); void on_stop_frontend(); void pre_run(); @@ -242,8 +262,6 @@ class FePresent bool reset_screen_saver(); bool handle_event( FeInputMap::Command ); - void change_selection( int step, bool end_navigation=true ); - FeSettings *get_fes() const { return m_feSettings; }; int get_page_size() const; diff --git a/src/fe_vm.cpp b/src/fe_vm.cpp index 3dc0c199..c3972b20 100644 --- a/src/fe_vm.cpp +++ b/src/fe_vm.cpp @@ -263,23 +263,6 @@ Sqrat::Function &FeCallback::get_fn() return m_cached_fn; } -const char *FeVM::transitionTypeStrings[] = -{ - "StartLayout", - "EndLayout", - "ToNewSelection", - "FromOldSelection", - "ToGame", - "FromGame", - "ToNewList", - "EndNavigation", - "ShowOverlay", - "HideOverlay", - "NewSelOverlay", - "ChangedTag", - NULL -}; - FeVM::FeVM( FeSettings &fes, FeWindow &wnd, FeMusic &ambient_sound, bool console_input ) : FePresent( &fes, wnd ), m_overlay( NULL ), @@ -649,9 +632,9 @@ bool FeVM::on_new_layout() Enumeration transition; i=0; - while ( transitionTypeStrings[i] != NULL ) + while ( FeTransitionTypeStrings[i] != NULL ) { - transition.Const( transitionTypeStrings[i], i ); + transition.Const( FeTransitionTypeStrings[i], i ); i++; } ConstTable().Enum( _SC("Transition"), transition ); @@ -1308,7 +1291,7 @@ void FeVM::on_transition( { using namespace Sqrat; - FeDebug() << "[Transition] type=" << transitionTypeStrings[t] << ", var=" << var << std::endl; + FeDebug() << "[Transition] type=" << FeTransitionTypeStrings[t] << ", var=" << var << std::endl; sf::Clock clk; int ttime = 0; @@ -1360,7 +1343,7 @@ void FeVM::on_transition( } // redraw now if we are doing another pass... - // + // TODO: DEPRECATE BLOCKIKNG TRANSITIONS if (( !worklist.empty() ) && ( m_window.isOpen() )) { video_tick(); diff --git a/src/main.cpp b/src/main.cpp index 36d6a71b..cec178c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -987,8 +987,9 @@ int main(int argc, char *argv[]) switch ( move_triggered ) { + // Key repeat. First press in FePresent::handle_event() case FeInputMap::PrevGame: step = -step; break; - case FeInputMap::NextGame: break; // do nothing + case FeInputMap::NextGame: break; case FeInputMap::PrevPage: step *= -feVM.get_page_size(); break; case FeInputMap::NextPage: step *= feVM.get_page_size(); break; case FeInputMap::PrevFavourite: @@ -1034,7 +1035,7 @@ int main(int argc, char *argv[]) if ( step != 0 ) { if ( !feVM.script_handle_event( move_triggered ) ) - feVM.change_selection( step, false ); + feVM.queue_transition( ToNewSelection, step ); redraw=true; } @@ -1049,7 +1050,7 @@ int main(int argc, char *argv[]) // "End Navigation" stuff now // if ( move_triggered != FeInputMap::LAST_COMMAND ) - feVM.on_end_navigation(); + feVM.queue_transition( ToEndNavigation ); move_state = FeInputMap::LAST_COMMAND; move_triggered = FeInputMap::LAST_COMMAND; @@ -1073,6 +1074,8 @@ int main(int argc, char *argv[]) else has_focus = window.hasFocus(); + feVM.process_transitions(); + if ( feVM.on_tick() ) redraw=true;