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(); +}