Compare commits

..

4 Commits

Author SHA1 Message Date
WarmUpTill
e1020a1909 Fix poad load steps being executed too frequently
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-10-30 20:48:33 +01:00
WarmUpTill
8b0bd4193b Fix temp var save / loading not working 2025-10-30 20:48:33 +01:00
WarmUpTill
d55bb6bc86 Fall back to obs_frontend_get_current_scene()
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
If there wasn't any scene change yet GetCurrentScene() would always
return nullptr and break various scene checks.
For example, this could happen when startup up a fresh OBS install for
the first time.
2025-10-29 12:26:44 +01:00
WarmUpTill
0583331bfd Fix scene selection not working without secondary canvases 2025-10-29 12:26:44 +01:00
12 changed files with 53 additions and 25 deletions

View File

@@ -459,7 +459,7 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
LoadHotkeys(obj); LoadHotkeys(obj);
LoadUISettings(obj); LoadUISettings(obj);
RunPostLoadSteps(); RunAndClearPostLoadSteps();
// Reset on startup and scene collection change // Reset on startup and scene collection change
ResetLastOpenedTab(); ResetLastOpenedTab();

View File

@@ -117,7 +117,7 @@ void MacroActionEdit::ActionSelectionChanged(const QString &text)
*_entryData = MacroActionFactory::Create(id, macro); *_entryData = MacroActionFactory::Create(id, macro);
(*_entryData)->SetIndex(idx); (*_entryData)->SetIndex(idx);
(*_entryData)->PostLoad(); (*_entryData)->PostLoad();
RunPostLoadSteps(); RunAndClearPostLoadSteps();
} }
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData); auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)), QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),

View File

@@ -239,7 +239,7 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
(*_entryData)->SetIndex(idx); (*_entryData)->SetIndex(idx);
(*_entryData)->SetLogicType(logic); (*_entryData)->SetLogicType(logic);
(*_entryData)->PostLoad(); (*_entryData)->PostLoad();
RunPostLoadSteps(); RunAndClearPostLoadSteps();
} }
auto widget = auto widget =
MacroConditionFactory::CreateWidget(id, this, *_entryData); MacroConditionFactory::CreateWidget(id, this, *_entryData);

View File

@@ -1080,7 +1080,7 @@ void MacroEdit::AddMacroAction(Macro *macro, int idx, const std::string &id,
macro->Actions().at(idx)->Load(data); macro->Actions().at(idx)->Load(data);
} }
macro->Actions().at(idx)->PostLoad(); macro->Actions().at(idx)->PostLoad();
RunPostLoadSteps(); RunAndClearPostLoadSteps();
macro->UpdateActionIndices(); macro->UpdateActionIndices();
ui->actionsList->Insert( ui->actionsList->Insert(
idx, idx,
@@ -1383,7 +1383,7 @@ void MacroEdit::AddMacroElseAction(Macro *macro, int idx, const std::string &id,
macro->ElseActions().at(idx)->Load(data); macro->ElseActions().at(idx)->Load(data);
} }
macro->ElseActions().at(idx)->PostLoad(); macro->ElseActions().at(idx)->PostLoad();
RunPostLoadSteps(); RunAndClearPostLoadSteps();
macro->UpdateElseActionIndices(); macro->UpdateElseActionIndices();
ui->elseActionsList->Insert( ui->elseActionsList->Insert(
idx, new MacroActionEdit( idx, new MacroActionEdit(
@@ -1583,7 +1583,7 @@ void MacroEdit::AddMacroCondition(Macro *macro, int idx, const std::string &id,
macro->Conditions().at(idx)->Load(data); macro->Conditions().at(idx)->Load(data);
} }
macro->Conditions().at(idx)->PostLoad(); macro->Conditions().at(idx)->PostLoad();
RunPostLoadSteps(); RunAndClearPostLoadSteps();
(*cond)->SetLogicType(logic); (*cond)->SetLogicType(logic);
macro->UpdateConditionIndices(); macro->UpdateConditionIndices();
ui->conditionsList->Insert( ui->conditionsList->Insert(

View File

@@ -416,7 +416,7 @@ void AdvSceneSwitcher::ImportMacros()
OBSDataAutoRelease array_obj = obs_data_array_item(array, i); OBSDataAutoRelease array_obj = obs_data_array_item(array, i);
auto macro = std::make_shared<Macro>(); auto macro = std::make_shared<Macro>();
macro->Load(array_obj); macro->Load(array_obj);
RunPostLoadSteps(); RunAndClearPostLoadSteps();
if (macroNameExists(macro->Name()) && if (macroNameExists(macro->Name()) &&
!ResolveMacroImportNameConflict(macro)) { !ResolveMacroImportNameConflict(macro)) {
@@ -444,7 +444,7 @@ void AdvSceneSwitcher::ImportMacros()
for (const auto &macro : importedMacros) { for (const auto &macro : importedMacros) {
macro->PostLoad(); macro->PostLoad();
} }
RunPostLoadSteps(); RunAndClearPostLoadSteps();
ui->macros->Reset(GetMacros(), ui->macros->Reset(GetMacros(),
GetGlobalMacroSettings()._highlightExecuted); GetGlobalMacroSettings()._highlightExecuted);
@@ -752,7 +752,7 @@ void AdvSceneSwitcher::CopyMacro()
newMacro->Load(data); newMacro->Load(data);
newMacro->PostLoad(); newMacro->PostLoad();
newMacro->SetName(name); newMacro->SetName(name);
RunPostLoadSteps(); RunAndClearPostLoadSteps();
Macro::PrepareMoveToGroup(macro->Parent(), newMacro); Macro::PrepareMoveToGroup(macro->Parent(), newMacro);
ui->macros->Add(newMacro, macro); ui->macros->Add(newMacro, macro);

View File

@@ -113,7 +113,7 @@ void ActionQueue::Add(const std::shared_ptr<MacroAction> &action)
action->Save(data); action->Save(data);
copy->Load(data); copy->Load(data);
copy->PostLoad(); copy->PostLoad();
RunPostLoadSteps(); RunAndClearPostLoadSteps();
copy->ResolveVariablesToFixedValues(); copy->ResolveVariablesToFixedValues();
_actions.emplace_back(copy); _actions.emplace_back(copy);
} else { } else {

View File

@@ -113,12 +113,13 @@ void RunLoadSteps(obs_data_t *obj)
} }
} }
void RunPostLoadSteps() void RunAndClearPostLoadSteps()
{ {
std::lock_guard<std::mutex> lock(postLoadMutex); std::lock_guard<std::mutex> lock(postLoadMutex);
for (const auto &func : getPostLoadSteps()) { for (const auto &func : getPostLoadSteps()) {
func(); func();
} }
getPostLoadSteps().clear();
} }
void ClearPostLoadSteps() void ClearPostLoadSteps()

View File

@@ -14,7 +14,7 @@ EXPORT void AddPostLoadStep(std::function<void()>);
EXPORT void AddIntervalResetStep(std::function<void()>); EXPORT void AddIntervalResetStep(std::function<void()>);
void RunSaveSteps(obs_data_t *); void RunSaveSteps(obs_data_t *);
void RunLoadSteps(obs_data_t *); void RunLoadSteps(obs_data_t *);
EXPORT void RunPostLoadSteps(); EXPORT void RunAndClearPostLoadSteps();
void ClearPostLoadSteps(); void ClearPostLoadSteps();
EXPORT void AddPluginInitStep(std::function<void()>); EXPORT void AddPluginInitStep(std::function<void()>);

View File

@@ -239,22 +239,26 @@ void SceneSelection::ResolveVariables()
_type = Type::SCENE; _type = Type::SCENE;
} }
SceneSelection SceneSelectionWidget::CurrentSelection() static obs_weak_canvas_t *getWeakRefToMainCanvas()
{ {
SceneSelection s; static auto canvas = obs_get_main_canvas();
static auto weakCanvas = obs_canvas_get_weak_canvas(canvas);
static auto mainCanvas = obs_get_main_canvas();
static auto mainCanvasWeak = obs_canvas_get_weak_canvas(mainCanvas);
[[maybe_unused]] static const bool _ = []() { [[maybe_unused]] static const bool _ = []() {
// Let's just hope we don't have to deal with selecting scenes // Let's just hope we don't have to deal with selecting scenes
// when the OBS main canvas gets deleted and release the // when the OBS main canvas gets deleted and release the
// references here already to avoid reporting leaks on shutdown // references here already to avoid reporting leaks on shutdown
obs_canvas_release(mainCanvas); obs_canvas_release(canvas);
obs_weak_canvas_release(mainCanvasWeak); obs_weak_canvas_release(weakCanvas);
return true; return true;
}(); }();
return weakCanvas;
}
s._canvas = _forceMainCanvas ? OBSWeakCanvas(mainCanvasWeak) SceneSelection SceneSelectionWidget::CurrentSelection()
{
SceneSelection s;
s._canvas = _forceMainCanvas ? OBSWeakCanvas(getWeakRefToMainCanvas())
: _canvas->GetCanvas(); : _canvas->GetCanvas();
const int idx = _scenes->currentIndex(); const int idx = _scenes->currentIndex();
@@ -342,6 +346,10 @@ void SceneSelectionWidget::Reset()
void SceneSelectionWidget::PopulateSceneSelection(obs_weak_canvas_t *canvas) void SceneSelectionWidget::PopulateSceneSelection(obs_weak_canvas_t *canvas)
{ {
if (_forceMainCanvas) {
canvas = getWeakRefToMainCanvas();
}
_scenes->clear(); _scenes->clear();
if ((_current || _previous)) { if ((_current || _previous)) {
const bool isMain = IsMainCanvas(canvas); const bool isMain = IsMainCanvas(canvas);
@@ -418,7 +426,7 @@ SceneSelectionWidget::SceneSelectionWidget(QWidget *parent, bool variables,
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
if (GetCanvasCount() <= 1) { if (GetCanvasCount() <= 1) {
_canvas->hide(); LockToMainCanvas();
} }
Resize(); Resize();

View File

@@ -199,7 +199,17 @@ std::chrono::high_resolution_clock::time_point GetLastSceneChangeTime()
OBSWeakSource GetCurrentScene() OBSWeakSource GetCurrentScene()
{ {
return switcher->currentScene; if (switcher->currentScene) {
return switcher->currentScene;
}
// If there wasn't any scene switch yet switcher->currentScene will be
// null and we must use obs_frontend_get_current_scene() instead
OBSSourceAutoRelease currentSceneSource =
obs_frontend_get_current_scene();
OBSWeakSourceAutoRelease currentSceneWeakSource =
obs_source_get_weak_source(currentSceneSource);
return currentSceneWeakSource.Get();
} }
OBSWeakSource GetPreviousScene() OBSWeakSource GetPreviousScene()

View File

@@ -202,6 +202,8 @@ static void appendNestedMacros(std::deque<std::shared_ptr<Macro>> &macros,
dynamic_cast<MacroActionMacro *>(action.get()); dynamic_cast<MacroActionMacro *>(action.get());
if (nestedMacroAction) { if (nestedMacroAction) {
macros.push_back(nestedMacroAction->_nestedMacro); macros.push_back(nestedMacroAction->_nestedMacro);
appendNestedMacros(
macros, nestedMacroAction->_nestedMacro.get());
} }
} }
for (const auto &action : macro->ElseActions()) { for (const auto &action : macro->ElseActions()) {
@@ -209,6 +211,8 @@ static void appendNestedMacros(std::deque<std::shared_ptr<Macro>> &macros,
dynamic_cast<MacroActionMacro *>(action.get()); dynamic_cast<MacroActionMacro *>(action.get());
if (nestedMacroAction) { if (nestedMacroAction) {
macros.push_back(nestedMacroAction->_nestedMacro); macros.push_back(nestedMacroAction->_nestedMacro);
appendNestedMacros(
macros, nestedMacroAction->_nestedMacro.get());
} }
} }
} }
@@ -301,8 +305,13 @@ void TempVariableRef::Save(obs_data_t *obj, Macro *macro,
void TempVariableRef::Load(obs_data_t *obj, Macro *macroPtr, const char *name) void TempVariableRef::Load(obs_data_t *obj, Macro *macroPtr, const char *name)
{ {
std::deque<std::shared_ptr<Macro>> allMacros = GetMacros();
for (const auto &topLevelMacro : GetMacros()) {
appendNestedMacros(allMacros, topLevelMacro.get());
}
std::weak_ptr<Macro> macro; std::weak_ptr<Macro> macro;
for (const auto &macroShared : GetMacros()) { for (const auto &macroShared : allMacros) {
if (macroShared.get() == macroPtr) { if (macroShared.get() == macroPtr) {
macro = macroShared; macro = macroShared;
break; break;
@@ -340,7 +349,7 @@ void TempVariableRef::PostLoad(int idx, SegmentType type,
return; return;
} }
Macro *macro = nullptr; auto macro = childMacro.get();
for (int i = 0; i < _depth; i++) { for (int i = 0; i < _depth; i++) {
macro = getParentMacro(childMacro.get()); macro = getParentMacro(childMacro.get());
} }

View File

@@ -75,7 +75,7 @@ private:
void PostLoad(int idx, SegmentType, const std::weak_ptr<Macro> &); void PostLoad(int idx, SegmentType, const std::weak_ptr<Macro> &);
std::string _id = ""; std::string _id = "";
std::weak_ptr<MacroSegment> _segment; std::weak_ptr<MacroSegment> _segment = {};
int _depth = 0; int _depth = 0;
friend TempVariable; friend TempVariable;