From 48e6bcbb7a19c1fced69a07fe0ed3b1048422040 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Mon, 24 May 2021 02:01:32 +0200 Subject: [PATCH] Fix conditions and actions referencing macros not loading correctly The reason is that while loading the required macro might not have been loaded resulting in the pointer to the macro never being set correctly in the loading phase. --- src/headers/macro-action-pause.hpp | 3 +- src/headers/macro-condition-counter.hpp | 3 +- src/headers/macro.hpp | 33 +++++++++++- src/macro-action-pause.cpp | 26 ++++----- src/macro-condition-counter.cpp | 36 ++++++------- src/macro.cpp | 71 +++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 42 deletions(-) diff --git a/src/headers/macro-action-pause.hpp b/src/headers/macro-action-pause.hpp index 56a7f793..be670f50 100644 --- a/src/headers/macro-action-pause.hpp +++ b/src/headers/macro-action-pause.hpp @@ -8,7 +8,7 @@ enum class PauseAction { UNPAUSE, }; -class MacroActionPause : public MacroAction { +class MacroActionPause : public MacroRefAction { public: bool PerformAction(); void LogAction(); @@ -21,7 +21,6 @@ public: } PauseAction _action = PauseAction::PAUSE; - Macro *_macro = nullptr; private: static bool _registered; diff --git a/src/headers/macro-condition-counter.hpp b/src/headers/macro-condition-counter.hpp index d788009b..e02bc646 100644 --- a/src/headers/macro-condition-counter.hpp +++ b/src/headers/macro-condition-counter.hpp @@ -12,7 +12,7 @@ enum class CounterCondition { EQUAL, }; -class MacroConditionCounter : public MacroCondition { +class MacroConditionCounter : public MacroRefCondition { public: bool CheckCondition(); bool Save(obs_data_t *obj); @@ -23,7 +23,6 @@ public: return std::make_shared(); } - Macro *_macro = nullptr; CounterCondition _condition = CounterCondition::BELOW; int _count = 0; diff --git a/src/headers/macro.hpp b/src/headers/macro.hpp index 90dd9a22..f5532c20 100644 --- a/src/headers/macro.hpp +++ b/src/headers/macro.hpp @@ -59,7 +59,6 @@ public: }; class Macro { - public: Macro(std::string name = ""); virtual ~Macro(); @@ -81,6 +80,9 @@ public: bool Save(obs_data_t *obj); bool Load(obs_data_t *obj); + // Some macros can refer to other macros, which are not yet loaded. + // Use this function to set these references after loading is complete. + void ResolveMacroRef(); // Helper function for plugin state condition regarding scene change bool SwitchesScene(); @@ -96,3 +98,32 @@ private: Macro *GetMacroByName(const char *name); Macro *GetMacroByQString(const QString &name); + +class MacroRef { +public: + MacroRef(){}; + MacroRef(std::string name); + void UpdateRef(); + void UpdateRef(std::string name); + void UpdateRef(QString name); + void Save(obs_data_t *obj); + void Load(obs_data_t *obj); + Macro *get(); + Macro *operator->(); + +private: + std::string _name = ""; + Macro *_ref = nullptr; +}; + +class MacroRefCondition : public MacroCondition { +public: + void ResolveMacroRef(); + MacroRef _macro; +}; + +class MacroRefAction : public MacroAction { +public: + void ResolveMacroRef(); + MacroRef _macro; +}; diff --git a/src/macro-action-pause.cpp b/src/macro-action-pause.cpp index 1e79f649..28c30a34 100644 --- a/src/macro-action-pause.cpp +++ b/src/macro-action-pause.cpp @@ -16,7 +16,7 @@ const static std::map actionTypes = { bool MacroActionPause::PerformAction() { - if (!_macro) { + if (!_macro.get()) { return true; } @@ -35,7 +35,7 @@ bool MacroActionPause::PerformAction() void MacroActionPause::LogAction() { - if (!_macro) { + if (!_macro.get()) { return; } switch (_action) { @@ -53,9 +53,7 @@ void MacroActionPause::LogAction() bool MacroActionPause::Save(obs_data_t *obj) { MacroAction::Save(obj); - if (_macro) { - obs_data_set_string(obj, "macro", _macro->Name().c_str()); - } + _macro.Save(obj); obs_data_set_int(obj, "action", static_cast(_action)); return true; } @@ -63,7 +61,7 @@ bool MacroActionPause::Save(obs_data_t *obj) bool MacroActionPause::Load(obs_data_t *obj) { MacroAction::Load(obj); - _macro = GetMacroByName(obs_data_get_string(obj, "macro")); + _macro.Load(obj); _action = static_cast(obs_data_get_int(obj, "action")); return true; } @@ -111,7 +109,7 @@ void MacroActionPauseEdit::UpdateEntryData() return; } _actions->setCurrentIndex(static_cast(_entryData->_action)); - _macros->SetCurrentMacro(_entryData->_macro); + _macros->SetCurrentMacro(_entryData->_macro.get()); } void MacroActionPauseEdit::MacroChanged(const QString &text) @@ -121,7 +119,7 @@ void MacroActionPauseEdit::MacroChanged(const QString &text) } std::lock_guard lock(switcher->m); - _entryData->_macro = GetMacroByQString(text); + _entryData->_macro.UpdateRef(text); } void MacroActionPauseEdit::ActionChanged(int value) @@ -136,14 +134,8 @@ void MacroActionPauseEdit::ActionChanged(int value) void MacroActionPauseEdit::MacroRemove(const QString &name) { - int idx = _macros->findText(name); - if (idx == -1) { - return; + UNUSED_PARAMETER(name); + if (_entryData) { + _entryData->_macro.UpdateRef(); } - _macros->removeItem(idx); - if (_entryData && _entryData->_macro == GetMacroByQString(name)) { - std::lock_guard lock(switcher->m); - _entryData->_macro = nullptr; - } - _macros->setCurrentIndex(0); } diff --git a/src/macro-condition-counter.cpp b/src/macro-condition-counter.cpp index dbfbc443..b8d18f13 100644 --- a/src/macro-condition-counter.cpp +++ b/src/macro-condition-counter.cpp @@ -21,13 +21,17 @@ static std::map counterConditionTypes = { bool MacroConditionCounter::CheckCondition() { + if (!_macro.get()) { + return false; + } + switch (_condition) { case CounterCondition::BELOW: - return _macro && _macro->GetCount() < _count; + return _macro->GetCount() < _count; case CounterCondition::ABOVE: - return _macro && _macro->GetCount() > _count; + return _macro->GetCount() > _count; case CounterCondition::EQUAL: - return _macro && _macro->GetCount() == _count; + return _macro->GetCount() == _count; default: break; } @@ -38,9 +42,7 @@ bool MacroConditionCounter::CheckCondition() bool MacroConditionCounter::Save(obs_data_t *obj) { MacroCondition::Save(obj); - if (_macro) { - obs_data_set_string(obj, "macro", _macro->Name().c_str()); - } + _macro.Save(obj); obs_data_set_int(obj, "condition", static_cast(_condition)); obs_data_set_int(obj, "count", _count); return true; @@ -49,7 +51,7 @@ bool MacroConditionCounter::Save(obs_data_t *obj) bool MacroConditionCounter::Load(obs_data_t *obj) { MacroCondition::Load(obj); - _macro = GetMacroByName(obs_data_get_string(obj, "macro")); + _macro.Load(obj); _condition = static_cast( obs_data_get_int(obj, "condition")); _count = obs_data_get_int(obj, "count"); @@ -119,7 +121,7 @@ void MacroConditionCounterEdit::UpdateEntryData() return; } - _macros->SetCurrentMacro(_entryData->_macro); + _macros->SetCurrentMacro(_entryData->_macro.get()); _conditions->setCurrentIndex(static_cast(_entryData->_condition)); _count->setValue(_entryData->_count); ResetTimer(); @@ -132,7 +134,7 @@ void MacroConditionCounterEdit::MacroChanged(const QString &text) } std::lock_guard lock(switcher->m); - _entryData->_macro = GetMacroByQString(text); + _entryData->_macro.UpdateRef(text); ResetTimer(); } @@ -158,21 +160,15 @@ void MacroConditionCounterEdit::ConditionChanged(int cond) void MacroConditionCounterEdit::MacroRemove(const QString &name) { - int idx = _macros->findText(name); - if (idx == -1) { - return; + UNUSED_PARAMETER(name); + if (_entryData) { + _entryData->_macro.UpdateRef(); } - _macros->removeItem(idx); - if (_entryData && _entryData->_macro == GetMacroByQString(name)) { - std::lock_guard lock(switcher->m); - _entryData->_macro = nullptr; - } - _macros->setCurrentIndex(0); } void MacroConditionCounterEdit::ResetClicked() { - if (_loading || !_entryData || !_entryData->_macro) { + if (_loading || !_entryData || !_entryData->_macro.get()) { return; } @@ -182,7 +178,7 @@ void MacroConditionCounterEdit::ResetClicked() void MacroConditionCounterEdit::UpdateCount() { - if (_entryData && _entryData->_macro) { + if (_entryData && _entryData->_macro.get()) { _currentCount->setText( QString::number(_entryData->_macro->GetCount())); } else { diff --git a/src/macro.cpp b/src/macro.cpp index c62ee31f..1e4865ab 100644 --- a/src/macro.cpp +++ b/src/macro.cpp @@ -216,6 +216,23 @@ bool Macro::Load(obs_data_t *obj) return true; } +void Macro::ResolveMacroRef() +{ + for (auto &c : _conditions) { + MacroRefCondition *ref = + dynamic_cast(c.get()); + if (ref) { + ref->_macro.UpdateRef(); + } + } + for (auto &a : _actions) { + MacroRefAction *ref = dynamic_cast(a.get()); + if (ref) { + ref->_macro.UpdateRef(); + } + } +} + bool Macro::SwitchesScene() { MacroActionSwitchScene temp; @@ -350,6 +367,10 @@ void SwitcherData::loadMacros(obs_data_t *obj) obs_data_release(array_obj); } obs_data_array_release(macroArray); + + for (auto &m : macros) { + m.ResolveMacroRef(); + } } bool SwitcherData::checkMacros() @@ -398,3 +419,53 @@ Macro *GetMacroByQString(const QString &name) { return GetMacroByName(name.toUtf8().constData()); } + +MacroRef::MacroRef(std::string name) : _name(name) +{ + UpdateRef(); +} +void MacroRef::UpdateRef() +{ + _ref = GetMacroByName(_name.c_str()); +} +void MacroRef::UpdateRef(std::string newName) +{ + _name = newName; + UpdateRef(); +} +void MacroRef::UpdateRef(QString newName) +{ + _name = newName.toStdString(); + UpdateRef(); +} +void MacroRef::Save(obs_data_t *obj) +{ + if (_ref) { + obs_data_set_string(obj, "macro", _ref->Name().c_str()); + } +} +void MacroRef::Load(obs_data_t *obj) +{ + _name = obs_data_get_string(obj, "macro"); + UpdateRef(); +} + +Macro *MacroRef::get() +{ + return _ref; +} + +Macro *MacroRef::operator->() +{ + return _ref; +} + +void MacroRefCondition::ResolveMacroRef() +{ + _macro.UpdateRef(); +} + +void MacroRefAction::ResolveMacroRef() +{ + _macro.UpdateRef(); +}