Clean up SwitcherData

* Moved various functions, members, and definitions
 * Separated out priority related functionality
 * Visually grouped various function groups
This commit is contained in:
WarmUpTill
2023-04-29 13:37:47 +02:00
committed by WarmUpTill
parent 0138b412b4
commit 5602dfa09a
11 changed files with 383 additions and 331 deletions

View File

@@ -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

View File

@@ -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();
}

View File

@@ -4,12 +4,6 @@
#include <ui_advanced-scene-switcher.h>
#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

View File

@@ -31,7 +31,7 @@ void AdvSceneSwitcher::on_noMatchDontSwitch_clicked()
}
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lock(switcher->m);
switcher->startupBehavior = (StartupBehavior)index;
switcher->startupBehavior =
static_cast<SwitcherData::StartupBehavior>(index);
}
void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
@@ -98,7 +99,7 @@ void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
}
std::lock_guard<std::mutex> lock(switcher->m);
switcher->autoStartEvent = static_cast<AutoStartEvent>(index);
switcher->autoStartEvent = static_cast<SwitcherData::AutoStart>(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<int>(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<int>(startupBehavior));
obs_data_set_int(obj, "autoStartEvent",
static_cast<int>(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<int>(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<AutoStartEvent>(
obs_data_get_int(obj, "autoStartEvent"));
autoStartEvent =
static_cast<AutoStart>(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<int>(switcher->startupBehavior));
populateAutoStartEventSelection(ui->autoStartEvent);
ui->autoStartEvent->setCurrentIndex(

View File

@@ -8,6 +8,7 @@
#pragma once
#include "switch-generic.hpp"
#include <QPlainTextEdit>
#include <QDateTime>
#include <obs-module.h>
namespace advss {

View File

@@ -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)

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -8,95 +8,124 @@
#include <curl/curl.h>
#include <unordered_map>
#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 "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 <macro-properties.hpp>
#include <duration-control.hpp>
#include <connection-manager.hpp>
#include <curl-helper.hpp>
#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<std::mutex> *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<void()>);
bool checkForMatch(OBSWeakSource &scene, OBSWeakSource &transition,
int &linger, bool &setPreviousSceneAsMatch,
bool &macroMatch);
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 &currentVersion);
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<std::mutex> *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<std::function<void()>> 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<std::string, AudioFadeInfo> activeAudioFades;
Duration cooldown;
std::chrono::high_resolution_clock::time_point lastMatchTime;
MacroProperties macroProperties;
std::deque<std::shared_ptr<Macro>> 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<std::shared_ptr<Item>> connections;
std::vector<std::string> websocketMessages;
std::deque<std::shared_ptr<Item>> variables;
std::deque<WindowSwitch> windowSwitches;
std::vector<std::string> ignoreIdleWindows;
std::string lastTitle;
std::string currentTitle;
std::string currentForegroundProcess;
std::deque<ScreenRegionSwitch> screenRegionSwitches;
std::pair<int, int> lastCursorPos = {0, 0};
bool cursorPosChanged = false;
std::vector<std::string> ignoreWindowsSwitches;
bool uninterruptibleSceneSequenceActive = false;
std::deque<SceneSequenceSwitch> sceneSequenceSwitches;
std::deque<RandomSwitch> randomSwitches;
IdleData idleData;
FileIOData fileIO;
std::deque<FileSwitch> fileSwitches;
std::deque<ExecutableSwitch> executableSwitches;
std::deque<SceneTrigger> sceneTriggers;
std::deque<SceneTransition> sceneTransitions;
std::deque<DefaultSceneTransition> defaultSceneTransitions;
std::deque<MediaSwitch> mediaSwitches;
std::deque<PauseEntry> pauseEntries;
std::deque<TimeSwitch> timeSwitches;
QDateTime liveTime;
std::deque<AudioSwitch> audioSwitches;
AudioSwitchFallback audioFallback;
WSServer server;
ServerStatus serverStatus = ServerStatus::NOT_RUNNING;
WSClient client;
ClientStatus clientStatus = ClientStatus::DISCONNECTED;
NetworkConfig networkConfig;
std::deque<VideoSwitch> videoSwitches;
std::deque<SceneGroup> sceneGroups;
std::vector<int> functionNamesByPriority = std::vector<int>{
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<ThreadPrio> 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<int> functionNamesByPriority =
GetDefaultFunctionPriorityList();
const std::vector<ThreadPrio> threadPriorities = GetThreadPrioMapping();
uint32_t threadPriority = QThread::NormalPriority;
std::vector<int> tabOrder = std::vector<int>(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<int> tabOrder = std::vector<int>(tab_count);
bool saveWindowGeo = false;
QPoint windowPos = {};
QSize windowSize = {};
QList<int> macroActionConditionSplitterPosition;
QList<int> macroListMacroEditSplitterPosition;
bool versionChanged(obs_data_t *obj, std::string currentVersion);
/* --- End of UI section --- */
void Thread();
void Start();
void Stop();
std::unique_lock<std::mutex> *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<void()>);
std::vector<std::function<void()>> resetForNextIntervalFuncs;
bool checkForMatch(OBSWeakSource &scene, OBSWeakSource &transition,
int &linger, bool &setPreviousSceneAsMatch,
bool &macroMatch);
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 &currentVersion);
std::deque<WindowSwitch> windowSwitches;
std::vector<std::string> ignoreWindowsSwitches;
IdleData idleData;
std::vector<std::string> ignoreIdleWindows;
bool showFrame = false;
std::deque<ScreenRegionSwitch> screenRegionSwitches;
bool uninterruptibleSceneSequenceActive = false;
std::deque<SceneSequenceSwitch> sceneSequenceSwitches;
std::deque<RandomSwitch> randomSwitches;
OBSWeakSource lastRandomScene;
FileIOData fileIO;
std::deque<FileSwitch> fileSwitches;
std::deque<ExecutableSwitch> executableSwitches;
std::deque<SceneTrigger> sceneTriggers;
std::deque<SceneTransition> sceneTransitions;
std::deque<DefaultSceneTransition> defaultSceneTransitions;
std::deque<MediaSwitch> mediaSwitches;
std::deque<PauseEntry> pauseEntries;
std::deque<TimeSwitch> timeSwitches;
QDateTime liveTime;
std::deque<AudioSwitch> audioSwitches;
AudioSwitchFallback audioFallback;
WSServer server;
ServerStatus serverStatus = ServerStatus::NOT_RUNNING;
WSClient client;
ClientStatus clientStatus = ClientStatus::DISCONNECTED;
NetworkConfig networkConfig;
std::deque<VideoSwitch> videoSwitches;
std::deque<SceneGroup> 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(){};

View File

@@ -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 <QThread>
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<int> 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<ThreadPrio> 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

View File

@@ -0,0 +1,19 @@
#pragma once
#include <vector>
#include <string>
#include <obs-data.h>
namespace advss {
struct ThreadPrio {
std::string name;
std::string description;
uint32_t value;
};
std::vector<int> GetDefaultFunctionPriorityList();
void SetDefaultFunctionPriorities(obs_data_t *);
std::vector<ThreadPrio> GetThreadPrioMapping();
} // namespace advss