diff --git a/src/advanced-scene-switcher.cpp b/src/advanced-scene-switcher.cpp index be79946a..2d752ce0 100644 --- a/src/advanced-scene-switcher.cpp +++ b/src/advanced-scene-switcher.cpp @@ -428,9 +428,6 @@ void SwitcherData::Thread() OBSWeakSource scene; OBSWeakSource transition; - bool defTransitionMatch = false; - OBSWeakSource defTransition; - endTime = std::chrono::high_resolution_clock::now(); auto runTime = @@ -466,8 +463,6 @@ void SwitcherData::Thread() continue; } - checkDefaultSceneTransitions(defTransitionMatch, defTransition); - for (int switchFuncName : functionNamesByPriority) { switch (switchFuncName) { case read_file_func: @@ -544,10 +539,6 @@ void SwitcherData::Thread() // leading to a deadlock, so we have to unlock() lock.unlock(); - if (!match && defTransitionMatch) { - setCurrentDefTransition(defTransition); - } - if (match) { switchScene(scene, transition, tansitionOverrideOverride); @@ -658,12 +649,8 @@ void handleSceneChange(SwitcherData *s) s->previousSceneHelper = ws; } - switcher->checkTriggers(); -} - -void handleTransitionStop(SwitcherData *s) -{ - s->checkedDefTransition = false; + s->checkTriggers(); + s->checkDefaultSceneTransitions(); } void setLiveTime(SwitcherData *s) @@ -702,9 +689,6 @@ static void OBSEvent(enum obs_frontend_event event, void *switcher) case OBS_FRONTEND_EVENT_SCENE_CHANGED: handleSceneChange((SwitcherData *)switcher); break; - case OBS_FRONTEND_EVENT_TRANSITION_STOPPED: - handleTransitionStop((SwitcherData *)switcher); - break; case OBS_FRONTEND_EVENT_RECORDING_STARTED: setLiveTime((SwitcherData *)switcher); checkAutoStartRecording((SwitcherData *)switcher); diff --git a/src/headers/switch-transitions.hpp b/src/headers/switch-transitions.hpp index 6d1454bb..0fe957f5 100644 --- a/src/headers/switch-transitions.hpp +++ b/src/headers/switch-transitions.hpp @@ -20,6 +20,8 @@ struct DefaultSceneTransition : SceneSwitcherEntry { static bool pause; const char *getType() { return "def_transition"; } + bool checkMatch(OBSWeakSource currentScene); + void setTransition(); inline DefaultSceneTransition(){}; inline DefaultSceneTransition(OBSWeakSource scene_, diff --git a/src/headers/switcher-data-structs.hpp b/src/headers/switcher-data-structs.hpp index a07e0849..94c89cb7 100644 --- a/src/headers/switcher-data-structs.hpp +++ b/src/headers/switcher-data-structs.hpp @@ -100,7 +100,6 @@ struct SwitcherData { std::deque sceneTransitions; std::deque defaultSceneTransitions; - bool checkedDefTransition = false; std::deque mediaSwitches; @@ -164,9 +163,7 @@ struct SwitcherData { void writeSceneInfoToFile(); void writeToStatusFile(QString status); bool checkPause(); - void checkDefaultSceneTransitions(bool &match, - OBSWeakSource &transition); - void setCurrentDefTransition(OBSWeakSource &transition); + void checkDefaultSceneTransitions(); void checkSceneSequence(bool &match, OBSWeakSource &scene, OBSWeakSource &transition, int &linger); void checkIdleSwitch(bool &match, OBSWeakSource &scene, diff --git a/src/switch-transitions.cpp b/src/switch-transitions.cpp index cb4b2fb7..fb4364de 100644 --- a/src/switch-transitions.cpp +++ b/src/switch-transitions.cpp @@ -1,3 +1,5 @@ +#include + #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" @@ -148,42 +150,28 @@ void AdvSceneSwitcher::on_defaultTransitionsDown_clicked() switcher->defaultSceneTransitions[index + 1]); } -void SwitcherData::checkDefaultSceneTransitions(bool &match, - OBSWeakSource &transition) +void SwitcherData::checkDefaultSceneTransitions() { - if (checkedDefTransition || DefaultSceneTransition::pause) { + if (DefaultSceneTransition::pause || stop) { return; } - obs_source_t *currentSource = obs_frontend_get_current_scene(); - obs_weak_source_t *ws = obs_source_get_weak_source(currentSource); - - for (DefaultSceneTransition &s : defaultSceneTransitions) { - if (s.scene == ws) { - if (!s.initialized()) { - continue; - } - - match = true; - transition = s.transition; + obs_source_t *currentSceneSource = obs_frontend_get_current_scene(); + obs_weak_source_t *currentScene = + obs_source_get_weak_source(currentSceneSource); + for (auto &t : defaultSceneTransitions) { + if (t.checkMatch(currentScene)) { if (verbose) { - s.logMatch(); + t.logMatch(); } + t.setTransition(); break; } } - obs_source_release(currentSource); - obs_weak_source_release(ws); - checkedDefTransition = true; -} - -void SwitcherData::setCurrentDefTransition(OBSWeakSource &transition) -{ - obs_source_t *transitionSource = obs_weak_source_get_source(transition); - obs_frontend_set_current_transition(transitionSource); - obs_source_release(transitionSource); + obs_weak_source_release(currentScene); + obs_source_release(currentSceneSource); } void AdvSceneSwitcher::on_transitionOverridecheckBox_stateChanged(int state) @@ -533,3 +521,37 @@ void DefTransitionSwitchWidget::swapSwitchData(DefTransitionSwitchWidget *s1, s1->setSwitchData(s2->getSwitchData()); s2->setSwitchData(t); } + +bool DefaultSceneTransition::checkMatch(OBSWeakSource currentScene) +{ + return scene == currentScene; +} + +void setTransitionDelayed(OBSWeakSource transition) +{ + // A hardcoded delay of 50 ms before switching transition type is + // necessary due to OBS_FRONTEND_EVENT_SCENE_CHANGED seemingly firing a + // bit too early and thus leading to canceled transitions. + // + // The same is to be the case for OBS_FRONTEND_EVENT_TRANSITION_STOPPED. + // + // 50 ms was chosen as it seems to avoid the problem mentioned above and + // becuase that is the minimum value which can be chosen for the scene + // switcher's check interval. + // Thus it can be made sure that the delayed setting of the transition + // does not interfere with any new scene changes triggered by the scene + // switcher + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + + obs_source_t *transitionSource = obs_weak_source_get_source(transition); + obs_frontend_set_current_transition(transitionSource); + obs_source_release(transitionSource); +} + +void DefaultSceneTransition::setTransition() +{ + std::thread t; + t = std::thread(setTransitionDelayed, transition); + t.detach(); +}