Add option to wait for transition to complete

This commit is contained in:
WarmUpTill
2021-12-22 22:12:01 +01:00
committed by WarmUpTill
parent 0881146a25
commit a2ba7adc56
5 changed files with 67 additions and 2 deletions

View File

@@ -9,10 +9,40 @@ bool MacroActionSwitchScene::_registered = MacroActionFactory::Register(
{MacroActionSwitchScene::Create, MacroActionSwitchSceneEdit::Create,
"AdvSceneSwitcher.action.switchScene"});
void waitForTransitionChange(OBSWeakSource &target)
{
const int maxNrChecks = 100;
int curCheckNr = 0;
bool transitionEnded = false;
auto sceneCheckStartedOn = obs_frontend_get_current_scene();
obs_source_release(sceneCheckStartedOn);
switcher->abortMacroWait = false;
std::unique_lock<std::mutex> lock(switcher->m);
while (!transitionEnded && curCheckNr < maxNrChecks &&
!switcher->abortMacroWait) {
switcher->abortMacroWait = false;
switcher->macroTransitionCv.wait_for(
lock,
std::chrono::milliseconds(
(long long)switcher->interval),
[] { return switcher->abortMacroWait.load(); });
auto curScene = obs_frontend_get_current_scene();
obs_source_release(curScene);
transitionEnded = curScene != sceneCheckStartedOn ||
switcher->currentScene == target;
++curCheckNr;
}
}
bool MacroActionSwitchScene::PerformAction()
{
OBSWeakSource scene = getScene();
switchScene({scene, transition, (int)(_duration.seconds * 1000)});
if (_blockUntilTransitionDone) {
waitForTransitionChange(scene);
return !switcher->abortMacroWait;
}
return true;
}
@@ -28,6 +58,8 @@ bool MacroActionSwitchScene::Save(obs_data_t *obj)
MacroAction::Save(obj);
SceneSwitcherEntry::save(obj);
_duration.Save(obj);
obs_data_set_bool(obj, "blockUntilTransitionDone",
_blockUntilTransitionDone);
return true;
}
@@ -36,6 +68,8 @@ bool MacroActionSwitchScene::Load(obs_data_t *obj)
MacroAction::Load(obj);
SceneSwitcherEntry::load(obj);
_duration.Load(obj);
_blockUntilTransitionDone =
obs_data_get_bool(obj, "blockUntilTransitionDone");
return true;
}
@@ -55,23 +89,35 @@ MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
: SwitchWidget(parent, entryData.get(), true, true)
{
_duration = new DurationSelection(parent, false);
_blockUntilTransitionDone = new QCheckBox(obs_module_text(
"AdvSceneSwitcher.action.scene.blockUntilTransitionDone"));
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
SLOT(DurationChanged(double)));
QWidget::connect(_blockUntilTransitionDone, SIGNAL(stateChanged(int)),
this, SLOT(BlockUntilTransitionDoneChanged(int)));
QWidget::connect(scenes, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(ChangeHeaderInfo(const QString &)));
QHBoxLayout *mainLayout = new QHBoxLayout;
QHBoxLayout *entryLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{scenes}}", scenes},
{"{{transitions}}", transitions},
{"{{duration}}", _duration},
{"{{blockUntilTransitionDone}}", _blockUntilTransitionDone},
};
placeWidgets(obs_module_text("AdvSceneSwitcher.action.scene.entry"),
mainLayout, widgetPlaceholders);
entryLayout, widgetPlaceholders);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(entryLayout);
mainLayout->addWidget(_blockUntilTransitionDone);
setLayout(mainLayout);
_entryData = entryData;
_duration->SetDuration(_entryData->_duration);
_blockUntilTransitionDone->setChecked(
_entryData->_blockUntilTransitionDone);
SwitchWidget::loading = false;
}
@@ -85,6 +131,16 @@ void MacroActionSwitchSceneEdit::DurationChanged(double seconds)
_entryData->_duration.seconds = seconds;
}
void MacroActionSwitchSceneEdit::BlockUntilTransitionDoneChanged(int state)
{
if (SwitchWidget::loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_blockUntilTransitionDone = state;
}
void MacroActionSwitchSceneEdit::ChangeHeaderInfo(const QString &)
{
emit HeaderInfoChanged(