diff --git a/advanced-scene-switcher.cpp b/advanced-scene-switcher.cpp index c92267c2..9c367e2b 100644 --- a/advanced-scene-switcher.cpp +++ b/advanced-scene-switcher.cpp @@ -55,6 +55,7 @@ SceneSwitcher::SceneSwitcher(QWidget* parent) ui->executableScenes->addItem(name); ui->idleScenes->addItem(name); ui->randomScenes->addItem(name); + ui->fileScenes->addItem(name); temp++; } @@ -72,6 +73,7 @@ SceneSwitcher::SceneSwitcher(QWidget* parent) ui->executableTransitions->addItem(name); ui->idleTransitions->addItem(name); ui->randomTransitions->addItem(name); + ui->fileTransitions->addItem(name); } obs_frontend_source_list_free(transitions); @@ -242,6 +244,17 @@ SceneSwitcher::SceneSwitcher(QWidget* parent) item->setData(Qt::UserRole, text); } + for (auto& s : switcher->fileSwitches) + { + string sceneName = GetWeakSourceName(s.scene); + string transitionName = GetWeakSourceName(s.transition); + QString listText = MakeFileSwitchName( + sceneName.c_str(), transitionName.c_str(), s.file.c_str(), s.text.c_str()); + + QListWidgetItem* item = new QListWidgetItem(listText, ui->fileScenesList); + item->setData(Qt::UserRole, listText); + } + ui->idleCheckBox->setChecked(switcher->idleData.idleEnable); ui->idleScenes->setCurrentText(GetWeakSourceName(switcher->idleData.scene).c_str()); ui->idleTransitions->setCurrentText(GetWeakSourceName(switcher->idleData.transition).c_str()); @@ -287,8 +300,28 @@ SceneSwitcher::SceneSwitcher(QWidget* parent) connect(screenRegionTimer, SIGNAL(timeout()), this, SLOT(updateScreenRegionCursorPos())); screenRegionTimer->start(1000); - for (string s : switcher->functionNamesByPriority) + for (int p : switcher->functionNamesByPriority) { + string s = ""; + switch (p) { + case READ_FILE_FUNC: + s = "File Content"; + break; + case ROUND_TRIP_FUNC: + s = "Scene Sequence"; + break; + case IDLE_FUNC: + s = "Idle Detection"; + break; + case EXE_FUNC: + s = "Executable"; + break; + case SCREEN_REGION_FUNC: + s = "Screen Region"; + break; + case WINDOW_TITLE_FUNC: + s = "Window Title"; + } QString text(s.c_str()); QListWidgetItem* item = new QListWidgetItem(text, ui->priorityList); item->setData(Qt::UserRole, text); @@ -315,6 +348,7 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_array_t* ignoreIdleWindowsArray = obs_data_array_create(); obs_data_array_t* executableArray = obs_data_array_create(); obs_data_array_t* randomArray = obs_data_array_create(); + obs_data_array_t* fileArray = obs_data_array_create(); switcher->Prune(); @@ -524,6 +558,29 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_release(array_obj); } + for (FileSwitch& s : switcher->fileSwitches) + { + obs_data_t* array_obj = obs_data_create(); + + obs_source_t* source = obs_weak_source_get_source(s.scene); + obs_source_t* transition = obs_weak_source_get_source(s.transition); + + if (source && transition) + { + const char* sceneName = obs_source_get_name(source); + const char* transitionName = obs_source_get_name(transition); + obs_data_set_string(array_obj, "scene", sceneName); + obs_data_set_string(array_obj, "transition", transitionName); + obs_data_set_string(array_obj, "file", s.file.c_str()); + obs_data_set_string(array_obj, "text", s.text.c_str()); + obs_data_array_push_back(fileArray, array_obj); + obs_source_release(source); + obs_source_release(transition); + } + + obs_data_release(array_obj); + } + string nonMatchingSceneName = GetWeakSourceName(switcher->nonMatchingScene); obs_data_set_int(obj, "interval", switcher->interval); @@ -542,6 +599,7 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_set_array(obj, "executableSwitches", executableArray); obs_data_set_array(obj, "ignoreIdleWindows", ignoreIdleWindowsArray); obs_data_set_array(obj, "randomSwitches", randomArray); + obs_data_set_array(obj, "fileSwitches", fileArray); string autoStopSceneName = GetWeakSourceName(switcher->autoStopScene); @@ -560,12 +618,12 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_set_bool(obj, "writeEnabled", switcher->fileIO.writeEnabled); obs_data_set_string(obj, "writePath", switcher->fileIO.writePath.c_str()); - obs_data_set_string(obj, "priority0", switcher->functionNamesByPriority[0].c_str()); - obs_data_set_string(obj, "priority1", switcher->functionNamesByPriority[1].c_str()); - obs_data_set_string(obj, "priority2", switcher->functionNamesByPriority[2].c_str()); - obs_data_set_string(obj, "priority3", switcher->functionNamesByPriority[3].c_str()); - obs_data_set_string(obj, "priority4", switcher->functionNamesByPriority[4].c_str()); - obs_data_set_string(obj, "priority5", switcher->functionNamesByPriority[5].c_str()); + obs_data_set_int(obj, "priority0", switcher->functionNamesByPriority[0]); + obs_data_set_int(obj, "priority1", switcher->functionNamesByPriority[1]); + obs_data_set_int(obj, "priority2", switcher->functionNamesByPriority[2]); + obs_data_set_int(obj, "priority3", switcher->functionNamesByPriority[3]); + obs_data_set_int(obj, "priority4", switcher->functionNamesByPriority[4]); + obs_data_set_int(obj, "priority5", switcher->functionNamesByPriority[5]); obs_data_set_obj(save_data, "advanced-scene-switcher", obj); @@ -580,6 +638,7 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_array_release(executableArray); obs_data_array_release(ignoreIdleWindowsArray); obs_data_array_release(randomArray); + obs_data_array_release(fileArray); obs_data_release(obj); } @@ -599,6 +658,7 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_array_t* executableArray = obs_data_get_array(obj, "executableSwitches"); obs_data_array_t* ignoreIdleWindowsArray = obs_data_get_array(obj, "ignoreIdleWindows"); obs_data_array_t* randomArray = obs_data_get_array(obj, "randomSwitches"); + obs_data_array_t* fileArray = obs_data_get_array(obj, "fileSwitches"); if (!obj) obj = obs_data_create(); @@ -606,6 +666,7 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_set_default_int(obj, "interval", DEFAULT_INTERVAL); switcher->interval = obs_data_get_int(obj, "interval"); + obs_data_set_default_int(obj, "switch_if_not_matching", NO_SWITCH); switcher->switchIfNotMatching = (NoMatch)obs_data_get_int(obj, "switch_if_not_matching"); string nonMatchingScene = obs_data_get_string(obj, "non_matching_scene"); bool active = obs_data_get_bool(obj, "active"); @@ -786,6 +847,7 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_release(array_obj); } + switcher->randomSwitches.clear(); count = obs_data_array_count(randomArray); for (size_t i = 0; i < count; i++) @@ -795,7 +857,7 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) const char* scene = obs_data_get_string(array_obj, "scene"); const char* transition = obs_data_get_string(array_obj, "transition"); double delay = obs_data_get_double(array_obj, "delay"); - string str = obs_data_get_string(array_obj, "str"); + const char* str = obs_data_get_string(array_obj, "str"); switcher->randomSwitches.emplace_back( GetWeakSourceByName(scene), GetWeakTransitionByName(transition), delay, str); @@ -803,6 +865,24 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_release(array_obj); } + switcher->fileSwitches.clear(); + count = obs_data_array_count(fileArray); + + for (size_t i = 0; i < count; i++) + { + obs_data_t* array_obj = obs_data_array_item(fileArray, i); + + const char* scene = obs_data_get_string(array_obj, "scene"); + const char* transition = obs_data_get_string(array_obj, "transition"); + const char* file = obs_data_get_string(array_obj, "file"); + const char* text = obs_data_get_string(array_obj, "text"); + + switcher->fileSwitches.emplace_back( + GetWeakSourceByName(scene), GetWeakTransitionByName(transition), file, text); + + obs_data_release(array_obj); + } + string autoStopScene = obs_data_get_string(obj, "autoStopSceneName"); switcher->autoStopEnable = obs_data_get_bool(obj, "autoStopEnable"); switcher->autoStopScene = GetWeakSourceByName(autoStopScene.c_str()); @@ -811,27 +891,31 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) string idleTransitionName = obs_data_get_string(obj, "idleTransitionName"); switcher->idleData.scene = GetWeakSourceByName(idleSceneName.c_str()); switcher->idleData.transition = GetWeakTransitionByName(idleTransitionName.c_str()); + obs_data_set_default_bool(obj, "idleEnable", false); switcher->idleData.idleEnable = obs_data_get_bool(obj, "idleEnable"); + obs_data_set_default_int(obj, "idleTime", DEFAULT_IDLE_TIME); switcher->idleData.time = obs_data_get_int(obj, "idleTime"); + obs_data_set_default_bool(obj, "readEnabled", false); switcher->fileIO.readEnabled = obs_data_get_bool(obj, "readEnabled"); switcher->fileIO.readPath = obs_data_get_string(obj, "readPath"); + obs_data_set_default_bool(obj, "writeEnabled", false); switcher->fileIO.writeEnabled = obs_data_get_bool(obj, "writeEnabled"); switcher->fileIO.writePath = obs_data_get_string(obj, "writePath"); - obs_data_set_default_string(obj, "priority0", DEFAULT_PRIORITY_0); - obs_data_set_default_string(obj, "priority1", DEFAULT_PRIORITY_1); - obs_data_set_default_string(obj, "priority2", DEFAULT_PRIORITY_2); - obs_data_set_default_string(obj, "priority3", DEFAULT_PRIORITY_3); - obs_data_set_default_string(obj, "priority4", DEFAULT_PRIORITY_4); - obs_data_set_default_string(obj, "priority5", DEFAULT_PRIORITY_5); + 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); - switcher->functionNamesByPriority[0] = (obs_data_get_string(obj, "priority0")); - switcher->functionNamesByPriority[1] = (obs_data_get_string(obj, "priority1")); - switcher->functionNamesByPriority[2] = (obs_data_get_string(obj, "priority2")); - switcher->functionNamesByPriority[3] = (obs_data_get_string(obj, "priority3")); - switcher->functionNamesByPriority[4] = (obs_data_get_string(obj, "priority4")); - switcher->functionNamesByPriority[5] = (obs_data_get_string(obj, "priority5")); + switcher->functionNamesByPriority[0] = (obs_data_get_int(obj, "priority0")); + switcher->functionNamesByPriority[1] = (obs_data_get_int(obj, "priority1")); + switcher->functionNamesByPriority[2] = (obs_data_get_int(obj, "priority2")); + switcher->functionNamesByPriority[3] = (obs_data_get_int(obj, "priority3")); + switcher->functionNamesByPriority[4] = (obs_data_get_int(obj, "priority4")); + switcher->functionNamesByPriority[5] = (obs_data_get_int(obj, "priority5")); if (!switcher->prioFuncsValid()) { switcher->functionNamesByPriority[0] = (DEFAULT_PRIORITY_0); @@ -852,6 +936,7 @@ static void SaveSceneSwitcher(obs_data_t* save_data, bool saving, void*) obs_data_array_release(executableArray); obs_data_array_release(ignoreIdleWindowsArray); obs_data_array_release(randomArray); + obs_data_array_release(fileArray); obs_data_release(obj); @@ -921,7 +1006,7 @@ void SwitcherData::Thread() //to avoid scene duplication when rapidly switching scene collection this_thread::sleep_for(chrono::seconds(2)); - int extraSleep = 0; + int sleep = 0; while (true) { @@ -931,11 +1016,11 @@ void SwitcherData::Thread() OBSWeakSource scene; OBSWeakSource transition; chrono::milliseconds duration; - if (extraSleep > interval) - duration = chrono::milliseconds(extraSleep); + if (sleep > interval) + duration = chrono::milliseconds(sleep); else duration = chrono::milliseconds(interval); - extraSleep = 0; + sleep = 0; switcher->Prune(); writeSceneInfoToFile(); //sleep for a bit @@ -954,30 +1039,27 @@ void SwitcherData::Thread() continue; } - for (string switchFuncName : functionNamesByPriority) + for (int switchFuncName : functionNamesByPriority) { - if (switchFuncName == READ_FILE_FUNC) - { + switch (switchFuncName) { + case READ_FILE_FUNC: checkSwitchInfoFromFile(match, scene, transition); - } - if (switchFuncName == IDLE_FUNC) - { + checkFileContent(match, scene, transition); + break; + case IDLE_FUNC: checkIdleSwitch(match, scene, transition); - } - if (switchFuncName == EXE_FUNC) - { + break; + case EXE_FUNC: checkExeSwitch(match, scene, transition); - } - if (switchFuncName == SCREEN_REGION_FUNC) - { + break; + + case SCREEN_REGION_FUNC: checkScreenRegionSwitch(match, scene, transition); - } - if (switchFuncName == WINDOW_TITLE_FUNC) - { + break; + case WINDOW_TITLE_FUNC: checkWindowTitleSwitch(match, scene, transition); - } - if (switchFuncName == ROUND_TRIP_FUNC) - { + break; + case ROUND_TRIP_FUNC: checkSceneRoundTrip(match, scene, transition, lock); if (sceneChangedDuringWait()) //scene might have changed during the sleep { @@ -1002,7 +1084,7 @@ void SwitcherData::Thread() } if (!match && switchIfNotMatching == RANDOM_SWITCH) { - checkRandom(match, scene, transition, extraSleep); + checkRandom(match, scene, transition, sleep); } if (match) { diff --git a/advanced-scene-switcher.hpp b/advanced-scene-switcher.hpp index 8d09d942..3e1382f2 100644 --- a/advanced-scene-switcher.hpp +++ b/advanced-scene-switcher.hpp @@ -109,6 +109,11 @@ public slots: void on_randomRemove_clicked(); void on_randomScenesList_currentRowChanged(int idx); + void on_fileAdd_clicked(); + void on_fileRemove_clicked(); + void on_fileScenesList_currentRowChanged(int idx); + void on_browseButton_3_clicked(); + void on_priorityUp_clicked(); void on_priorityDown_clicked(); diff --git a/file-switch.cpp b/file-switch.cpp index 38f55f23..1e0a09ff 100644 --- a/file-switch.cpp +++ b/file-switch.cpp @@ -7,10 +7,10 @@ void SceneSwitcher::on_browseButton_clicked() { - QString directory = QFileDialog::getOpenFileName( + QString path = QFileDialog::getOpenFileName( this, tr("Select a file to write to ..."), QDir::currentPath(), tr("Text files (*.txt)")); - if (!directory.isEmpty()) - ui->writePathLineEdit->setText(directory); + if (!path.isEmpty()) + ui->writePathLineEdit->setText(path); } void SceneSwitcher::on_readFileCheckBox_stateChanged(int state) @@ -65,15 +65,15 @@ void SceneSwitcher::on_writePathLineEdit_textChanged(const QString& text) void SceneSwitcher::on_browseButton_2_clicked() { - QString directory = QFileDialog::getOpenFileName( + QString path = QFileDialog::getOpenFileName( this, tr("Select a file to read from ..."), QDir::currentPath(), tr("Text files (*.txt)")); - if (!directory.isEmpty()) - ui->readPathLineEdit->setText(directory); + if (!path.isEmpty()) + ui->readPathLineEdit->setText(path); } void SwitcherData::writeSceneInfoToFile() { - if (!fileIO.writeEnabled) + if (!fileIO.writeEnabled || fileIO.writePath.empty()) return; obs_source_t* currentSource = obs_frontend_get_current_scene(); @@ -114,3 +114,126 @@ void SwitcherData::checkSwitchInfoFromFile(bool& match, OBSWeakSource& scene, OB file.close(); } } + +void SwitcherData::checkFileContent(bool& match, OBSWeakSource& scene, OBSWeakSource& transition) +{ + for (FileSwitch& s : fileSwitches) + { + bool equal = false; + QString t = QString::fromStdString(s.text); + QFile file(QString::fromStdString(s.file)); + if (!file.open(QIODevice::ReadOnly)) + continue; + + /*Im using QTextStream here so the conversion between different lineendings is done by QT. + *QT itself uses only the linefeed internally so the input by the user is always using that, + *but the files selected by the user might use different line endings. + *If you are reading this and know of a cleaner way to do this, please let me know :) + */ + QTextStream in(&file); + QTextStream text(&t); + while (!in.atEnd() && !text.atEnd()) + { + QString fileLine = in.readLine(); + QString textLine = text.readLine(); + if (QString::compare(fileLine, textLine, Qt::CaseSensitive) != 0) + { + equal = false; + break; + } + else { + equal = true; + } + } + + file.close(); + + if (equal) { + scene = s.scene; + transition = s.transition; + match = true; + + break; + } + } +} + + +void SceneSwitcher::on_browseButton_3_clicked() +{ + QString path = QFileDialog::getOpenFileName( + this, tr("Select a file to read from ..."), QDir::currentPath(), tr("Text files (*.txt)")); + if (!path.isEmpty()) + ui->filePathLineEdit->setText(path); +} + +void SceneSwitcher::on_fileAdd_clicked() +{ + QString sceneName = ui->fileScenes->currentText(); + QString transitionName = ui->fileTransitions->currentText(); + QString fileName = ui->filePathLineEdit->text(); + QString text = ui->fileTextEdit->toPlainText(); + //QFile file(QString::fromStdString(fileName)); //don't check if file exists because it might not yet exist + + if (sceneName.isEmpty() || transitionName.isEmpty() || fileName.isEmpty() || text.isEmpty()) + return; + + OBSWeakSource source = GetWeakSourceByQString(sceneName); + OBSWeakSource transition = GetWeakTransitionByQString(transitionName); + + QString switchText = MakeFileSwitchName(sceneName, transitionName, fileName, text); + QVariant v = QVariant::fromValue(switchText); + + + QListWidgetItem* item = new QListWidgetItem(switchText, ui->fileScenesList); + item->setData(Qt::UserRole, v); + + lock_guard lock(switcher->m); + switcher->fileSwitches.emplace_back( + source, transition, fileName.toUtf8().constData(), text.toUtf8().constData()); + +} + +void SceneSwitcher::on_fileRemove_clicked() +{ + QListWidgetItem* item = ui->fileScenesList->currentItem(); + if (!item) + return; + + int idx = ui->fileScenesList->currentRow(); + if (idx == -1) + return; + + { + lock_guard lock(switcher->m); + + auto& switches = switcher->fileSwitches; + switches.erase(switches.begin() + idx); + } + qDeleteAll(ui->fileScenesList->selectedItems()); + //delete item; +} + + +void SceneSwitcher::on_fileScenesList_currentRowChanged(int idx) +{ + if (loading) + return; + if (idx == -1) + return; + + lock_guard lock(switcher->m); + + if (switcher->fileSwitches.size() <= idx) + return; + FileSwitch s = switcher->fileSwitches[idx]; + + string sceneName = GetWeakSourceName(s.scene); + string transitionName = GetWeakSourceName(s.transition); + + ui->fileScenes->setCurrentText(sceneName.c_str()); + ui->fileTransitions->setCurrentText(transitionName.c_str()); + ui->fileTextEdit->setPlainText(s.text.c_str()); + ui->filePathLineEdit->setText(s.file.c_str()); + +} diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui index 6cb36495..787ea13a 100644 --- a/forms/advanced-scene-switcher.ui +++ b/forms/advanced-scene-switcher.ui @@ -25,101 +25,11 @@ - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Order the different switching methods in order of their priority (with the highest priority being at the top): - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - 22 - 22 - - - - - ../../../forms/images/up.png../../../forms/images/up.png - - - true - - - upArrowIconSmall - - - - - - - - 22 - 22 - - - - - ../../../forms/images/down.png../../../forms/images/down.png - - - true - - - downArrowIconSmall - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + Qt::Horizontal + + @@ -296,12 +206,96 @@ - - - (You can set a Hotkey to start and stop the scene switcher under Settings / Hotkeys / Toggle Start Stop for the Advanced Scene Switcher) + + + Qt::Horizontal + + + + + + Order the different switching methods in order of their priority (with the highest priority being at the top): + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + 22 + 22 + + + + + ../../../forms/images/up.png../../../forms/images/up.png + + + true + + + upArrowIconSmall + + + + + + + + 22 + 22 + + + + + ../../../forms/images/down.png../../../forms/images/down.png + + + true + + + downArrowIconSmall + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -342,6 +336,20 @@ + + + + Qt::Horizontal + + + + + + + (You can set a Hotkey to start and stop the scene switcher under Settings / Hotkeys / Toggle Start Stop for the Advanced Scene Switcher) + + + @@ -474,6 +482,13 @@ + + + + Qt::Horizontal + + + @@ -589,6 +604,20 @@ + + + + Qt::Horizontal + + + + + + + (If you want to add OBS itself as a window title use "OBS" - If you want to add ALT + TAB add "Task Switching") + + + @@ -1520,6 +1549,13 @@ + + + + Qt::Horizontal + + + @@ -1791,6 +1827,13 @@ + + + + Qt::Horizontal + + + @@ -2066,7 +2109,7 @@ Write To File / Read From File - + @@ -2089,52 +2132,216 @@ - + + + Qt::Horizontal + + + + + - - - - - Enable switching of scenes based on file input - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + Enable switching of scenes based on file input + + - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Read scene name to be switched to from this file: + + + + + + + + + + Browse + + + + + + + + + Qt::Horizontal + + + + + + + Switch scene based on file contents: + + + + + + + - + - Read scene to be switched to from this file: + If the file - + - + Browse + + + + contains: + + + + + + + + + + + + + + switch to + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + + + + using + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + false + + + + + + + + + + 22 + 22 + + + + true + + + addIconSmall + + + + + + + + 22 + 22 + + + + true + + + removeIconSmall + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/priority.cpp b/priority.cpp index 82ccf495..e1eeedd3 100644 --- a/priority.cpp +++ b/priority.cpp @@ -27,29 +27,17 @@ void SceneSwitcher::on_priorityDown_clicked() } } -bool prioStrValid(string s) -{ - if (s == WINDOW_TITLE_FUNC) - return true; - if (s == SCREEN_REGION_FUNC) - return true; - if (s == ROUND_TRIP_FUNC) - return true; - if (s == (IDLE_FUNC)) - return true; - if (s == EXE_FUNC) - return true; - if (s == READ_FILE_FUNC) - return true; - return false; -} - bool SwitcherData::prioFuncsValid() { - for (string f : functionNamesByPriority) + auto it = std::unique(functionNamesByPriority.begin(), functionNamesByPriority.end()); + bool wasUnique = (it == functionNamesByPriority.end()); + if (!wasUnique) + return false; + + for (int p : functionNamesByPriority) { - if (!prioStrValid(f)) + if (p < 0 || p > 5) return false; } return true; diff --git a/random.cpp b/random.cpp index 650effe2..4b1c1a9d 100644 --- a/random.cpp +++ b/random.cpp @@ -124,11 +124,10 @@ void SceneSwitcher::on_randomRemove_clicked() void SwitcherData::checkRandom(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, int& delay) { - int size = randomSwitches.size(); if (randomSwitches.size() == 0) return; - vector rs = randomSwitches; + vector rs (randomSwitches); std::random_shuffle(rs.begin(), rs.end()); for (RandomSwitch& r : rs) { diff --git a/switcher-data-structs.hpp b/switcher-data-structs.hpp index 41b15efc..143a8761 100644 --- a/switcher-data-structs.hpp +++ b/switcher-data-structs.hpp @@ -11,12 +11,14 @@ #define DEFAULT_INTERVAL 300 -#define READ_FILE_FUNC "File based" -#define ROUND_TRIP_FUNC "Scene Sequence" -#define IDLE_FUNC "Idle detection" -#define EXE_FUNC "Executable" -#define SCREEN_REGION_FUNC "Screen region" -#define WINDOW_TITLE_FUNC "Window title" +#define DEFAULT_IDLE_TIME 60 + +#define READ_FILE_FUNC 0 +#define ROUND_TRIP_FUNC 1 +#define IDLE_FUNC 2 +#define EXE_FUNC 3 +#define SCREEN_REGION_FUNC 4 +#define WINDOW_TITLE_FUNC 5 #define DEFAULT_PRIORITY_0 READ_FILE_FUNC #define DEFAULT_PRIORITY_1 ROUND_TRIP_FUNC @@ -149,18 +151,35 @@ struct DefaultSceneTransition } }; +struct FileSwitch +{ + OBSWeakSource scene; + OBSWeakSource transition; + string file; + string text; + + inline FileSwitch( + OBSWeakSource scene_, OBSWeakSource transition_, const char* file_, const char* text_) + : scene(scene_) + , transition(transition_) + , file(file_) + , text(text_) + { + } +}; + struct FileIOData { - bool readEnabled; + bool readEnabled = false; string readPath; - bool writeEnabled; + bool writeEnabled = false; string writePath; }; struct IdleData { - bool idleEnable; - int time; + bool idleEnable = false; + int time = DEFAULT_IDLE_TIME; OBSWeakSource scene; OBSWeakSource transition; }; @@ -188,7 +207,7 @@ struct SwitcherData OBSWeakSource nonMatchingScene; OBSWeakSource lastRandomScene; int interval = DEFAULT_INTERVAL; - NoMatch switchIfNotMatching; + NoMatch switchIfNotMatching = NO_SWITCH; bool startAtLaunch = false; vector screenRegionSwitches; vector pauseScenesSwitches; @@ -196,6 +215,7 @@ struct SwitcherData vector ignoreWindowsSwitches; vector sceneRoundTripSwitches; vector randomSwitches; + vector fileSwitches; bool autoStopEnable = false; OBSWeakSource autoStopScene; string waitSceneName; //indicates which scene was active when we startet waiting on something @@ -205,13 +225,13 @@ struct SwitcherData FileIOData fileIO; IdleData idleData; vector ignoreIdleWindows; - vector functionNamesByPriority = vector{ - string(DEFAULT_PRIORITY_0), - string(DEFAULT_PRIORITY_1), - string(DEFAULT_PRIORITY_2), - string(DEFAULT_PRIORITY_3), - string(DEFAULT_PRIORITY_4), - string(DEFAULT_PRIORITY_5), + vector functionNamesByPriority = vector{ + DEFAULT_PRIORITY_0, + DEFAULT_PRIORITY_1, + DEFAULT_PRIORITY_2, + DEFAULT_PRIORITY_3, + DEFAULT_PRIORITY_4, + DEFAULT_PRIORITY_5, }; void Thread(); @@ -230,6 +250,7 @@ struct SwitcherData void checkExeSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition); void checkScreenRegionSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition); void checkSwitchInfoFromFile(bool& match, OBSWeakSource& scene, OBSWeakSource& transition); + void checkFileContent(bool& match, OBSWeakSource& scene, OBSWeakSource& transition); void checkRandom(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, int& delay); @@ -306,6 +327,13 @@ struct SwitcherData executableSwitches.erase(executableSwitches.begin() + i--); } + for (size_t i = 0; i < fileSwitches.size(); i++) + { + FileSwitch& s = fileSwitches[i]; + if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition)) + fileSwitches.erase(fileSwitches.begin() + i--); + } + if (!WeakSourceValid(idleData.scene) || !WeakSourceValid(idleData.transition)) { idleData.idleEnable = false; diff --git a/utility.hpp b/utility.hpp index 59e47f44..c8bd5124 100644 --- a/utility.hpp +++ b/utility.hpp @@ -69,6 +69,18 @@ static inline QString MakeRandomSwitchName( + QString::number(delay) + QStringLiteral(" seconds"); } +static inline QString MakeFileSwitchName( + const QString& scene, const QString& transition, const QString& fileName, const QString& text) +{ + + if (text.length() > 30) + return QStringLiteral("Switch to ") + scene + QStringLiteral(" using ") + transition + QStringLiteral(" if ") + + fileName + QStringLiteral(" contains: \n\"") + text.left(27) + QStringLiteral("...\""); + else + return QStringLiteral("Switch to ") + scene + QStringLiteral(" using ") + transition + QStringLiteral(" if ") + + fileName + QStringLiteral(" contains: \n\"") + text + QStringLiteral("\""); +} + static inline string GetWeakSourceName(obs_weak_source_t* weak_source) { string name;