diff --git a/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.cpp b/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.cpp index 9cda195871..e9b7c12758 100644 --- a/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.cpp +++ b/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.cpp @@ -71,6 +71,7 @@ VideoSession::VideoSession(Logger& logger, VideoSourceOption& option) std::shared_ptr VideoSession::descriptor() const{ + auto scope = m_sanitizer.check_scope(); ReadSpinLock lg(m_state_lock, PA_CURRENT_FUNCTION); return m_descriptor; } @@ -79,6 +80,7 @@ void VideoSession::current_stream_format( VideoFormat& format, FramesPerSecond& fps ){ + auto scope = m_sanitizer.check_scope(); ReadSpinLock lg(m_state_lock, PA_CURRENT_FUNCTION); if (m_video_source){ resolution = m_video_source->current_resolution(); @@ -91,6 +93,7 @@ void VideoSession::current_stream_format( } } Resolution VideoSession::current_resolution(){ + auto scope = m_sanitizer.check_scope(); ReadSpinLock lg(m_state_lock, PA_CURRENT_FUNCTION); if (m_video_source){ return m_video_source->current_resolution(); @@ -117,6 +120,7 @@ FramesPerSecond VideoSession::current_fps(){ } #endif VideoFormatSet VideoSession::supported_formats() const{ + auto scope = m_sanitizer.check_scope(); ReadSpinLock lg(m_state_lock, PA_CURRENT_FUNCTION); if (m_video_source){ return m_video_source->supported_formats(); @@ -128,10 +132,12 @@ VideoFormatSet VideoSession::supported_formats() const{ void VideoSession::save(VideoSourceOption& option) const{ + auto scope = m_sanitizer.check_scope(); ReadSpinLock lg(m_state_lock, PA_CURRENT_FUNCTION); option = m_option; } void VideoSession::load(const VideoSourceOption& option){ + auto scope = m_sanitizer.check_scope(); set_source( option.descriptor(), option.m_resolution, @@ -141,6 +147,7 @@ void VideoSession::load(const VideoSourceOption& option){ } void VideoSession::reset(){ + auto scope = m_sanitizer.check_scope(); { WriteSpinLock lg(m_queue_lock, PA_CURRENT_FUNCTION); // cout << "VideoSession::reset(): " << m_queued_commands.size() << endl; @@ -162,6 +169,7 @@ void VideoSession::set_source( VideoFormat format, size_t fps ){ + auto scope = m_sanitizer.check_scope(); { WriteSpinLock lg(m_queue_lock, PA_CURRENT_FUNCTION); // cout << "VideoSession::set_source(): " << resolution.to_string() << endl; @@ -178,6 +186,7 @@ void VideoSession::set_source( run_commands(); } void VideoSession::set_resolution(Resolution resolution){ + auto scope = m_sanitizer.check_scope(); { WriteSpinLock lg(m_queue_lock, PA_CURRENT_FUNCTION); // cout << "VideoSession::set_resolution(): " << m_queued_commands.size() << endl; @@ -194,6 +203,7 @@ void VideoSession::set_resolution(Resolution resolution){ run_commands(); } void VideoSession::set_format(VideoFormat format, size_t fps){ + auto scope = m_sanitizer.check_scope(); { WriteSpinLock lg(m_queue_lock, PA_CURRENT_FUNCTION); // cout << "VideoSession::set_resolution(): " << m_queued_commands.size() << endl; @@ -211,6 +221,7 @@ void VideoSession::set_format(VideoFormat format, size_t fps){ } void VideoSession::internal_reset(){ + auto scope = m_sanitizer.check_scope(); m_logger.log("Resetting the video...", COLOR_GREEN); m_state_listeners.run_method(&StateListener::pre_shutdown); @@ -256,6 +267,7 @@ void VideoSession::internal_set_source( VideoFormat format, FramesPerSecond fps ){ + auto scope = m_sanitizer.check_scope(); m_logger.log("Changing video...", COLOR_GREEN); if (*m_descriptor == *device && !m_descriptor->should_reload() && m_option.m_resolution == resolution && @@ -308,6 +320,7 @@ void VideoSession::internal_set_source( ); } void VideoSession::internal_set_resolution(Resolution resolution){ + auto scope = m_sanitizer.check_scope(); m_logger.log("Changing resolution...", COLOR_GREEN); if (m_option.m_resolution == resolution){ return; @@ -356,6 +369,7 @@ void VideoSession::internal_set_resolution(Resolution resolution){ ); } void VideoSession::internal_set_format(VideoFormat format, FramesPerSecond fps){ + auto scope = m_sanitizer.check_scope(); m_logger.log("Changing format...", COLOR_GREEN); if (m_option.m_format == format && m_option.m_fps == fps){ return; @@ -396,6 +410,7 @@ void VideoSession::internal_set_format(VideoFormat format, FramesPerSecond fps){ } void VideoSession::run_commands(){ + auto scope = m_sanitizer.check_scope(); if (!m_reset_lock.try_acquire_write()){ m_logger.log("Suppressing re-entrant command...", COLOR_RED); return; @@ -468,6 +483,7 @@ double VideoSession::fps_display() const{ void VideoSession::on_watchdog_timeout(){ + auto scope = m_sanitizer.check_scope(); { ReadSpinLock lg(m_state_lock, PA_CURRENT_FUNCTION); if (!m_video_source || !m_video_source->allow_watchdog_reset()){ diff --git a/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.h b/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.h index bb255c8102..0b94f4fb79 100644 --- a/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.h +++ b/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.h @@ -251,6 +251,8 @@ class VideoSession ListenerSet m_state_listeners; ListenerSet m_frame_listeners; + + LifetimeSanitizer m_sanitizer; }; diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.cpp b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.cpp deleted file mode 100644 index 25cd2a9d77..0000000000 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* Multi-Switch Program Option - * - * From: https://github.com/PokemonAutomation/ - * - */ - -#include "Common/Cpp/Json/JsonValue.h" -#include "Common/Cpp/Json/JsonObject.h" -#include "NintendoSwitch_MultiSwitchProgramOption.h" -#include "UI/NintendoSwitch_MultiSwitchProgramWidget.h" - -namespace PokemonAutomation{ -namespace NintendoSwitch{ - - - -MultiSwitchProgramOption::~MultiSwitchProgramOption() = default; -MultiSwitchProgramOption::MultiSwitchProgramOption(const MultiSwitchProgramDescriptor& descriptor) - : PanelSession(descriptor) - , m_descriptor(descriptor) - , m_system( - descriptor.feedback(), - descriptor.allow_commands_while_running() - ? AllowCommandsWhenRunning::ENABLE_COMMANDS - : AllowCommandsWhenRunning::DISABLE_COMMANDS, - descriptor.min_switches(), - descriptor.max_switches(), - descriptor.default_switches() - ) - , m_instance(descriptor.make_instance()) -{} - -void MultiSwitchProgramOption::from_json(const JsonValue& json){ - const JsonObject* obj = json.to_object(); - if (obj == nullptr){ - return; - } - const JsonValue* value = obj->get_value("SwitchSetup"); - if (value){ - m_system.load_json(*value); - } - m_instance->from_json(json); -} -JsonValue MultiSwitchProgramOption::to_json() const{ - JsonObject obj = std::move(*m_instance->to_json().to_object()); - obj["SwitchSetup"] = m_system.to_json(); - return obj; -} - -ConfigOption& MultiSwitchProgramOption::options(){ - return m_instance->m_options; -} - -std::string MultiSwitchProgramOption::check_validity() const{ - return m_instance->check_validity(); -} -void MultiSwitchProgramOption::restore_defaults(){ - m_instance->restore_defaults(); -} - - -QWidget* MultiSwitchProgramOption::make_widget(QWidget& parent){ - return new MultiSwitchProgramWidget2(parent, *this); -} - - - - -} -} diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.h b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.h deleted file mode 100644 index 42f4170eae..0000000000 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Multi-Switch Program Option - * - * From: https://github.com/PokemonAutomation/ - * - * This class represents the serializable state of a Switch program. - * This class maintains no UI and is not thread-safe. - * - * Note that this class does own the "MultiSwitchProgramInstance", object - * which is controlled by the individual program itself. There the running - * program can do whatever it wants - including keeping run-time state. - * - */ - -#ifndef PokemonAutomation_NintendoSwitch_MultiSwitchProgramOption_H -#define PokemonAutomation_NintendoSwitch_MultiSwitchProgramOption_H - -#include "CommonFramework/Panels/PanelSession.h" -#include "NintendoSwitch_MultiSwitchSystemOption.h" - -namespace PokemonAutomation{ - class ConfigOption; -namespace NintendoSwitch{ - -class MultiSwitchProgramDescriptor; -class MultiSwitchProgramInstance; - - -class MultiSwitchProgramOption final : public PanelSession{ -public: - ~MultiSwitchProgramOption(); - MultiSwitchProgramOption(const MultiSwitchProgramDescriptor& descriptor); - - virtual void from_json(const JsonValue& json) override; - virtual JsonValue to_json() const override; - -public: - const MultiSwitchProgramDescriptor& descriptor() const{ return m_descriptor; } - MultiSwitchSystemOption& system(){ return m_system; } - MultiSwitchProgramInstance& instance(){ return *m_instance; } - ConfigOption& options(); - - std::string check_validity() const; - void restore_defaults(); - -private: - virtual QWidget* make_widget(QWidget& parent) override; - -private: - const MultiSwitchProgramDescriptor& m_descriptor; - MultiSwitchSystemOption m_system; - std::unique_ptr m_instance; -}; - - - - - -} -} -#endif diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.cpp b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.cpp index 6433e18738..846ba1debc 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.cpp @@ -6,6 +6,8 @@ #include "Common/Cpp/ScopeExit.h" #include "Common/Cpp/Exceptions.h" +#include "Common/Cpp/Json/JsonValue.h" +#include "Common/Cpp/Json/JsonObject.h" #include "Common/Cpp/EarlyShutdown.h" #include "Common/Cpp/Concurrency/SpinPause.h" #include "Common/Cpp/Containers/FixedLimitVector.tpp" @@ -16,10 +18,9 @@ #include "CommonFramework/Notifications/ProgramInfo.h" #include "CommonFramework/Notifications/ProgramNotifications.h" #include "CommonFramework/Options/Environment/SleepSuppressOption.h" -#include "Controllers/NullController.h" #include "NintendoSwitch/NintendoSwitch_Settings.h" -#include "NintendoSwitch_MultiSwitchProgramOption.h" #include "NintendoSwitch_MultiSwitchProgramSession.h" +#include "UI/NintendoSwitch_MultiSwitchProgramWidget.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -38,15 +39,25 @@ void MultiSwitchProgramSession::remove_listener(Listener& listener){ -MultiSwitchProgramSession::MultiSwitchProgramSession(MultiSwitchProgramOption& option) - : ProgramSession(option.descriptor()) - , m_option(option) - , m_system(option.system(), instance_id()) +MultiSwitchProgramSession::MultiSwitchProgramSession(const MultiSwitchProgramDescriptor& descriptor) + : PanelSession(descriptor) + , ProgramSession(descriptor) + , m_descriptor(descriptor) + , m_system_option( + descriptor.allow_commands_while_running() + ? AllowCommandsWhenRunning::ENABLE_COMMANDS + : AllowCommandsWhenRunning::DISABLE_COMMANDS, + descriptor.min_switches(), + descriptor.max_switches(), + descriptor.default_switches() + ) + , m_system(m_system_option, instance_id()) + , m_instance(descriptor.make_instance()) , m_scope(nullptr) , m_sanitizer("MultiSwitchProgramSession") { // WriteSpinLock lg(m_lock, PA_CURRENT_FUNCTION); - m_option.instance().update_active_consoles(option.system().count()); + m_instance->update_active_consoles(m_system_option.count()); m_system.add_listener(*this); } @@ -74,15 +85,44 @@ void MultiSwitchProgramSession::restore_defaults(){ return; } logger().log("Restoring settings to defaults..."); - m_option.restore_defaults(); + m_instance->restore_defaults(); } std::string MultiSwitchProgramSession::check_validity() const{ auto ScopeCheck = m_sanitizer.check_scope(); - return m_option.check_validity(); + return m_instance->check_validity(); } + +ConfigOption& MultiSwitchProgramSession::options(){ + return m_instance->m_options; +} + + +void MultiSwitchProgramSession::from_json(const JsonValue& json){ + const JsonObject* obj = json.to_object(); + if (obj == nullptr){ + return; + } + const JsonValue* value = obj->get_value("SwitchSetup"); + if (value){ + m_system.load_json(*value); + } + m_instance->from_json(json); +} +JsonValue MultiSwitchProgramSession::to_json() const{ + JsonObject obj = std::move(*m_instance->to_json().to_object()); + obj["SwitchSetup"] = m_system_option.to_json(); + return obj; +} +QWidget* MultiSwitchProgramSession::make_widget(QWidget& parent){ + return new MultiSwitchProgramWidget2(parent, *this); +} + + + + void MultiSwitchProgramSession::run_program_instance(MultiSwitchProgramEnvironment& env, CancellableScope& scope){ auto ScopeCheck = m_sanitizer.check_scope(); { @@ -97,16 +137,16 @@ void MultiSwitchProgramSession::run_program_instance(MultiSwitchProgramEnvironme size_t consoles = m_system.count(); for (size_t console = 0; console < consoles; console++){ // Startup Checks - m_option.instance().start_program_controller_check( + m_instance->start_program_controller_check( m_system[console].controller(), console ); - m_option.instance().start_program_feedback_check( + m_instance->start_program_feedback_check( env.consoles[console], console, - m_option.descriptor().feedback() + m_descriptor.feedback() ); - m_option.instance().start_program_border_check( + m_instance->start_program_border_check( env.consoles[console], console, - m_option.descriptor().feedback() + m_descriptor.feedback() ); // Attach all the controllers to the scope so they can be cancelled from the top. @@ -132,7 +172,7 @@ void MultiSwitchProgramSession::run_program_instance(MultiSwitchProgramEnvironme m_scope.store(nullptr, std::memory_order_release); }); - m_option.instance().program(env, scope); + m_instance->program(env, scope); for (size_t c = 0; c < consoles; c++){ env.consoles[c].wait_for_all_controllers(); } @@ -174,7 +214,7 @@ void MultiSwitchProgramSession::internal_run_program(){ } auto ScopeCheck = m_sanitizer.check_scope(); - m_option.options().reset_state(); + options().reset_state(); SleepSuppressScope sleep_scope(GlobalSettings::instance().SLEEP_SUPPRESS->PROGRAM_RUNNING); @@ -183,8 +223,8 @@ void MultiSwitchProgramSession::internal_run_program(){ ProgramInfo program_info( identifier(), - m_option.descriptor().category(), - m_option.descriptor().display_name(), + m_descriptor.category(), + m_descriptor.display_name(), timestamp() ); @@ -229,7 +269,7 @@ void MultiSwitchProgramSession::internal_run_program(){ }catch (ProgramFinishedException& e){ logger().log("Program finished early!", COLOR_BLUE); env.add_overlay_log_to_all_consoles("- Program Finished -"); - send_program_finished_notification(env, m_option.instance().NOTIFICATION_PROGRAM_FINISH, e.message(), *e.screenshot()); + send_program_finished_notification(env, m_instance->NOTIFICATION_PROGRAM_FINISH, e.message(), *e.screenshot()); }catch (InvalidConnectionStateException& e){ logger().log("Program stopped due to connection issue.", COLOR_RED); env.add_overlay_log_to_all_consoles("- Invalid Connection -", COLOR_RED); @@ -247,7 +287,7 @@ void MultiSwitchProgramSession::internal_run_program(){ message = e.name(); } report_error(message); - e.send_fatal_error_notif_and_telemetry_report(env, m_option.instance().NOTIFICATION_ERROR_FATAL); + e.send_fatal_error_notif_and_telemetry_report(env, m_instance->NOTIFICATION_ERROR_FATAL); }catch (OperationFailedException& e){ // no screenshot logger().log("Program stopped with an exception!", COLOR_RED); env.add_overlay_log_to_all_consoles("- Program Error -", COLOR_RED); @@ -257,7 +297,7 @@ void MultiSwitchProgramSession::internal_run_program(){ message = e.name(); } report_error(message); - e.send_fatal_error_notif_and_telemetry_report(env, m_option.instance().NOTIFICATION_ERROR_FATAL); + e.send_fatal_error_notif_and_telemetry_report(env, m_instance->NOTIFICATION_ERROR_FATAL); }catch (FatalProgramException& e){ logger().log("Program stopped with an exception!", COLOR_RED); env.add_overlay_log_to_all_consoles("- Program Error -", COLOR_RED); @@ -267,7 +307,7 @@ void MultiSwitchProgramSession::internal_run_program(){ message = e.name(); } report_error(message); - e.send_fatal_error_notif_and_telemetry_report(env, m_option.instance().NOTIFICATION_ERROR_FATAL); + e.send_fatal_error_notif_and_telemetry_report(env, m_instance->NOTIFICATION_ERROR_FATAL); }catch (Exception& e){ logger().log("Program stopped with an exception!", COLOR_RED); env.add_overlay_log_to_all_consoles("- Program Error -", COLOR_RED); @@ -277,7 +317,7 @@ void MultiSwitchProgramSession::internal_run_program(){ } report_error(message); send_program_fatal_error_notification( - env, m_option.instance().NOTIFICATION_ERROR_FATAL, + env, m_instance->NOTIFICATION_ERROR_FATAL, message ); }catch (std::exception& e){ @@ -289,7 +329,7 @@ void MultiSwitchProgramSession::internal_run_program(){ } report_error(message); send_program_fatal_error_notification( - env, m_option.instance().NOTIFICATION_ERROR_FATAL, + env, m_instance->NOTIFICATION_ERROR_FATAL, message ); }catch (...){ @@ -297,7 +337,7 @@ void MultiSwitchProgramSession::internal_run_program(){ env.add_overlay_log_to_all_consoles("- Unknown Error -", COLOR_RED); report_error("Unknown error."); send_program_fatal_error_notification( - env, m_option.instance().NOTIFICATION_ERROR_FATAL, + env, m_instance->NOTIFICATION_ERROR_FATAL, "Unknown error." ); } @@ -310,7 +350,7 @@ void MultiSwitchProgramSession::shutdown(){ } void MultiSwitchProgramSession::startup(size_t switch_count){ auto ScopeCheck = m_sanitizer.check_scope(); - m_option.instance().update_active_consoles(switch_count); + m_instance->update_active_consoles(switch_count); m_listeners.run_method(&Listener::redraw_options); } diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.h b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.h index 5080654aff..0b9e5b809c 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.h +++ b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.h @@ -15,6 +15,7 @@ #ifndef PokemonAutomation_NintendoSwitch_MultiSwitchProgramSession_H #define PokemonAutomation_NintendoSwitch_MultiSwitchProgramSession_H +#include "CommonFramework/Panels/PanelSession.h" #include "CommonFramework/ProgramSession.h" #include "NintendoSwitch/NintendoSwitch_MultiSwitchProgram.h" #include "NintendoSwitch_MultiSwitchSystemSession.h" @@ -25,7 +26,11 @@ namespace NintendoSwitch{ class MultiSwitchProgramOption; -class MultiSwitchProgramSession final : public ProgramSession, private MultiSwitchSystemSession::Listener{ +class MultiSwitchProgramSession final + : public PanelSession + , public ProgramSession + , private MultiSwitchSystemSession::Listener +{ public: // This is temporary. Remove once configs have push notifications. struct Listener{ @@ -34,15 +39,20 @@ class MultiSwitchProgramSession final : public ProgramSession, private MultiSwit void add_listener(Listener& listener); void remove_listener(Listener& listener); + public: bool try_shutdown(); ~MultiSwitchProgramSession(); - MultiSwitchProgramSession(MultiSwitchProgramOption& option); + MultiSwitchProgramSession(const MultiSwitchProgramDescriptor& descriptor); void restore_defaults(); + public: + const MultiSwitchProgramDescriptor& descriptor() const{ return m_descriptor; } MultiSwitchSystemSession& system(){ return m_system; } + ConfigOption& options(); + private: virtual std::string check_validity() const override; @@ -53,13 +63,24 @@ class MultiSwitchProgramSession final : public ProgramSession, private MultiSwit virtual void shutdown() override; virtual void startup(size_t switch_count) override; + virtual void from_json(const JsonValue& json) override; + virtual JsonValue to_json() const override; + virtual QWidget* make_widget(QWidget& parent) override; + + private: void run_program_instance(MultiSwitchProgramEnvironment& env, CancellableScope& scope); + private: - MultiSwitchProgramOption& m_option; + + const MultiSwitchProgramDescriptor& m_descriptor; + + MultiSwitchSystemOption m_system_option; MultiSwitchSystemSession m_system; + std::unique_ptr m_instance; + std::atomic m_scope; ListenerSet m_listeners; diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.cpp b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.cpp index c05ddbd085..1c2f3a80eb 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.cpp @@ -7,6 +7,7 @@ #include "Common/Cpp/Json/JsonValue.h" #include "Common/Cpp/Json/JsonArray.h" #include "Common/Cpp/Json/JsonObject.h" +#include "Common/Cpp/Containers/FixedLimitVector.tpp" #include "NintendoSwitch_MultiSwitchSystemOption.h" namespace PokemonAutomation{ @@ -14,7 +15,6 @@ namespace NintendoSwitch{ MultiSwitchSystemOption::MultiSwitchSystemOption( - FeedbackType feedback, AllowCommandsWhenRunning allow_commands_while_running, size_t min_switches, size_t max_switches, @@ -24,13 +24,16 @@ MultiSwitchSystemOption::MultiSwitchSystemOption( , m_min_switches(std::max(min_switches, (size_t)1)) , m_max_switches(std::min(max_switches, (size_t)MAX_SWITCHES)) , m_active_switches(0) + , m_switches(m_max_switches) { + for (size_t c = 0; c < m_max_switches; c++){ + m_switches.emplace_back(m_allow_commands_while_running); + } switches = std::max(switches, m_min_switches); switches = std::min(switches, m_max_switches); - resize(switches); + m_active_switches = switches; } MultiSwitchSystemOption::MultiSwitchSystemOption( - FeedbackType feedback, AllowCommandsWhenRunning allow_commands_while_running, size_t min_switches, size_t max_switches, @@ -41,47 +44,38 @@ MultiSwitchSystemOption::MultiSwitchSystemOption( , m_max_switches(std::min(max_switches, (size_t)MAX_SWITCHES)) , m_active_switches(0) { - MultiSwitchSystemOption::load_json(json); - if (m_switches.size() < m_min_switches){ - resize(m_min_switches); + for (size_t c = 0; c < m_max_switches; c++){ + m_switches.emplace_back(m_allow_commands_while_running); } + MultiSwitchSystemOption::load_json(json); } void MultiSwitchSystemOption::load_json(const JsonValue& json){ const JsonObject* obj = json.to_object(); if (obj == nullptr){ return; } + obj->read_integer(m_active_switches, "ActiveDevices", m_min_switches, m_max_switches); const JsonArray* array = obj->get_array("DeviceList"); - if (array != nullptr && !array->empty() && array->size() <= MAX_SWITCHES){ - m_switches.clear(); - size_t items = array->size(); - for (size_t c = 0; c < items; c++){ - m_switches.emplace_back( - new SwitchSystemOption( - m_allow_commands_while_running, - (*array)[c] - ) - ); + if (array != nullptr){ + size_t c = 0; + size_t stop = std::min(m_max_switches, array->size()); + for (; c < stop; c++){ + m_switches[c].load_json((*array)[c]); } + m_active_switches = c; } - obj->read_integer(m_active_switches, "ActiveDevices", m_min_switches, m_max_switches); } JsonValue MultiSwitchSystemOption::to_json() const{ JsonObject obj; obj["ActiveDevices"] = m_active_switches; JsonArray array; for (const auto& item : m_switches){ - array.push_back(item->to_json()); + array.push_back(item.to_json()); } obj["DeviceList"] = std::move(array); return obj; } void MultiSwitchSystemOption::resize(size_t count){ - while (m_switches.size() < count){ - m_switches.emplace_back( - new SwitchSystemOption(m_allow_commands_while_running) - ); - } m_active_switches = count; } diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.h b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.h index b9e798bc1d..5840be5d59 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.h +++ b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.h @@ -13,9 +13,7 @@ #ifndef PokemonAutomationn_NintendoSwitch_MultiSwitchSystemOption_H #define PokemonAutomationn_NintendoSwitch_MultiSwitchSystemOption_H -#include -#include -#include "CommonFramework/Globals.h" +#include "Common/Cpp/Containers/FixedLimitVector.h" #include "CommonFramework/Panels/ProgramDescriptor.h" #include "NintendoSwitch_SwitchSystemOption.h" @@ -31,14 +29,12 @@ class MultiSwitchSystemOption{ public: MultiSwitchSystemOption( - FeedbackType feedback, AllowCommandsWhenRunning allow_commands_while_running, size_t min_switches, size_t max_switches, size_t switches ); MultiSwitchSystemOption( - FeedbackType feedback, AllowCommandsWhenRunning allow_commands_while_running, size_t min_switches, size_t max_switches, @@ -54,10 +50,11 @@ class MultiSwitchSystemOption{ size_t max_switches() const{ return m_max_switches; } size_t count() const{ return m_active_switches; } - SwitchSystemOption& operator[](size_t index){ return *m_switches[index]; } + SwitchSystemOption& operator[](size_t index){ return m_switches[index]; } private: + friend class MultiSwitchProgramSession; friend class MultiSwitchSystemWidget; const bool m_allow_commands_while_running; @@ -65,7 +62,7 @@ class MultiSwitchSystemOption{ const size_t m_min_switches; const size_t m_max_switches; size_t m_active_switches; - std::vector> m_switches; + FixedLimitVector m_switches; }; diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemSession.cpp b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemSession.cpp index 4fe15044db..bec36e34db 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemSession.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemSession.cpp @@ -86,6 +86,16 @@ bool MultiSwitchSystemSession::set_switch_count(size_t count){ +void MultiSwitchSystemSession::load_json(const JsonValue& json){ + m_option.load_json(json); + set_switch_count(m_option.count()); +} +JsonValue MultiSwitchSystemSession::to_json() const{ + return m_option.to_json(); +} + + + } diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemSession.h b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemSession.h index 6220052f1b..cff9c726e8 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemSession.h +++ b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemSession.h @@ -63,6 +63,9 @@ class MultiSwitchSystemSession{ size_t count() const{ return m_consoles.size(); } SwitchSystemSession& operator[](size_t index){ return m_consoles[index]; } + void load_json(const JsonValue& json); + JsonValue to_json() const; + private: MultiSwitchSystemOption& m_option; diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_SingleSwitchProgramSession.cpp b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_SingleSwitchProgramSession.cpp index e74ad3280b..dca4733549 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_SingleSwitchProgramSession.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_SingleSwitchProgramSession.cpp @@ -22,10 +22,9 @@ #include "NintendoSwitch_SingleSwitchProgramSession.h" #include "UI/NintendoSwitch_SingleSwitchProgramWidget.h" -// REMOVE -#include -using std::cout; -using std::endl; +//#include +//using std::cout; +//using std::endl; namespace PokemonAutomation{ @@ -274,7 +273,6 @@ void SingleSwitchProgramSession::internal_run_program(){ void SingleSwitchProgramSession::from_json(const JsonValue& json){ - cout << "SingleSwitchProgramSession::from_json()" << endl; const JsonObject* obj = json.to_object(); if (obj == nullptr){ return; @@ -287,7 +285,6 @@ void SingleSwitchProgramSession::from_json(const JsonValue& json){ m_instance->from_json(json); } JsonValue SingleSwitchProgramSession::to_json() const{ - cout << "SingleSwitchProgramSession::to_json()" << endl; JsonObject obj = std::move(*m_instance->to_json().to_object()); obj["SwitchSetup"] = m_system_option.to_json(); return obj; diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.cpp b/SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.cpp index 34ff5000e5..7e7c7b802f 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.cpp @@ -17,7 +17,6 @@ #include "CommonFramework/Panels/UI/PanelElements.h" #include "CommonFramework/ProgramStats/StatsTracking.h" #include "CommonFramework/ResourceDownload/ProgramResourceDownloadWidget.h" -#include "NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.h" #include "NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.h" #include "NintendoSwitch_MultiSwitchProgramWidget.h" @@ -47,16 +46,16 @@ MultiSwitchProgramWidget2::~MultiSwitchProgramWidget2(){ MultiSwitchProgramWidget2::MultiSwitchProgramWidget2( QWidget& parent, - MultiSwitchProgramOption& option + MultiSwitchProgramSession& session ) : QWidget(&parent) - , m_session(option) + , m_session(session) , m_sanitizer("MultiSwitchProgramWidget2") { m_layout = new QVBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); - const MultiSwitchProgramDescriptor& descriptor = option.descriptor(); + const MultiSwitchProgramDescriptor& descriptor = session.descriptor(); CollapsibleGroupBox* header = make_panel_header( *this, @@ -93,7 +92,7 @@ MultiSwitchProgramWidget2::MultiSwitchProgramWidget2( m_system = new MultiSwitchSystemWidget(*this, m_session.system(), m_session.instance_id()); scroll_layout->addWidget(m_system); - m_options = ConfigWidget::make_from_option(option.options(), this); + m_options = ConfigWidget::make_from_option(m_session.options(), this); scroll_layout->addWidget(&m_options->widget()); scroll_layout->addStretch(1); @@ -130,7 +129,7 @@ MultiSwitchProgramWidget2::MultiSwitchProgramWidget2( m_actions_bar, &RunnablePanelActionBar::defaults_clicked, this, [&]{ std::lock_guard lg(m_session.program_lock()); - option.restore_defaults(); + m_session.restore_defaults(); m_options->update_all(false); } ); diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.h b/SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.h index 02446c94e0..2f136184ad 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.h +++ b/SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_MultiSwitchProgramWidget.h @@ -36,7 +36,7 @@ class MultiSwitchProgramWidget2 : public QWidget, private ProgramSession::Listen ~MultiSwitchProgramWidget2(); MultiSwitchProgramWidget2( QWidget& parent, - MultiSwitchProgramOption& option + MultiSwitchProgramSession& session ); private: @@ -52,7 +52,7 @@ class MultiSwitchProgramWidget2 : public QWidget, private ProgramSession::Listen ProgramResourceDownloadTableWidget* ensure_downloads_table(); private: - MultiSwitchProgramSession m_session; + MultiSwitchProgramSession& m_session; QVBoxLayout* m_layout; MultiSwitchSystemWidget* m_system; ConfigWidget* m_options; diff --git a/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.cpp b/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.cpp index 73cc94db66..8f815e9f11 100644 --- a/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.cpp +++ b/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.cpp @@ -12,7 +12,7 @@ #include "CommonTools/StartupChecks/StartProgramChecks.h" #include "Controllers/ControllerSession.h" #include "NintendoSwitch_MultiSwitchProgram.h" -#include "Framework/NintendoSwitch_MultiSwitchProgramOption.h" +#include "Framework/NintendoSwitch_MultiSwitchProgramSession.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -135,7 +135,7 @@ MultiSwitchProgramDescriptor::MultiSwitchProgramDescriptor( , m_default_switches(default_switches) {} std::unique_ptr MultiSwitchProgramDescriptor::make_panel() const{ - return std::unique_ptr(new MultiSwitchProgramOption(*this)); + return std::unique_ptr(new MultiSwitchProgramSession(*this)); } diff --git a/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.h b/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.h index 16941672eb..8d5cdcc5be 100644 --- a/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.h +++ b/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_MultiSwitchProgram.h @@ -176,6 +176,7 @@ class MultiSwitchProgramInstance{ protected: friend class MultiSwitchProgramOption; + friend class MultiSwitchProgramSession; BatchOption m_options; void add_option(ConfigOption& option, std::string serialization_string); diff --git a/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h b/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h index e9059bf0dc..c8247999e7 100644 --- a/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h +++ b/SerialPrograms/Source/NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h @@ -151,7 +151,6 @@ class SingleSwitchProgramInstance{ protected: - friend class SingleSwitchProgramOption; friend class SingleSwitchProgramSession; BatchOption m_options; diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_SwitchViewer.cpp b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_SwitchViewer.cpp index 2983a3dc04..d366010f97 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_SwitchViewer.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_SwitchViewer.cpp @@ -30,7 +30,6 @@ SwitchViewer_Descriptor::SwitchViewer_Descriptor() SwitchViewer::SwitchViewer(const SwitchViewer_Descriptor& descriptor) : PanelSession(descriptor) , m_switches( - FeedbackType::NONE, AllowCommandsWhenRunning::DISABLE_COMMANDS, 1, 4, 1 ) diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 93b38f78f8..ad277940bf 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1179,8 +1179,6 @@ file(GLOB LIBRARY_SOURCES Source/NintendoSwitch/DevPrograms/TestProgramSwitch.h Source/NintendoSwitch/DevPrograms/WaterfillTemplateMaker.cpp Source/NintendoSwitch/DevPrograms/WaterfillTemplateMaker.h - Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.cpp - Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramOption.h Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.cpp Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchProgramSession.h Source/NintendoSwitch/Framework/NintendoSwitch_MultiSwitchSystemOption.cpp