mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Allow running macros in parallel to other macros
This commit is contained in:
parent
9dd47b811b
commit
845506f7e4
|
|
@ -67,6 +67,8 @@ AdvSceneSwitcher.macroTab.edit.action="Action type:"
|
|||
AdvSceneSwitcher.macroTab.add="Add new macro"
|
||||
AdvSceneSwitcher.macroTab.name="Name:"
|
||||
AdvSceneSwitcher.macroTab.run="Run macro"
|
||||
AdvSceneSwitcher.macroTab.runFail="Running \"%1\" failed!\nEither one of the actions failed or the macro is running already."
|
||||
AdvSceneSwitcher.macroTab.runInParallel="Run macro in parallel to other macros"
|
||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||
AdvSceneSwitcher.macroTab.exists="Macro name exists already"
|
||||
AdvSceneSwitcher.macroTab.copy="Create copy"
|
||||
|
|
|
|||
|
|
@ -722,7 +722,7 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_34">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="0,0,0,0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="0,0,0,0,0">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="text">
|
||||
|
|
@ -740,6 +740,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="runMacroInParallel">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.macroTab.runInParallel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_13">
|
||||
<property name="orientation">
|
||||
|
|
|
|||
|
|
@ -98,6 +98,11 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||
obs_data_set_obj(save_data, "advanced-scene-switcher", obj);
|
||||
obs_data_release(obj);
|
||||
} else {
|
||||
// Stop the scene switcher at least once to
|
||||
// avoid scene duplication issues with scene collection changes
|
||||
bool start = !switcher->stop;
|
||||
switcher->Stop();
|
||||
|
||||
switcher->m.lock();
|
||||
obs_data_t *obj =
|
||||
obs_data_get_obj(save_data, "advanced-scene-switcher");
|
||||
|
|
@ -111,10 +116,6 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||
obs_data_release(obj);
|
||||
switcher->m.unlock();
|
||||
|
||||
// Stop the scene switcher at least once to
|
||||
// avoid scene duplication issues with scene collection changes
|
||||
bool start = !switcher->stop;
|
||||
switcher->Stop();
|
||||
if (start) {
|
||||
switcher->Start();
|
||||
}
|
||||
|
|
@ -410,9 +411,9 @@ void SwitcherData::Stop()
|
|||
{
|
||||
if (th && th->isRunning()) {
|
||||
stop = true;
|
||||
cv.notify_one();
|
||||
cv.notify_all();
|
||||
abortMacroWait = true;
|
||||
macroWaitCv.notify_one();
|
||||
macroWaitCv.notify_all();
|
||||
th->wait();
|
||||
delete th;
|
||||
th = nullptr;
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ public slots:
|
|||
void on_macroDown_clicked();
|
||||
void on_macroName_editingFinished();
|
||||
void on_runMacro_clicked();
|
||||
void on_runMacroInParallel_stateChanged(int value);
|
||||
void on_macros_currentRowChanged(int idx);
|
||||
void on_macros_itemChanged(QListWidgetItem *);
|
||||
void on_conditionAdd_clicked();
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
#include "macro-segment.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
#include <QString>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <obs.hpp>
|
||||
#include <obs-module.h>
|
||||
#include <QString>
|
||||
|
||||
constexpr auto macro_func = 10;
|
||||
constexpr auto default_priority_10 = macro_func;
|
||||
|
|
@ -73,10 +74,12 @@ public:
|
|||
virtual ~Macro();
|
||||
|
||||
bool CeckMatch();
|
||||
bool PerformAction();
|
||||
bool PerformAction(bool forceParallel = false);
|
||||
bool Matched() { return _matched; }
|
||||
std::string Name() { return _name; }
|
||||
void SetName(const std::string &name);
|
||||
void SetRunInParallel(bool parallel) { _runInParallel = parallel; }
|
||||
bool RunInParallel() { return _runInParallel; }
|
||||
void SetPaused(bool pause = true);
|
||||
bool Paused() { return _paused; }
|
||||
int GetCount() { return _count; };
|
||||
|
|
@ -103,16 +106,23 @@ private:
|
|||
void ClearHotkeys();
|
||||
void SetHotkeysDesc();
|
||||
void ResetTimers();
|
||||
void RunActions(bool &ret);
|
||||
void RunActions();
|
||||
|
||||
std::string _name = "";
|
||||
std::deque<std::shared_ptr<MacroCondition>> _conditions;
|
||||
std::deque<std::shared_ptr<MacroAction>> _actions;
|
||||
bool _runInParallel = false;
|
||||
bool _matched = false;
|
||||
bool _paused = false;
|
||||
int _count = 0;
|
||||
obs_hotkey_id _pauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id _unpauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id _togglePauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
|
||||
bool _stop = false;
|
||||
bool _done = true;
|
||||
std::thread _thread;
|
||||
};
|
||||
|
||||
Macro *GetMacroByName(const char *name);
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
|||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
macro->Actions().erase(macro->Actions().begin() + idx);
|
||||
switcher->abortMacroWait = true;
|
||||
switcher->macroWaitCv.notify_one();
|
||||
switcher->macroWaitCv.notify_all();
|
||||
macro->UpdateActionIndices();
|
||||
|
||||
clearLayout(ui->macroEditActionLayout, idx);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ void AdvSceneSwitcher::on_macroRemove_clicked()
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->abortMacroWait = true;
|
||||
switcher->macroWaitCv.notify_one();
|
||||
switcher->macroWaitCv.notify_all();
|
||||
int idx = ui->macros->currentRow();
|
||||
QString::fromStdString(switcher->macros[idx]->Name());
|
||||
switcher->macros.erase(switcher->macros.begin() + idx);
|
||||
|
|
@ -180,7 +180,22 @@ void AdvSceneSwitcher::on_runMacro_clicked()
|
|||
return;
|
||||
}
|
||||
|
||||
macro->PerformAction();
|
||||
bool ret = macro->PerformAction(true);
|
||||
if (!ret) {
|
||||
QString err =
|
||||
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
|
||||
DisplayMessage(err.arg(QString::fromStdString(macro->Name())));
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_runMacroInParallel_stateChanged(int value)
|
||||
{
|
||||
Macro *macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
macro->SetRunInParallel(value);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::PopulateMacroActions(Macro &m, uint32_t afterIdx)
|
||||
|
|
@ -215,6 +230,7 @@ void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx)
|
|||
void AdvSceneSwitcher::SetEditMacro(Macro &m)
|
||||
{
|
||||
ui->macroName->setText(m.Name().c_str());
|
||||
ui->runMacroInParallel->setChecked(m.RunInParallel());
|
||||
clearLayout(ui->macroEditConditionLayout);
|
||||
clearLayout(ui->macroEditActionLayout);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ Macro::Macro(const std::string &name)
|
|||
|
||||
Macro::~Macro()
|
||||
{
|
||||
_stop = true;
|
||||
if (_thread.joinable()) {
|
||||
_thread.join();
|
||||
}
|
||||
ClearHotkeys();
|
||||
}
|
||||
|
||||
|
|
@ -104,15 +108,22 @@ bool Macro::CeckMatch()
|
|||
return _matched;
|
||||
}
|
||||
|
||||
bool Macro::PerformAction()
|
||||
bool Macro::PerformAction(bool forceParallel)
|
||||
{
|
||||
if (!_done) {
|
||||
vblog(LOG_INFO, "macro %s already running", _name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = true;
|
||||
for (auto &a : _actions) {
|
||||
a->LogAction();
|
||||
ret = ret && a->PerformAction();
|
||||
if (!ret) {
|
||||
return false;
|
||||
_done = false;
|
||||
if (_runInParallel || forceParallel) {
|
||||
if (_thread.joinable()) {
|
||||
_thread.join();
|
||||
}
|
||||
_thread = std::thread([this] { RunActions(); });
|
||||
} else {
|
||||
RunActions(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -130,6 +141,27 @@ void Macro::ResetTimers()
|
|||
}
|
||||
}
|
||||
|
||||
void Macro::RunActions(bool &retVal)
|
||||
{
|
||||
bool ret = true;
|
||||
for (auto &a : _actions) {
|
||||
a->LogAction();
|
||||
ret = ret && a->PerformAction();
|
||||
if (!ret || _stop) {
|
||||
retVal = ret;
|
||||
_done = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
_done = true;
|
||||
}
|
||||
|
||||
void Macro::RunActions()
|
||||
{
|
||||
bool unused;
|
||||
RunActions(unused);
|
||||
}
|
||||
|
||||
void Macro::SetPaused(bool pause)
|
||||
{
|
||||
if (_paused && !pause) {
|
||||
|
|
@ -160,6 +192,7 @@ bool Macro::Save(obs_data_t *obj)
|
|||
{
|
||||
obs_data_set_string(obj, "name", _name.c_str());
|
||||
obs_data_set_bool(obj, "pause", _paused);
|
||||
obs_data_set_bool(obj, "parallel", _runInParallel);
|
||||
|
||||
obs_data_array_t *pauseHotkey = obs_hotkey_save(_pauseHotkey);
|
||||
obs_data_set_array(obj, "pauseHotkey", pauseHotkey);
|
||||
|
|
@ -237,6 +270,7 @@ bool Macro::Load(obs_data_t *obj)
|
|||
{
|
||||
_name = obs_data_get_string(obj, "name");
|
||||
_paused = obs_data_get_bool(obj, "pause");
|
||||
_runInParallel = obs_data_get_bool(obj, "parallel");
|
||||
|
||||
obs_data_array_t *pauseHotkey = obs_data_get_array(obj, "pauseHotkey");
|
||||
obs_hotkey_load(_pauseHotkey, pauseHotkey);
|
||||
|
|
@ -541,7 +575,6 @@ bool SwitcherData::runMacros()
|
|||
if (!m->PerformAction()) {
|
||||
blog(LOG_WARNING, "abort macro: %s",
|
||||
m->Name().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user