mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-07 17:16:00 -05:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da28fea2e0 | ||
|
|
b6b0531dbc | ||
|
|
2de0a94756 | ||
|
|
d018740442 | ||
|
|
d89f8a7972 | ||
|
|
f7a2aa09cb |
@@ -268,7 +268,8 @@ static inline void populateConditionSelection(QComboBox *list)
|
|||||||
|
|
||||||
MacroConditionVideoEdit::MacroConditionVideoEdit(
|
MacroConditionVideoEdit::MacroConditionVideoEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroConditionVideo> entryData)
|
QWidget *parent, std::shared_ptr<MacroConditionVideo> entryData)
|
||||||
: QWidget(parent), _matchDialog(this, entryData.get())
|
: QWidget(parent),
|
||||||
|
_matchDialog(this, entryData.get(), &GetSwitcher()->m)
|
||||||
{
|
{
|
||||||
_videoSelection = new QComboBox();
|
_videoSelection = new QComboBox();
|
||||||
_condition = new QComboBox();
|
_condition = new QComboBox();
|
||||||
|
|||||||
@@ -3,12 +3,16 @@
|
|||||||
#include "opencv-helpers.hpp"
|
#include "opencv-helpers.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
ShowMatchDialog::ShowMatchDialog(QWidget *parent,
|
ShowMatchDialog::ShowMatchDialog(QWidget *parent,
|
||||||
MacroConditionVideo *conditionData)
|
MacroConditionVideo *conditionData,
|
||||||
|
std::mutex *mutex)
|
||||||
: QDialog(parent),
|
: QDialog(parent),
|
||||||
_conditionData(conditionData),
|
_conditionData(conditionData),
|
||||||
_imageLabel(new QLabel),
|
_imageLabel(new QLabel),
|
||||||
_scrollArea(new QScrollArea)
|
_scrollArea(new QScrollArea),
|
||||||
|
_mtx(mutex)
|
||||||
{
|
{
|
||||||
setWindowTitle("Advanced Scene Switcher");
|
setWindowTitle("Advanced Scene Switcher");
|
||||||
_statusLabel = new QLabel(obs_module_text(
|
_statusLabel = new QLabel(obs_module_text(
|
||||||
@@ -20,6 +24,16 @@ ShowMatchDialog::ShowMatchDialog(QWidget *parent,
|
|||||||
layout->addWidget(_statusLabel);
|
layout->addWidget(_statusLabel);
|
||||||
layout->addWidget(_scrollArea);
|
layout->addWidget(_scrollArea);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
|
// This is a workaround to handle random segfaults triggered when using:
|
||||||
|
// QMetaObject::invokeMethod(this, "RedrawImage", -Qt::QueuedConnection,
|
||||||
|
// Q_ARG(QImage, image));
|
||||||
|
// from within CheckForMatchLoop().
|
||||||
|
// Even using BlockingQueuedConnection causes deadlocks
|
||||||
|
_timer.setInterval(500);
|
||||||
|
QWidget::connect(&_timer, &QTimer::timeout, this,
|
||||||
|
&ShowMatchDialog::Resize);
|
||||||
|
_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowMatchDialog::~ShowMatchDialog()
|
ShowMatchDialog::~ShowMatchDialog()
|
||||||
@@ -43,38 +57,39 @@ void ShowMatchDialog::ShowMatch()
|
|||||||
_thread = std::thread(&ShowMatchDialog::CheckForMatchLoop, this);
|
_thread = std::thread(&ShowMatchDialog::CheckForMatchLoop, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowMatchDialog::RedrawImage(QImage img)
|
void ShowMatchDialog::Resize()
|
||||||
{
|
{
|
||||||
_imageLabel->setPixmap(QPixmap::fromImage(img));
|
|
||||||
_imageLabel->adjustSize();
|
_imageLabel->adjustSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowMatchDialog::CheckForMatchLoop()
|
void ShowMatchDialog::CheckForMatchLoop()
|
||||||
{
|
{
|
||||||
|
std::condition_variable cv;
|
||||||
while (!_stop) {
|
while (!_stop) {
|
||||||
|
std::unique_lock<std::mutex> lock(*_mtx);
|
||||||
auto source = obs_weak_source_get_source(
|
auto source = obs_weak_source_get_source(
|
||||||
_conditionData->_videoSource);
|
_conditionData->_videoSource);
|
||||||
ScreenshotHelper screenshot(source);
|
ScreenshotHelper screenshot(source);
|
||||||
obs_source_release(source);
|
obs_source_release(source);
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
cv.wait_for(lock, std::chrono::seconds(1));
|
||||||
|
if (_stop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!screenshot.done) {
|
if (!screenshot.done) {
|
||||||
_statusLabel->setText(obs_module_text(
|
_statusLabel->setText(obs_module_text(
|
||||||
"AdvSceneSwitcher.condition.video.screenshotFail"));
|
"AdvSceneSwitcher.condition.video.screenshotFail"));
|
||||||
|
_imageLabel->setPixmap(QPixmap());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (screenshot.image.width() == 0 ||
|
if (screenshot.image.width() == 0 ||
|
||||||
screenshot.image.height() == 0) {
|
screenshot.image.height() == 0) {
|
||||||
_statusLabel->setText(obs_module_text(
|
_statusLabel->setText(obs_module_text(
|
||||||
"AdvSceneSwitcher.condition.video.screenshotEmpty"));
|
"AdvSceneSwitcher.condition.video.screenshotEmpty"));
|
||||||
|
_imageLabel->setPixmap(QPixmap());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto image = MarkMatch(screenshot.image);
|
auto image = MarkMatch(screenshot.image);
|
||||||
if (_stop) {
|
_imageLabel->setPixmap(QPixmap::fromImage(screenshot.image));
|
||||||
return;
|
|
||||||
}
|
|
||||||
QMetaObject::invokeMethod(this, "RedrawImage",
|
|
||||||
Qt::BlockingQueuedConnection,
|
|
||||||
Q_ARG(QImage, image));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
#include <QTimer>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class MacroConditionVideo;
|
class MacroConditionVideo;
|
||||||
|
|
||||||
@@ -11,12 +13,13 @@ class ShowMatchDialog : public QDialog {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShowMatchDialog(QWidget *parent, MacroConditionVideo *_conditionData);
|
ShowMatchDialog(QWidget *parent, MacroConditionVideo *_conditionData,
|
||||||
|
std::mutex *mutex);
|
||||||
virtual ~ShowMatchDialog();
|
virtual ~ShowMatchDialog();
|
||||||
void ShowMatch();
|
void ShowMatch();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void RedrawImage(QImage img);
|
void Resize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CheckForMatchLoop();
|
void CheckForMatchLoop();
|
||||||
@@ -26,6 +29,8 @@ private:
|
|||||||
QScrollArea *_scrollArea;
|
QScrollArea *_scrollArea;
|
||||||
QLabel *_statusLabel;
|
QLabel *_statusLabel;
|
||||||
QLabel *_imageLabel;
|
QLabel *_imageLabel;
|
||||||
|
QTimer _timer;
|
||||||
|
std::mutex *_mtx;
|
||||||
std::thread _thread;
|
std::thread _thread;
|
||||||
std::atomic_bool _stop = {false};
|
std::atomic_bool _stop = {false};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -156,16 +156,18 @@ void AdvSceneSwitcher::AddMacroAction(int idx)
|
|||||||
MacroActionSwitchScene temp(nullptr);
|
MacroActionSwitchScene temp(nullptr);
|
||||||
id = temp.GetId();
|
id = temp.GetId();
|
||||||
}
|
}
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
{
|
||||||
macro->Actions().emplace(macro->Actions().begin() + idx,
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
MacroActionFactory::Create(id, macro));
|
macro->Actions().emplace(macro->Actions().begin() + idx,
|
||||||
if (idx - 1 >= 0) {
|
MacroActionFactory::Create(id, macro));
|
||||||
auto data = obs_data_create();
|
if (idx - 1 >= 0) {
|
||||||
macro->Actions().at(idx - 1)->Save(data);
|
auto data = obs_data_create();
|
||||||
macro->Actions().at(idx)->Load(data);
|
macro->Actions().at(idx - 1)->Save(data);
|
||||||
obs_data_release(data);
|
macro->Actions().at(idx)->Load(data);
|
||||||
|
obs_data_release(data);
|
||||||
|
}
|
||||||
|
macro->UpdateActionIndices();
|
||||||
}
|
}
|
||||||
macro->UpdateActionIndices();
|
|
||||||
|
|
||||||
clearLayout(actionsList->ContentLayout(), idx);
|
clearLayout(actionsList->ContentLayout(), idx);
|
||||||
PopulateMacroActions(*macro, idx);
|
PopulateMacroActions(*macro, idx);
|
||||||
@@ -206,11 +208,13 @@ void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
{
|
||||||
macro->Actions().erase(macro->Actions().begin() + idx);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->abortMacroWait = true;
|
macro->Actions().erase(macro->Actions().begin() + idx);
|
||||||
switcher->macroWaitCv.notify_all();
|
switcher->abortMacroWait = true;
|
||||||
macro->UpdateActionIndices();
|
switcher->macroWaitCv.notify_all();
|
||||||
|
macro->UpdateActionIndices();
|
||||||
|
}
|
||||||
|
|
||||||
clearLayout(actionsList->ContentLayout(), idx);
|
clearLayout(actionsList->ContentLayout(), idx);
|
||||||
PopulateMacroActions(*macro, idx);
|
PopulateMacroActions(*macro, idx);
|
||||||
|
|||||||
@@ -128,6 +128,9 @@ void MacroActionFileEdit::UpdateEntryData()
|
|||||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||||
_filePath->SetPath(QString::fromStdString(_entryData->_file));
|
_filePath->SetPath(QString::fromStdString(_entryData->_file));
|
||||||
_text->setPlainText(QString::fromStdString(_entryData->_text));
|
_text->setPlainText(QString::fromStdString(_entryData->_text));
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionFileEdit::PathChanged(const QString &text)
|
void MacroActionFileEdit::PathChanged(const QString &text)
|
||||||
|
|||||||
@@ -153,6 +153,9 @@ void MacroActionFilterEdit::UpdateEntryData()
|
|||||||
GetWeakSourceName(_entryData->_filter).c_str());
|
GetWeakSourceName(_entryData->_filter).c_str());
|
||||||
_settings->setPlainText(QString::fromStdString(_entryData->_settings));
|
_settings->setPlainText(QString::fromStdString(_entryData->_settings));
|
||||||
SetWidgetVisibility(_entryData->_action == FilterAction::SETTINGS);
|
SetWidgetVisibility(_entryData->_action == FilterAction::SETTINGS);
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionFilterEdit::SourceChanged(const QString &text)
|
void MacroActionFilterEdit::SourceChanged(const QString &text)
|
||||||
|
|||||||
@@ -161,6 +161,9 @@ void MacroActionSceneTransformEdit::UpdateEntryData()
|
|||||||
_scenes->SetScene(_entryData->_scene);
|
_scenes->SetScene(_entryData->_scene);
|
||||||
_sources->SetSceneItem(_entryData->_source);
|
_sources->SetSceneItem(_entryData->_source);
|
||||||
_settings->setPlainText(formatJsonString(_entryData->GetSettings()));
|
_settings->setPlainText(formatJsonString(_entryData->GetSettings()));
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSceneTransformEdit::SceneChanged(const SceneSelection &s)
|
void MacroActionSceneTransformEdit::SceneChanged(const SceneSelection &s)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ bool MacroActionSequence::_registered = MacroActionFactory::Register(
|
|||||||
int getNextUnpausedMacroIdx(std::vector<MacroRef> ¯os, int startIdx)
|
int getNextUnpausedMacroIdx(std::vector<MacroRef> ¯os, int startIdx)
|
||||||
{
|
{
|
||||||
for (; (int)macros.size() > startIdx; ++startIdx) {
|
for (; (int)macros.size() > startIdx; ++startIdx) {
|
||||||
if (!macros[startIdx]->Paused()) {
|
if (macros[startIdx].get() && !macros[startIdx]->Paused()) {
|
||||||
return startIdx;
|
return startIdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,6 +141,9 @@ void MacroActionSourceEdit::UpdateEntryData()
|
|||||||
GetWeakSourceName(_entryData->_source).c_str());
|
GetWeakSourceName(_entryData->_source).c_str());
|
||||||
_settings->setPlainText(QString::fromStdString(_entryData->_settings));
|
_settings->setPlainText(QString::fromStdString(_entryData->_settings));
|
||||||
SetWidgetVisibility(_entryData->_action == SourceAction::SETTINGS);
|
SetWidgetVisibility(_entryData->_action == SourceAction::SETTINGS);
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSourceEdit::SourceChanged(const QString &text)
|
void MacroActionSourceEdit::SourceChanged(const QString &text)
|
||||||
|
|||||||
@@ -282,18 +282,20 @@ void AdvSceneSwitcher::AddMacroCondition(int idx)
|
|||||||
id = temp.GetId();
|
id = temp.GetId();
|
||||||
logic = LogicType::ROOT_NONE;
|
logic = LogicType::ROOT_NONE;
|
||||||
}
|
}
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
{
|
||||||
auto cond = macro->Conditions().emplace(
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
macro->Conditions().begin() + idx,
|
auto cond = macro->Conditions().emplace(
|
||||||
MacroConditionFactory::Create(id, macro));
|
macro->Conditions().begin() + idx,
|
||||||
if (idx - 1 >= 0) {
|
MacroConditionFactory::Create(id, macro));
|
||||||
auto data = obs_data_create();
|
if (idx - 1 >= 0) {
|
||||||
macro->Conditions().at(idx - 1)->Save(data);
|
auto data = obs_data_create();
|
||||||
macro->Conditions().at(idx)->Load(data);
|
macro->Conditions().at(idx - 1)->Save(data);
|
||||||
obs_data_release(data);
|
macro->Conditions().at(idx)->Load(data);
|
||||||
|
obs_data_release(data);
|
||||||
|
}
|
||||||
|
(*cond)->SetLogicType(logic);
|
||||||
|
macro->UpdateConditionIndices();
|
||||||
}
|
}
|
||||||
(*cond)->SetLogicType(logic);
|
|
||||||
macro->UpdateConditionIndices();
|
|
||||||
|
|
||||||
clearLayout(conditionsList->ContentLayout(), idx);
|
clearLayout(conditionsList->ContentLayout(), idx);
|
||||||
PopulateMacroConditions(*macro, idx);
|
PopulateMacroConditions(*macro, idx);
|
||||||
@@ -334,13 +336,15 @@ void AdvSceneSwitcher::RemoveMacroCondition(int idx)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
{
|
||||||
macro->Conditions().erase(macro->Conditions().begin() + idx);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
macro->UpdateConditionIndices();
|
macro->Conditions().erase(macro->Conditions().begin() + idx);
|
||||||
|
macro->UpdateConditionIndices();
|
||||||
|
|
||||||
if (idx == 0 && macro->Conditions().size() > 0) {
|
if (idx == 0 && macro->Conditions().size() > 0) {
|
||||||
auto newRoot = macro->Conditions().at(0);
|
auto newRoot = macro->Conditions().at(0);
|
||||||
newRoot->SetLogicType(LogicType::ROOT_NONE);
|
newRoot->SetLogicType(LogicType::ROOT_NONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clearLayout(conditionsList->ContentLayout(), idx);
|
clearLayout(conditionsList->ContentLayout(), idx);
|
||||||
|
|||||||
@@ -208,6 +208,9 @@ void MacroConditionFileEdit::UpdateEntryData()
|
|||||||
_useRegex->setChecked(_entryData->_useRegex);
|
_useRegex->setChecked(_entryData->_useRegex);
|
||||||
_checkModificationDate->setChecked(_entryData->_useTime);
|
_checkModificationDate->setChecked(_entryData->_useTime);
|
||||||
_checkFileContent->setChecked(_entryData->_onlyMatchIfChanged);
|
_checkFileContent->setChecked(_entryData->_onlyMatchIfChanged);
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionFileEdit::FileTypeChanged(int index)
|
void MacroConditionFileEdit::FileTypeChanged(int index)
|
||||||
|
|||||||
@@ -247,4 +247,7 @@ void MacroConditionFilterEdit::UpdateEntryData()
|
|||||||
_regex->setChecked(_entryData->_regex);
|
_regex->setChecked(_entryData->_regex);
|
||||||
SetSettingsSelectionVisible(_entryData->_condition ==
|
SetSettingsSelectionVisible(_entryData->_condition ==
|
||||||
FilterCondition::SETTINGS);
|
FilterCondition::SETTINGS);
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,9 @@ void MacroConditionSceneTransformEdit::UpdateEntryData()
|
|||||||
_sources->SetSceneItem(_entryData->_source);
|
_sources->SetSceneItem(_entryData->_source);
|
||||||
_regex->setChecked(_entryData->_regex);
|
_regex->setChecked(_entryData->_regex);
|
||||||
_settings->setPlainText(QString::fromStdString(_entryData->_settings));
|
_settings->setPlainText(QString::fromStdString(_entryData->_settings));
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s)
|
void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s)
|
||||||
|
|||||||
@@ -221,4 +221,7 @@ void MacroConditionSourceEdit::UpdateEntryData()
|
|||||||
_regex->setChecked(_entryData->_regex);
|
_regex->setChecked(_entryData->_regex);
|
||||||
SetSettingsSelectionVisible(_entryData->_condition ==
|
SetSettingsSelectionVisible(_entryData->_condition ==
|
||||||
SourceCondition::SETTINGS);
|
SourceCondition::SETTINGS);
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -912,6 +912,7 @@ QMetaObject::Connection PulseWidget(QWidget *widget, QColor startColor,
|
|||||||
[animation] {
|
[animation] {
|
||||||
animation->start();
|
animation->start();
|
||||||
});
|
});
|
||||||
|
timer->setSingleShot(true);
|
||||||
timer->start(1000);
|
timer->start(1000);
|
||||||
});
|
});
|
||||||
animation->start();
|
animation->start();
|
||||||
|
|||||||
Reference in New Issue
Block a user