mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-04-20 00:57:22 -05:00
Add option to wait for transition to complete
This commit is contained in:
parent
0881146a25
commit
a2ba7adc56
|
|
@ -259,6 +259,7 @@ AdvSceneSwitcher.condition.studioMode.entry="{{conditions}}{{scenes}}"
|
|||
; Macro Actions
|
||||
AdvSceneSwitcher.action.switchScene="Switch scene"
|
||||
AdvSceneSwitcher.action.scene.entry="Switch to scene {{scenes}} using {{transitions}} with a duration of {{duration}} seconds"
|
||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Wait until transition to target scene is complete"
|
||||
AdvSceneSwitcher.action.wait="Wait"
|
||||
AdvSceneSwitcher.action.wait.type.fixed="fixed"
|
||||
AdvSceneSwitcher.action.wait.type.random="random"
|
||||
|
|
|
|||
|
|
@ -413,6 +413,7 @@ void SwitcherData::Stop()
|
|||
cv.notify_all();
|
||||
abortMacroWait = true;
|
||||
macroWaitCv.notify_all();
|
||||
macroTransitionCv.notify_all();
|
||||
th->wait();
|
||||
delete th;
|
||||
th = nullptr;
|
||||
|
|
@ -551,6 +552,7 @@ void setTranstionEnd()
|
|||
{
|
||||
switcher->lastTransitionEndTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
switcher->macroTransitionCv.notify_all();
|
||||
}
|
||||
|
||||
void setStreamStarting()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
#include "switch-generic.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
#include <QCheckBox>
|
||||
|
||||
// TODO: Switch to using SceneSelection class and widget instead
|
||||
|
||||
class MacroActionSwitchScene : public MacroAction, public SceneSwitcherEntry {
|
||||
|
|
@ -19,6 +21,7 @@ public:
|
|||
return std::make_shared<MacroActionSwitchScene>();
|
||||
}
|
||||
Duration _duration;
|
||||
bool _blockUntilTransitionDone = true;
|
||||
|
||||
private:
|
||||
const char *getType() { return "MacroActionSwitchScene"; }
|
||||
|
|
@ -45,11 +48,13 @@ public:
|
|||
|
||||
private slots:
|
||||
void DurationChanged(double seconds);
|
||||
void BlockUntilTransitionDoneChanged(int state);
|
||||
void ChangeHeaderInfo(const QString &);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
protected:
|
||||
DurationSelection *_duration;
|
||||
QCheckBox *_blockUntilTransitionDone;
|
||||
std::shared_ptr<MacroActionSwitchScene> _entryData;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ struct SwitcherData {
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user