From 5602dfa09a68cbf62ee181af78ce6b16a6c90326 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Sat, 29 Apr 2023 13:37:47 +0200 Subject: [PATCH] Clean up SwitcherData * Moved various functions, members, and definitions * Separated out priority related functionality * Visually grouped various function groups --- CMakeLists.txt | 2 + src/advanced-scene-switcher.cpp | 29 +- src/advanced-scene-switcher.hpp | 13 - src/general.cpp | 84 ++---- src/legacy/switch-file.hpp | 1 + src/legacy/switch-generic.cpp | 3 + src/legacy/switch-random.cpp | 3 +- src/switcher-data-structs.cpp | 24 +- src/switcher-data-structs.hpp | 455 +++++++++++++++----------------- src/utils/priority-helper.cpp | 81 ++++++ src/utils/priority-helper.hpp | 19 ++ 11 files changed, 383 insertions(+), 331 deletions(-) create mode 100644 src/utils/priority-helper.cpp create mode 100644 src/utils/priority-helper.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a17a0cc..bb2dd3d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -261,6 +261,8 @@ target_sources( src/utils/name-dialog.cpp src/utils/name-dialog.hpp src/utils/obs-dock.hpp + src/utils/priority-helper.cpp + src/utils/priority-helper.hpp src/utils/process-config.cpp src/utils/process-config.hpp src/utils/regex-config.cpp diff --git a/src/advanced-scene-switcher.cpp b/src/advanced-scene-switcher.cpp index 567391b0..351a1997 100644 --- a/src/advanced-scene-switcher.cpp +++ b/src/advanced-scene-switcher.cpp @@ -18,12 +18,6 @@ namespace advss { -SwitcherData *switcher = nullptr; -SwitcherData *GetSwitcher() -{ - return switcher; -} - AdvSceneSwitcher *AdvSceneSwitcher::window = nullptr; /****************************************************************************** @@ -555,15 +549,17 @@ void resetLiveTime() void checkAutoStartRecording() { - if (switcher->autoStartEvent == AutoStartEvent::RECORDING || - switcher->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING) + if (switcher->autoStartEvent == SwitcherData::AutoStart::RECORDING || + switcher->autoStartEvent == + SwitcherData::AutoStart::RECORINDG_OR_STREAMING) switcher->Start(); } void checkAutoStartStreaming() { - if (switcher->autoStartEvent == AutoStartEvent::STREAMING || - switcher->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING) + if (switcher->autoStartEvent == SwitcherData::AutoStart::STREAMING || + switcher->autoStartEvent == + SwitcherData::AutoStart::RECORINDG_OR_STREAMING) switcher->Start(); } @@ -726,14 +722,12 @@ void OpenSettingsWindow() } } -extern "C" void InitSceneSwitcher(obs_module_t *m, translateFunc t) +extern "C" void InitSceneSwitcher(obs_module_t *module, translateFunc translate) { blog(LOG_INFO, "version: %s", g_GIT_TAG); blog(LOG_INFO, "version: %s", g_GIT_SHA1); - switcher = new SwitcherData; - switcher->modulePtr = m; - switcher->translate = t; + switcher = new SwitcherData(module, translate); PlatformInit(); LoadPlugins(); @@ -754,10 +748,13 @@ const char *obs_module_text(const char *text) if (!advss::switcher) { return ""; } - return advss::switcher->translate(text); + return advss::switcher->Translate(text); } obs_module_t *obs_current_module() { - return advss::switcher->modulePtr; + if (!advss::switcher) { + return nullptr; + } + return advss::switcher->GetModule(); } diff --git a/src/advanced-scene-switcher.hpp b/src/advanced-scene-switcher.hpp index 5e69708a..01fad3c1 100644 --- a/src/advanced-scene-switcher.hpp +++ b/src/advanced-scene-switcher.hpp @@ -4,12 +4,6 @@ #include -#define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__) -#define vblog(level, msg, ...) \ - if (GetSwitcher()->verbose) { \ - blog(level, msg, ##__VA_ARGS__); \ - } - class QCloseEvent; namespace advss { @@ -381,11 +375,4 @@ public slots: void OpenSettingsWindow(); -/****************************************************************************** - * Main SwitcherData - ******************************************************************************/ -struct SwitcherData; -extern SwitcherData *switcher; -SwitcherData *GetSwitcher(); - } // namespace advss diff --git a/src/general.cpp b/src/general.cpp index f40450fb..7f85dc4e 100644 --- a/src/general.cpp +++ b/src/general.cpp @@ -31,7 +31,7 @@ void AdvSceneSwitcher::on_noMatchDontSwitch_clicked() } std::lock_guard lock(switcher->m); - switcher->switchIfNotMatching = NO_SWITCH; + switcher->switchIfNotMatching = SwitcherData::NoMatch::NO_SWITCH; ui->noMatchSwitchScene->setEnabled(false); ui->randomDisabledWarning->setVisible(true); } @@ -43,7 +43,7 @@ void AdvSceneSwitcher::on_noMatchSwitch_clicked() } std::lock_guard lock(switcher->m); - switcher->switchIfNotMatching = SWITCH; + switcher->switchIfNotMatching = SwitcherData::NoMatch::SWITCH; ui->noMatchSwitchScene->setEnabled(true); UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText()); ui->randomDisabledWarning->setVisible(true); @@ -56,7 +56,7 @@ void AdvSceneSwitcher::on_noMatchRandomSwitch_clicked() } std::lock_guard lock(switcher->m); - switcher->switchIfNotMatching = RANDOM_SWITCH; + switcher->switchIfNotMatching = SwitcherData::NoMatch::RANDOM_SWITCH; ui->noMatchSwitchScene->setEnabled(false); ui->randomDisabledWarning->setVisible(false); } @@ -88,7 +88,8 @@ void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index) } std::lock_guard lock(switcher->m); - switcher->startupBehavior = (StartupBehavior)index; + switcher->startupBehavior = + static_cast(index); } void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index) @@ -98,7 +99,7 @@ void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index) } std::lock_guard lock(switcher->m); - switcher->autoStartEvent = static_cast(index); + switcher->autoStartEvent = static_cast(index); } void AdvSceneSwitcher::on_noMatchSwitchScene_currentTextChanged( @@ -554,14 +555,16 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj) std::string nonMatchingSceneName = GetWeakSourceName(nonMatchingScene); obs_data_set_string(obj, "non_matching_scene", nonMatchingSceneName.c_str()); - obs_data_set_int(obj, "switch_if_not_matching", switchIfNotMatching); + obs_data_set_int(obj, "switch_if_not_matching", + static_cast(switchIfNotMatching)); noMatchDelay.Save(obj, "noMatchDelay"); cooldown.Save(obj, "cooldown"); obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop); sceneColletionStop = false; - obs_data_set_int(obj, "startup_behavior", startupBehavior); + obs_data_set_int(obj, "startup_behavior", + static_cast(startupBehavior)); obs_data_set_int(obj, "autoStartEvent", static_cast(autoStartEvent)); @@ -600,7 +603,8 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj) obs_data_set_default_int(obj, "interval", default_interval); interval = obs_data_get_int(obj, "interval"); - obs_data_set_default_int(obj, "switch_if_not_matching", NO_SWITCH); + obs_data_set_default_int(obj, "switch_if_not_matching", + static_cast(NoMatch::NO_SWITCH)); switchIfNotMatching = (NoMatch)obs_data_get_int(obj, "switch_if_not_matching"); std::string nonMatchingSceneName = @@ -613,15 +617,15 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj) stop = !obs_data_get_bool(obj, "active"); startupBehavior = (StartupBehavior)obs_data_get_int(obj, "startup_behavior"); - if (startupBehavior == START) { + if (startupBehavior == StartupBehavior::START) { stop = false; } - if (startupBehavior == STOP) { + if (startupBehavior == StartupBehavior::STOP) { stop = true; } - autoStartEvent = static_cast( - obs_data_get_int(obj, "autoStartEvent")); + autoStartEvent = + static_cast(obs_data_get_int(obj, "autoStartEvent")); verbose = obs_data_get_bool(obj, "verbose"); showSystemTrayNotifications = @@ -632,53 +636,17 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj) obs_data_set_default_bool(obj, "hideLegacyTabs", true); hideLegacyTabs = obs_data_get_bool(obj, "hideLegacyTabs"); - obs_data_set_default_int(obj, "priority0", default_priority_0); - obs_data_set_default_int(obj, "priority1", default_priority_1); - obs_data_set_default_int(obj, "priority2", default_priority_2); - obs_data_set_default_int(obj, "priority3", default_priority_3); - obs_data_set_default_int(obj, "priority4", default_priority_4); - obs_data_set_default_int(obj, "priority5", default_priority_5); - obs_data_set_default_int(obj, "priority6", default_priority_6); - obs_data_set_default_int(obj, "priority7", default_priority_7); - obs_data_set_default_int(obj, "priority8", default_priority_8); - - functionNamesByPriority[0] = (obs_data_get_int(obj, "priority0")); - functionNamesByPriority[1] = (obs_data_get_int(obj, "priority1")); - functionNamesByPriority[2] = (obs_data_get_int(obj, "priority2")); - functionNamesByPriority[3] = (obs_data_get_int(obj, "priority3")); - functionNamesByPriority[4] = (obs_data_get_int(obj, "priority4")); - functionNamesByPriority[5] = (obs_data_get_int(obj, "priority5")); - functionNamesByPriority[6] = (obs_data_get_int(obj, "priority6")); - functionNamesByPriority[7] = (obs_data_get_int(obj, "priority7")); - functionNamesByPriority[8] = (obs_data_get_int(obj, "priority8")); - functionNamesByPriority[9] = (obs_data_get_int(obj, "priority9")); - functionNamesByPriority[10] = (obs_data_get_int(obj, "priority10")); + SetDefaultFunctionPriorities(obj); if (!prioFuncsValid()) { - functionNamesByPriority[0] = (default_priority_0); - functionNamesByPriority[1] = (default_priority_1); - functionNamesByPriority[2] = (default_priority_2); - functionNamesByPriority[3] = (default_priority_3); - functionNamesByPriority[4] = (default_priority_4); - functionNamesByPriority[5] = (default_priority_5); - functionNamesByPriority[6] = (default_priority_6); - functionNamesByPriority[7] = (default_priority_7); - functionNamesByPriority[8] = (default_priority_8); - functionNamesByPriority[9] = (default_priority_9); - functionNamesByPriority[10] = (default_priority_10); + functionNamesByPriority = GetDefaultFunctionPriorityList(); } obs_data_set_default_int(obj, "threadPriority", QThread::NormalPriority); threadPriority = obs_data_get_int(obj, "threadPriority"); - // TODO: Remove this fallback in future version - if (obs_data_has_user_value(obj, "tansitionOverrideOverride")) { - transitionOverrideOverride = - obs_data_get_bool(obj, "tansitionOverrideOverride"); - } else { - transitionOverrideOverride = - obs_data_get_bool(obj, "transitionOverrideOverride"); - } + transitionOverrideOverride = + obs_data_get_bool(obj, "transitionOverrideOverride"); adjustActiveTransitionType = obs_data_get_bool(obj, "adjustActiveTransitionType"); @@ -838,12 +806,12 @@ void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene, return; } - if (switchIfNotMatching == SWITCH && nonMatchingScene) { + if (switchIfNotMatching == NoMatch::SWITCH && nonMatchingScene) { match = true; scene = nonMatchingScene; transition = nullptr; } - if (switchIfNotMatching == RANDOM_SWITCH) { + if (switchIfNotMatching == NoMatch::RANDOM_SWITCH) { match = checkRandom(scene, transition, sleep); } } @@ -888,10 +856,11 @@ void AdvSceneSwitcher::SetupGeneralTab() { PopulateSceneSelection(ui->noMatchSwitchScene, false); - if (switcher->switchIfNotMatching == SWITCH) { + if (switcher->switchIfNotMatching == SwitcherData::NoMatch::SWITCH) { ui->noMatchSwitch->setChecked(true); ui->noMatchSwitchScene->setEnabled(true); - } else if (switcher->switchIfNotMatching == NO_SWITCH) { + } else if (switcher->switchIfNotMatching == + SwitcherData::NoMatch::NO_SWITCH) { ui->noMatchDontSwitch->setChecked(true); ui->noMatchSwitchScene->setEnabled(false); } else { @@ -998,7 +967,8 @@ void AdvSceneSwitcher::SetupGeneralTab() } populateStartupBehavior(ui->startupBehavior); - ui->startupBehavior->setCurrentIndex(switcher->startupBehavior); + ui->startupBehavior->setCurrentIndex( + static_cast(switcher->startupBehavior)); populateAutoStartEventSelection(ui->autoStartEvent); ui->autoStartEvent->setCurrentIndex( diff --git a/src/legacy/switch-file.hpp b/src/legacy/switch-file.hpp index 955baee9..104c7cba 100644 --- a/src/legacy/switch-file.hpp +++ b/src/legacy/switch-file.hpp @@ -8,6 +8,7 @@ #pragma once #include "switch-generic.hpp" #include +#include #include namespace advss { diff --git a/src/legacy/switch-generic.cpp b/src/legacy/switch-generic.cpp index 4f11d72f..ff28ab1b 100644 --- a/src/legacy/switch-generic.cpp +++ b/src/legacy/switch-generic.cpp @@ -1,6 +1,9 @@ #include "advanced-scene-switcher.hpp" #include "utility.hpp" +constexpr auto previous_scene_name = "Previous Scene"; +constexpr auto current_transition_name = "Current Transition"; + namespace advss { static inline bool SceneGroupValid(SceneGroup *group) diff --git a/src/legacy/switch-random.cpp b/src/legacy/switch-random.cpp index da3a9e07..c789b95e 100644 --- a/src/legacy/switch-random.cpp +++ b/src/legacy/switch-random.cpp @@ -142,7 +142,8 @@ void AdvSceneSwitcher::SetupRandomTab() border-radius: 7px; \ border-color: rgb(0,0,0,0) \ }"); - if (switcher->switchIfNotMatching != RANDOM_SWITCH) { + if (switcher->switchIfNotMatching != + SwitcherData::NoMatch::RANDOM_SWITCH) { if (!switcher->disableHints) { PulseWidget(ui->randomDisabledWarning, QColor(Qt::red), QColor(0, 0, 0, 0)); diff --git a/src/switcher-data-structs.cpp b/src/switcher-data-structs.cpp index 709f06e3..318f091f 100644 --- a/src/switcher-data-structs.cpp +++ b/src/switcher-data-structs.cpp @@ -3,6 +3,28 @@ namespace advss { +SwitcherData *switcher = nullptr; +SwitcherData *GetSwitcher() +{ + return switcher; +} + +SwitcherData::SwitcherData(obs_module_t *m, translateFunc t) +{ + _modulePtr = m; + _translate = t; +} + +const char *SwitcherData::Translate(const char *text) +{ + return _translate(text); +} + +obs_module_t *SwitcherData::GetModule() +{ + return _modulePtr; +} + void SwitcherData::Prune() { for (size_t i = 0; i < windowSwitches.size(); i++) { @@ -13,7 +35,7 @@ void SwitcherData::Prune() } if (nonMatchingScene && !WeakSourceValid(nonMatchingScene)) { - switchIfNotMatching = NO_SWITCH; + switchIfNotMatching = NoMatch::NO_SWITCH; nonMatchingScene = nullptr; } diff --git a/src/switcher-data-structs.hpp b/src/switcher-data-structs.hpp index 594dfa02..1918f11d 100644 --- a/src/switcher-data-structs.hpp +++ b/src/switcher-data-structs.hpp @@ -8,95 +8,124 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "scene-group.hpp" +#include "scene-trigger.hpp" +#include "switch-audio.hpp" +#include "switch-executable.hpp" +#include "switch-file.hpp" +#include "switch-idle.hpp" +#include "switch-media.hpp" +#include "switch-pause.hpp" +#include "switch-random.hpp" +#include "switch-screen-region.hpp" +#include "switch-time.hpp" +#include "switch-transitions.hpp" +#include "switch-window.hpp" +#include "switch-sequence.hpp" +#include "switch-video.hpp" +#include "switch-network.hpp" -#include -#include -#include -#include -#include +#include "macro-properties.hpp" +#include "duration-control.hpp" +#include "connection-manager.hpp" +#include "curl-helper.hpp" +#include "priority-helper.hpp" + +#define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__) +#define vblog(level, msg, ...) \ + if (GetSwitcher()->verbose) { \ + blog(level, msg, ##__VA_ARGS__); \ + } namespace advss { constexpr auto default_interval = 300; -constexpr auto previous_scene_name = "Previous Scene"; -constexpr auto current_transition_name = "Current Transition"; constexpr auto tab_count = 18; -constexpr auto default_priority_0 = macro_func; -constexpr auto default_priority_1 = read_file_func; -constexpr auto default_priority_2 = idle_func; -constexpr auto default_priority_3 = audio_func; -constexpr auto default_priority_4 = media_func; -constexpr auto default_priority_5 = video_func; -constexpr auto default_priority_6 = time_func; -constexpr auto default_priority_7 = screen_region_func; -constexpr auto default_priority_8 = round_trip_func; -constexpr auto default_priority_9 = window_title_func; -constexpr auto default_priority_10 = exe_func; - -typedef enum { NO_SWITCH = 0, SWITCH = 1, RANDOM_SWITCH = 2 } NoMatch; -typedef enum { PERSIST = 0, START = 1, STOP = 2 } StartupBehavior; typedef const char *(*translateFunc)(const char *); -enum class AutoStartEvent { - NEVER, - RECORDING, - STREAMING, - RECORINDG_OR_STREAMING, -}; - class Item; +class Macro; class SwitcherThread; -/******************************************************************************** - * SwitcherData - ********************************************************************************/ -struct SwitcherData { +class SwitcherData; +extern SwitcherData *switcher; +SwitcherData *GetSwitcher(); + +class SwitcherData { +public: + void Thread(); + void Start(); + void Stop(); + std::unique_lock *GetLock() { return mainLoopLock; } + + const char *Translate(const char *); + obs_module_t *GetModule(); + + void setWaitScene(); + bool sceneChangedDuringWait(); + bool anySceneTransitionStarted(); + + void setPreconditions(); + void resetForNextInterval(); + void addResetForNextIntervalFunction(std::function); + bool checkForMatch(OBSWeakSource &scene, OBSWeakSource &transition, + int &linger, bool &setPreviousSceneAsMatch, + bool ¯oMatch); + bool checkMacros(); + bool runMacros(); + void checkNoMatchSwitch(bool &match, OBSWeakSource &scene, + OBSWeakSource &transition, int &sleep); + + /* --- Start of saving / loading section --- */ + + void saveSettings(obs_data_t *obj); + void saveMacros(obs_data_t *obj); + void saveConnections(obs_data_t *obj); + void saveVariables(obs_data_t *obj); + void saveGeneralSettings(obs_data_t *obj); + void saveHotkeys(obs_data_t *obj); + void saveUISettings(obs_data_t *obj); + void saveVersion(obs_data_t *obj, const std::string ¤tVersion); + + void loadSettings(obs_data_t *obj); + void loadMacros(obs_data_t *obj); + void loadConnections(obs_data_t *obj); + void loadVariables(obs_data_t *obj); + void loadGeneralSettings(obs_data_t *obj); + void loadHotkeys(obs_data_t *obj); + void loadUISettings(obs_data_t *obj); + + bool versionChanged(obs_data_t *obj, std::string currentVersion); + bool tabOrderValid(); + void resetTabOrder(); + bool prioFuncsValid(); + + /* --- End of saving / loading section --- */ + + SwitcherData(obs_module_t *m, translateFunc t); + inline ~SwitcherData() { Stop(); } + +public: SwitcherThread *th = nullptr; - obs_module_t *modulePtr = nullptr; - translateFunc translate = nullptr; - - bool settingsWindowOpened = false; - int lastOpenedTab = -1; - std::string lastImportPath; - bool firstBoot = true; - - std::condition_variable cv; std::mutex m; std::unique_lock *mainLoopLock = nullptr; - - bool transitionActive = false; - bool waitForTransition = false; bool stop = false; + std::condition_variable cv; + std::condition_variable macroWaitCv; + std::atomic_bool abortMacroWait = {false}; + std::condition_variable macroTransitionCv; + + std::vector> resetForNextIntervalFuncs; + + bool firstBoot = true; + bool transitionActive = false; bool sceneColletionStop = false; - bool verbose = false; - bool disableHints = false; - bool hideLegacyTabs = true; - bool showSystemTrayNotifications = false; - bool showFrame = false; - bool transitionOverrideOverride = false; - bool adjustActiveTransitionType = true; - - int interval = default_interval; - - QStringList loadFailureLibs; - bool warnPluginLoadFailure = true; + bool replayBufferSaved = false; + bool obsIsShuttingDown = false; + bool firstInterval = true; + bool firstIntervalAfterStop = true; + int shutdownConditionCount = 0; obs_source_t *waitScene = nullptr; OBSWeakSource currentScene = nullptr; @@ -105,13 +134,31 @@ struct SwitcherData { std::chrono::high_resolution_clock::time_point lastTransitionEndTime{}; std::chrono::high_resolution_clock::time_point lastStreamStartingTime{}; std::chrono::high_resolution_clock::time_point lastStreamStoppingTime{}; - OBSWeakSource lastRandomScene; - SceneGroup *lastRandomSceneGroup = nullptr; + std::chrono::high_resolution_clock::time_point lastMatchTime; + + /* --- Start of General tab section --- */ + + int interval = default_interval; OBSWeakSource nonMatchingScene; - NoMatch switchIfNotMatching = NO_SWITCH; + enum class NoMatch { NO_SWITCH = 0, SWITCH = 1, RANDOM_SWITCH = 2 }; + NoMatch switchIfNotMatching = NoMatch::NO_SWITCH; Duration noMatchDelay; - StartupBehavior startupBehavior = PERSIST; - AutoStartEvent autoStartEvent = AutoStartEvent::NEVER; + enum class StartupBehavior { PERSIST = 0, START = 1, STOP = 2 }; + StartupBehavior startupBehavior = StartupBehavior::PERSIST; + enum class AutoStart { + NEVER, + RECORDING, + STREAMING, + RECORINDG_OR_STREAMING + }; + AutoStart autoStartEvent = AutoStart::NEVER; + Duration cooldown; + bool showSystemTrayNotifications = false; + bool transitionOverrideOverride = false; + bool adjustActiveTransitionType = true; + bool verbose = false; + + /* --- End of General tab section --- */ struct AudioFadeInfo { std::atomic_bool active = {false}; @@ -120,111 +167,27 @@ struct SwitcherData { AudioFadeInfo masterAudioFade; std::unordered_map activeAudioFades; - Duration cooldown; - std::chrono::high_resolution_clock::time_point lastMatchTime; - MacroProperties macroProperties; std::deque> macros; - std::condition_variable macroWaitCv; - std::atomic_bool abortMacroWait = {false}; - std::condition_variable macroTransitionCv; bool macroSceneSwitched = false; - bool replayBufferSaved = false; - bool obsIsShuttingDown = false; - bool firstInterval = true; - bool firstIntervalAfterStop = true; - int shutdownConditionCount = 0; Curlhelper curl; - std::deque> connections; std::vector websocketMessages; - std::deque> variables; - std::deque windowSwitches; - std::vector ignoreIdleWindows; std::string lastTitle; std::string currentTitle; std::string currentForegroundProcess; - - std::deque screenRegionSwitches; std::pair lastCursorPos = {0, 0}; bool cursorPosChanged = false; - std::vector ignoreWindowsSwitches; - - bool uninterruptibleSceneSequenceActive = false; - std::deque sceneSequenceSwitches; - - std::deque randomSwitches; - - IdleData idleData; - - FileIOData fileIO; - std::deque fileSwitches; - - std::deque executableSwitches; - - std::deque sceneTriggers; - - std::deque sceneTransitions; - std::deque defaultSceneTransitions; - - std::deque mediaSwitches; - - std::deque pauseEntries; - - std::deque timeSwitches; - QDateTime liveTime; - - std::deque audioSwitches; - AudioSwitchFallback audioFallback; - - WSServer server; - ServerStatus serverStatus = ServerStatus::NOT_RUNNING; - WSClient client; - ClientStatus clientStatus = ClientStatus::DISCONNECTED; - NetworkConfig networkConfig; - - std::deque videoSwitches; - - std::deque sceneGroups; - - std::vector functionNamesByPriority = std::vector{ - default_priority_0, default_priority_1, default_priority_2, - default_priority_3, default_priority_4, default_priority_5, - default_priority_6, default_priority_7, default_priority_8, - default_priority_9, default_priority_10}; - - struct ThreadPrio { - std::string name; - std::string description; - uint32_t value; - }; - - std::vector threadPriorities{ - {"Idle", - "scheduled only when no other threads are running (lowest CPU load)", - QThread::IdlePriority}, - {"Lowest", "scheduled less often than LowPriority", - QThread::LowestPriority}, - {"Low", "scheduled less often than NormalPriority", - QThread::LowPriority}, - {"Normal", "the default priority of the operating system", - QThread::NormalPriority}, - {"High", "scheduled more often than NormalPriority", - QThread::HighPriority}, - {"Highest", "scheduled more often than HighPriority", - QThread::HighestPriority}, - {"Time critical", - "scheduled as often as possible (highest CPU load)", - QThread::TimeCriticalPriority}, - }; - + std::vector functionNamesByPriority = + GetDefaultFunctionPriorityList(); + const std::vector threadPriorities = GetThreadPrioMapping(); uint32_t threadPriority = QThread::NormalPriority; - std::vector tabOrder = std::vector(tab_count); + /* --- Start of hotkey section --- */ bool hotkeysRegistered = false; obs_hotkey_id startHotkey = OBS_INVALID_HOTKEY_ID; @@ -234,40 +197,64 @@ struct SwitcherData { obs_hotkey_id downMacroSegment = OBS_INVALID_HOTKEY_ID; obs_hotkey_id removeMacroSegment = OBS_INVALID_HOTKEY_ID; + /* --- End of hotkey section --- */ + + /* --- Start of UI section --- */ + + bool settingsWindowOpened = false; + int lastOpenedTab = -1; + std::string lastImportPath; + QStringList loadFailureLibs; + bool warnPluginLoadFailure = true; + bool disableHints = false; + bool hideLegacyTabs = true; + std::vector tabOrder = std::vector(tab_count); bool saveWindowGeo = false; QPoint windowPos = {}; QSize windowSize = {}; QList macroActionConditionSplitterPosition; QList macroListMacroEditSplitterPosition; - bool versionChanged(obs_data_t *obj, std::string currentVersion); + /* --- End of UI section --- */ - void Thread(); - void Start(); - void Stop(); - std::unique_lock *GetLock() { return mainLoopLock; } + /* --- Start of legacy tab section --- */ - void setWaitScene(); - bool sceneChangedDuringWait(); - bool anySceneTransitionStarted(); + void saveWindowTitleSwitches(obs_data_t *obj); + void saveScreenRegionSwitches(obs_data_t *obj); + void savePauseSwitches(obs_data_t *obj); + void saveSceneSequenceSwitches(obs_data_t *obj); + void saveSceneTransitions(obs_data_t *obj); + void saveIdleSwitches(obs_data_t *obj); + void saveExecutableSwitches(obs_data_t *obj); + void saveRandomSwitches(obs_data_t *obj); + void saveFileSwitches(obs_data_t *obj); + void saveMediaSwitches(obs_data_t *obj); + void saveTimeSwitches(obs_data_t *obj); + void saveAudioSwitches(obs_data_t *obj); + void saveSceneGroups(obs_data_t *obj); + void saveSceneTriggers(obs_data_t *obj); + void saveVideoSwitches(obs_data_t *obj); + void saveNetworkSwitches(obs_data_t *obj); - bool prioFuncsValid(); + void loadWindowTitleSwitches(obs_data_t *obj); + void loadScreenRegionSwitches(obs_data_t *obj); + void loadPauseSwitches(obs_data_t *obj); + void loadSceneSequenceSwitches(obs_data_t *obj); + void loadSceneTransitions(obs_data_t *obj); + void loadIdleSwitches(obs_data_t *obj); + void loadExecutableSwitches(obs_data_t *obj); + void loadRandomSwitches(obs_data_t *obj); + void loadFileSwitches(obs_data_t *obj); + void loadMediaSwitches(obs_data_t *obj); + void loadTimeSwitches(obs_data_t *obj); + void loadAudioSwitches(obs_data_t *obj); + void loadSceneGroups(obs_data_t *obj); + void loadSceneTriggers(obs_data_t *obj); + void loadVideoSwitches(obs_data_t *obj); + void loadNetworkSettings(obs_data_t *obj); - bool tabOrderValid(); - void resetTabOrder(); + void Prune(); - void writeSceneInfoToFile(); - void writeToStatusFile(const QString &msg); - - void setPreconditions(); - void resetForNextInterval(); - void addResetForNextIntervalFunction(std::function); - std::vector> resetForNextIntervalFuncs; - bool checkForMatch(OBSWeakSource &scene, OBSWeakSource &transition, - int &linger, bool &setPreviousSceneAsMatch, - bool ¯oMatch); - bool checkMacros(); - bool runMacros(); bool checkSceneSequence(OBSWeakSource &scene, OBSWeakSource &transition, int &linger, bool &setPrevSceneAfterLinger); bool checkIdleSwitch(OBSWeakSource &scene, OBSWeakSource &transition); @@ -287,68 +274,50 @@ struct SwitcherData { void checkAudioSwitchFallback(OBSWeakSource &scene, OBSWeakSource &transition); bool checkVideoSwitch(OBSWeakSource &scene, OBSWeakSource &transition); - void checkNoMatchSwitch(bool &match, OBSWeakSource &scene, - OBSWeakSource &transition, int &sleep); - void checkSwitchCooldown(bool &match); void checkTriggers(); bool checkPause(); void checkDefaultSceneTransitions(); + void writeSceneInfoToFile(); + void writeToStatusFile(const QString &msg); + void checkSwitchCooldown(bool &match); - void saveSettings(obs_data_t *obj); - void saveMacros(obs_data_t *obj); - void saveConnections(obs_data_t *obj); - void saveVariables(obs_data_t *obj); - void saveWindowTitleSwitches(obs_data_t *obj); - void saveScreenRegionSwitches(obs_data_t *obj); - void savePauseSwitches(obs_data_t *obj); - void saveSceneSequenceSwitches(obs_data_t *obj); - void saveSceneTransitions(obs_data_t *obj); - void saveIdleSwitches(obs_data_t *obj); - void saveExecutableSwitches(obs_data_t *obj); - void saveRandomSwitches(obs_data_t *obj); - void saveFileSwitches(obs_data_t *obj); - void saveMediaSwitches(obs_data_t *obj); - void saveTimeSwitches(obs_data_t *obj); - void saveAudioSwitches(obs_data_t *obj); - void saveSceneGroups(obs_data_t *obj); - void saveSceneTriggers(obs_data_t *obj); - void saveVideoSwitches(obs_data_t *obj); - void saveNetworkSwitches(obs_data_t *obj); - void saveGeneralSettings(obs_data_t *obj); - void saveHotkeys(obs_data_t *obj); - void saveUISettings(obs_data_t *obj); - void saveVersion(obs_data_t *obj, const std::string ¤tVersion); + std::deque windowSwitches; + std::vector ignoreWindowsSwitches; + IdleData idleData; + std::vector ignoreIdleWindows; + bool showFrame = false; + std::deque screenRegionSwitches; + bool uninterruptibleSceneSequenceActive = false; + std::deque sceneSequenceSwitches; + std::deque randomSwitches; + OBSWeakSource lastRandomScene; + FileIOData fileIO; + std::deque fileSwitches; + std::deque executableSwitches; + std::deque sceneTriggers; + std::deque sceneTransitions; + std::deque defaultSceneTransitions; + std::deque mediaSwitches; + std::deque pauseEntries; + std::deque timeSwitches; + QDateTime liveTime; + std::deque audioSwitches; + AudioSwitchFallback audioFallback; + WSServer server; + ServerStatus serverStatus = ServerStatus::NOT_RUNNING; + WSClient client; + ClientStatus clientStatus = ClientStatus::DISCONNECTED; + NetworkConfig networkConfig; + std::deque videoSwitches; + std::deque sceneGroups; + SceneGroup *lastRandomSceneGroup = nullptr; - void loadSettings(obs_data_t *obj); - void loadMacros(obs_data_t *obj); - void loadConnections(obs_data_t *obj); - void loadVariables(obs_data_t *obj); - void loadWindowTitleSwitches(obs_data_t *obj); - void loadScreenRegionSwitches(obs_data_t *obj); - void loadPauseSwitches(obs_data_t *obj); - void loadSceneSequenceSwitches(obs_data_t *obj); - void loadSceneTransitions(obs_data_t *obj); - void loadIdleSwitches(obs_data_t *obj); - void loadExecutableSwitches(obs_data_t *obj); - void loadRandomSwitches(obs_data_t *obj); - void loadFileSwitches(obs_data_t *obj); - void loadMediaSwitches(obs_data_t *obj); - void loadTimeSwitches(obs_data_t *obj); - void loadAudioSwitches(obs_data_t *obj); - void loadSceneGroups(obs_data_t *obj); - void loadSceneTriggers(obs_data_t *obj); - void loadVideoSwitches(obs_data_t *obj); - void loadNetworkSettings(obs_data_t *obj); - void loadGeneralSettings(obs_data_t *obj); - void loadHotkeys(obs_data_t *obj); - void loadUISettings(obs_data_t *obj); - - void Prune(); - - inline ~SwitcherData() { Stop(); } + /* --- End of legacy tab section --- */ +private: + obs_module_t *_modulePtr = nullptr; + translateFunc _translate = nullptr; }; -extern SwitcherData *switcher; class SwitcherThread : public QThread { public: explicit SwitcherThread(){}; diff --git a/src/utils/priority-helper.cpp b/src/utils/priority-helper.cpp new file mode 100644 index 00000000..e943cb9a --- /dev/null +++ b/src/utils/priority-helper.cpp @@ -0,0 +1,81 @@ +#include "priority-helper.hpp" +#include "scene-group.hpp" +#include "scene-trigger.hpp" +#include "switch-audio.hpp" +#include "switch-executable.hpp" +#include "switch-file.hpp" +#include "switch-idle.hpp" +#include "switch-media.hpp" +#include "switch-pause.hpp" +#include "switch-random.hpp" +#include "switch-screen-region.hpp" +#include "switch-time.hpp" +#include "switch-transitions.hpp" +#include "switch-window.hpp" +#include "switch-sequence.hpp" +#include "switch-video.hpp" +#include "switch-network.hpp" +#include "macro.hpp" + +#include + +namespace advss { + +constexpr auto default_priority_0 = macro_func; +constexpr auto default_priority_1 = read_file_func; +constexpr auto default_priority_2 = idle_func; +constexpr auto default_priority_3 = audio_func; +constexpr auto default_priority_4 = media_func; +constexpr auto default_priority_5 = video_func; +constexpr auto default_priority_6 = time_func; +constexpr auto default_priority_7 = screen_region_func; +constexpr auto default_priority_8 = round_trip_func; +constexpr auto default_priority_9 = window_title_func; +constexpr auto default_priority_10 = exe_func; + +void SetDefaultFunctionPriorities(obs_data_t *obj) +{ + obs_data_set_default_int(obj, "priority0", default_priority_0); + obs_data_set_default_int(obj, "priority1", default_priority_1); + obs_data_set_default_int(obj, "priority2", default_priority_2); + obs_data_set_default_int(obj, "priority3", default_priority_3); + obs_data_set_default_int(obj, "priority4", default_priority_4); + obs_data_set_default_int(obj, "priority5", default_priority_5); + obs_data_set_default_int(obj, "priority6", default_priority_6); + obs_data_set_default_int(obj, "priority7", default_priority_7); + obs_data_set_default_int(obj, "priority8", default_priority_8); + obs_data_set_default_int(obj, "priority9", default_priority_9); + obs_data_set_default_int(obj, "priority10", default_priority_10); +} + +std::vector GetDefaultFunctionPriorityList() +{ + return {default_priority_0, default_priority_1, default_priority_2, + default_priority_3, default_priority_4, default_priority_5, + default_priority_6, default_priority_7, default_priority_8, + default_priority_9, default_priority_10}; +} + +std::vector GetThreadPrioMapping() +{ + return { + {"Idle", + "scheduled only when no other threads are running (lowest CPU load)", + QThread::IdlePriority}, + {"Lowest", "scheduled less often than LowPriority", + QThread::LowestPriority}, + {"Low", "scheduled less often than NormalPriority", + QThread::LowPriority}, + {"Normal", "the default priority of the operating system", + QThread::NormalPriority}, + {"High", "scheduled more often than NormalPriority", + QThread::HighPriority}, + {"Highest", "scheduled more often than HighPriority", + QThread::HighestPriority}, + {"Time critical", + "scheduled as often as possible (highest CPU load)", + QThread::TimeCriticalPriority}, + }; +} + +} // namespace advss diff --git a/src/utils/priority-helper.hpp b/src/utils/priority-helper.hpp new file mode 100644 index 00000000..f73b5aef --- /dev/null +++ b/src/utils/priority-helper.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include + +#include + +namespace advss { + +struct ThreadPrio { + std::string name; + std::string description; + uint32_t value; +}; + +std::vector GetDefaultFunctionPriorityList(); +void SetDefaultFunctionPriorities(obs_data_t *); +std::vector GetThreadPrioMapping(); + +} // namespace advss