diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index edda5821c..f7c88f0f6 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -1869,6 +1869,8 @@ AdvSceneSwitcher.audio.monitor.both="Monitor and Output" AdvSceneSwitcher.noSettingsButtons="No buttons found!" +AdvSceneSwitcher.clearBufferOnMatch="Clear message buffer when matching message was found" + ; Legacy tabs below - please don't waste your time adding translations for these :) ; Transition Tab AdvSceneSwitcher.transitionTab.title="Transition" diff --git a/plugins/base/macro-condition-websocket.cpp b/plugins/base/macro-condition-websocket.cpp index 7c0d47ff0..71832d2ba 100644 --- a/plugins/base/macro-condition-websocket.cpp +++ b/plugins/base/macro-condition-websocket.cpp @@ -47,17 +47,27 @@ bool MacroConditionWebsocket::CheckCondition() continue; } if (_regex.Enabled()) { - if (_regex.Matches(*message, _message)) { - SetTempVarValue("message", *message); - SetVariableValue(*message); - return true; + if (!_regex.Matches(*message, _message)) { + continue; } + + SetTempVarValue("message", *message); + SetVariableValue(*message); + if (_clearBufferOnMatch) { + _messageBuffer->Clear(); + } + return true; } else { - if (*message == std::string(_message)) { - SetTempVarValue("message", *message); - SetVariableValue(*message); - return true; + if (*message != std::string(_message)) { + continue; + } + + SetTempVarValue("message", *message); + SetVariableValue(*message); + if (_clearBufferOnMatch) { + _messageBuffer->Clear(); } + return true; } } SetVariableValue(""); @@ -72,6 +82,8 @@ bool MacroConditionWebsocket::Save(obs_data_t *obj) const _regex.Save(obj); obs_data_set_string(obj, "connection", GetWeakConnectionName(_connection).c_str()); + obs_data_set_bool(obj, "clearBufferOnMatch", _clearBufferOnMatch); + obs_data_set_int(obj, "version", 1); return true; } @@ -89,6 +101,11 @@ bool MacroConditionWebsocket::Load(obs_data_t *obj) _connection = GetWeakConnectionByName(obs_data_get_string(obj, "connection")); + _clearBufferOnMatch = obs_data_get_bool(obj, "clearBufferOnMatch"); + if (!obs_data_has_user_value(obj, "version")) { + _clearBufferOnMatch = true; + } + SetType(_type); return true; } @@ -160,6 +177,8 @@ MacroConditionWebsocketEdit::MacroConditionWebsocketEdit( _message(new VariableTextEdit(this)), _regex(new RegexConfigWidget(parent)), _connection(new WSConnectionSelection(this)), + _clearBufferOnMatch(new QCheckBox( + obs_module_text("AdvSceneSwitcher.clearBufferOnMatch"))), _editLayout(new QHBoxLayout()) { populateConditionSelection(_conditions); @@ -174,6 +193,8 @@ MacroConditionWebsocketEdit::MacroConditionWebsocketEdit( QWidget::connect(_connection, SIGNAL(SelectionChanged(const QString &)), this, SLOT(ConnectionSelectionChanged(const QString &))); + QWidget::connect(_clearBufferOnMatch, SIGNAL(stateChanged(int)), this, + SLOT(ClearBufferOnMatchChanged(int))); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(_editLayout); @@ -183,6 +204,7 @@ MacroConditionWebsocketEdit::MacroConditionWebsocketEdit( regexLayout->addStretch(); regexLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addLayout(regexLayout); + mainLayout->addWidget(_clearBufferOnMatch); setLayout(mainLayout); _entryData = entryData; @@ -232,6 +254,7 @@ void MacroConditionWebsocketEdit::UpdateEntryData() _message->setPlainText(_entryData->_message); _regex->SetRegexConfig(_entryData->_regex); _connection->SetConnection(_entryData->GetConnection()); + _clearBufferOnMatch->setChecked(_entryData->_clearBufferOnMatch); if (_entryData->GetType() == MacroConditionWebsocket::Type::REQUEST) { SetupRequestEdit(); @@ -245,11 +268,7 @@ void MacroConditionWebsocketEdit::UpdateEntryData() void MacroConditionWebsocketEdit::ConditionChanged(int index) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->SetType(static_cast(index)); if (_entryData->GetType() == MacroConditionWebsocket::Type::REQUEST) { SetupRequestEdit(); @@ -262,11 +281,7 @@ void MacroConditionWebsocketEdit::ConditionChanged(int index) void MacroConditionWebsocketEdit::MessageChanged() { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_message = _message->toPlainText().toUtf8().constData(); adjustSize(); @@ -276,22 +291,20 @@ void MacroConditionWebsocketEdit::MessageChanged() void MacroConditionWebsocketEdit::ConnectionSelectionChanged( const QString &connection) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->SetConnection(connection.toStdString()); emit(HeaderInfoChanged(connection)); } -void MacroConditionWebsocketEdit::RegexChanged(const RegexConfig &conf) +void MacroConditionWebsocketEdit::ClearBufferOnMatchChanged(int value) { - if (_loading || !_entryData) { - return; - } + GUARD_LOADING_AND_LOCK(); + _entryData->_clearBufferOnMatch = value; +} - auto lock = LockContext(); +void MacroConditionWebsocketEdit::RegexChanged(const RegexConfig &conf) +{ + GUARD_LOADING_AND_LOCK(); _entryData->_regex = conf; adjustSize(); diff --git a/plugins/base/macro-condition-websocket.hpp b/plugins/base/macro-condition-websocket.hpp index d5fc106bc..56d41125c 100644 --- a/plugins/base/macro-condition-websocket.hpp +++ b/plugins/base/macro-condition-websocket.hpp @@ -33,6 +33,7 @@ class MacroConditionWebsocket : public MacroCondition { std::weak_ptr GetConnection() const; StringVariable _message = obs_module_text("AdvSceneSwitcher.enterText"); RegexConfig _regex; + bool _clearBufferOnMatch = true; private: void SetupTempVars(); @@ -69,12 +70,10 @@ private slots: void MessageChanged(); void RegexChanged(const RegexConfig &); void ConnectionSelectionChanged(const QString &); + void ClearBufferOnMatchChanged(int); signals: void HeaderInfoChanged(const QString &); -protected: - std::shared_ptr _entryData; - private: void SetupRequestEdit(); void SetupEventEdit(); @@ -83,7 +82,10 @@ private slots: VariableTextEdit *_message; RegexConfigWidget *_regex; WSConnectionSelection *_connection; + QCheckBox *_clearBufferOnMatch; QHBoxLayout *_editLayout; + + std::shared_ptr _entryData; bool _loading = true; }; diff --git a/plugins/midi/macro-condition-midi.cpp b/plugins/midi/macro-condition-midi.cpp index 3815b105d..66e2be953 100644 --- a/plugins/midi/macro-condition-midi.cpp +++ b/plugins/midi/macro-condition-midi.cpp @@ -33,6 +33,9 @@ bool MacroConditionMidi::CheckCondition() } if (message->Matches(_message)) { SetVariableValues(*message); + if (_clearBufferOnMatch) { + _messageBuffer->Clear(); + } return true; } } @@ -45,6 +48,8 @@ bool MacroConditionMidi::Save(obs_data_t *obj) const MacroCondition::Save(obj); _message.Save(obj); _device.Save(obj); + obs_data_set_bool(obj, "clearBufferOnMatch", _clearBufferOnMatch); + obs_data_set_int(obj, "version", 1); return true; } @@ -54,6 +59,10 @@ bool MacroConditionMidi::Load(obs_data_t *obj) _message.Load(obj); _device.Load(obj); _messageBuffer = _device.RegisterForMidiMessages(); + _clearBufferOnMatch = obs_data_get_bool(obj, "clearBufferOnMatch"); + if (!obs_data_has_user_value(obj, "version")) { + _clearBufferOnMatch = true; + } return true; } @@ -106,7 +115,9 @@ MacroConditionMidiEdit::MacroConditionMidiEdit( _resetMidiDevices(new QPushButton( obs_module_text("AdvSceneSwitcher.midi.resetDevices"))), _listen(new QPushButton( - obs_module_text("AdvSceneSwitcher.midi.startListen"))) + obs_module_text("AdvSceneSwitcher.midi.startListen"))), + _clearBufferOnMatch(new QCheckBox( + obs_module_text("AdvSceneSwitcher.clearBufferOnMatch"))) { QWidget::connect(_devices, SIGNAL(DeviceSelectionChanged(const MidiDevice &)), @@ -119,6 +130,8 @@ MacroConditionMidiEdit::MacroConditionMidiEdit( SLOT(ResetMidiDevices())); QWidget::connect(_listen, SIGNAL(clicked()), this, SLOT(ToggleListen())); + QWidget::connect(_clearBufferOnMatch, SIGNAL(stateChanged(int)), this, + SLOT(ClearBufferOnMatchChanged(int))); QWidget::connect(&_listenTimer, SIGNAL(timeout()), this, SLOT(SetMessageSelectionToLastReceived())); @@ -135,6 +148,7 @@ MacroConditionMidiEdit::MacroConditionMidiEdit( mainLayout->addWidget(_message); mainLayout->addLayout(listenLayout); mainLayout->addWidget(_resetMidiDevices); + mainLayout->addWidget(_clearBufferOnMatch); setLayout(mainLayout); _listenTimer.setInterval(100); @@ -157,6 +171,7 @@ void MacroConditionMidiEdit::UpdateEntryData() _message->SetMessage(_entryData->_message); _devices->SetDevice(_entryData->GetDevice()); + _clearBufferOnMatch->setChecked(_entryData->_clearBufferOnMatch); adjustSize(); updateGeometry(); @@ -182,14 +197,16 @@ void MacroConditionMidiEdit::DeviceSelectionChanged(const MidiDevice &device) void MacroConditionMidiEdit::MidiMessageChanged(const MidiMessage &message) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_message = message; } +void MacroConditionMidiEdit::ClearBufferOnMatchChanged(int value) +{ + GUARD_LOADING_AND_LOCK(); + _entryData->_clearBufferOnMatch = value; +} + void MacroConditionMidiEdit::ResetMidiDevices() { auto lock = LockContext(); diff --git a/plugins/midi/macro-condition-midi.hpp b/plugins/midi/macro-condition-midi.hpp index 5237ad15d..028288a74 100644 --- a/plugins/midi/macro-condition-midi.hpp +++ b/plugins/midi/macro-condition-midi.hpp @@ -2,6 +2,7 @@ #include "macro-condition-edit.hpp" #include "midi-helpers.hpp" +#include #include #include @@ -23,6 +24,7 @@ class MacroConditionMidi : public MacroCondition { void SetDevice(const MidiDevice &dev); const MidiDevice &GetDevice() const { return _device; } MidiMessage _message; + bool _clearBufferOnMatch = true; private: void SetupTempVars(); @@ -55,6 +57,7 @@ class MacroConditionMidiEdit : public QWidget { private slots: void DeviceSelectionChanged(const MidiDevice &); void MidiMessageChanged(const MidiMessage &); + void ClearBufferOnMatchChanged(int); void ResetMidiDevices(); void ToggleListen(); void SetMessageSelectionToLastReceived(); @@ -64,12 +67,13 @@ private slots: private: void EnableListening(bool); - std::shared_ptr _entryData; - MidiDeviceSelection *_devices; MidiMessageSelection *_message; QPushButton *_resetMidiDevices; QPushButton *_listen; + QCheckBox *_clearBufferOnMatch; + + std::shared_ptr _entryData; QTimer _listenTimer; MidiMessageBuffer _messageBuffer; bool _currentlyListening = false; diff --git a/plugins/twitch/macro-condition-twitch.cpp b/plugins/twitch/macro-condition-twitch.cpp index 1297baaf7..ad073b8bc 100644 --- a/plugins/twitch/macro-condition-twitch.cpp +++ b/plugins/twitch/macro-condition-twitch.cpp @@ -305,6 +305,10 @@ bool MacroConditionTwitch::CheckChannelGenericEvents(TwitchToken &token) std::bind(&MacroConditionTwitch::SetTempVarValue, this, std::placeholders::_1, std::placeholders::_2)); + + if (_clearBufferOnMatch) { + _eventBuffer->Clear(); + } return true; } @@ -343,6 +347,10 @@ bool MacroConditionTwitch::CheckChannelLiveEvents(TwitchToken &token) std::bind(&MacroConditionTwitch::SetTempVarValue, this, std::placeholders::_1, std::placeholders::_2)); + + if (_clearBufferOnMatch) { + _eventBuffer->Clear(); + } return true; } @@ -376,11 +384,18 @@ bool MacroConditionTwitch::CheckChatMessages(TwitchToken &token) if (!message) { continue; } - if (stringMatches(_regexChat, message->message, _chatMessage)) { - SetTempVarValue("chatter", message->source.nick); - SetTempVarValue("chat_message", message->message); - return true; + if (!stringMatches(_regexChat, message->message, + _chatMessage)) { + continue; + } + + SetTempVarValue("chatter", message->source.nick); + SetTempVarValue("chat_message", message->message); + + if (_clearBufferOnMatch) { + _eventBuffer->Clear(); } + return true; } return false; } @@ -588,6 +603,8 @@ bool MacroConditionTwitch::Save(obs_data_t *obj) const _chatMessage.Save(obj, "chatMessage"); _regexChat.Save(obj, "regexChat"); _category.Save(obj); + obs_data_set_bool(obj, "clearBufferOnMatch", _clearBufferOnMatch); + obs_data_set_int(obj, "version", 1); return true; } @@ -605,6 +622,10 @@ bool MacroConditionTwitch::Load(obs_data_t *obj) _chatMessage.Load(obj, "chatMessage"); _regexChat.Load(obj, "regexChat"); _category.Load(obj); + _clearBufferOnMatch = obs_data_get_bool(obj, "clearBufferOnMatch"); + if (!obs_data_has_user_value(obj, "version")) { + _clearBufferOnMatch = true; + } _subscriptionID = ""; ResetChatConnection(); @@ -1244,7 +1265,9 @@ MacroConditionTwitchEdit::MacroConditionTwitchEdit( _regexTitle(new RegexConfigWidget(parent)), _chatMessage(new VariableTextEdit(this, 5, 1, 1)), _regexChat(new RegexConfigWidget(parent)), - _category(new TwitchCategoryWidget(this)) + _category(new TwitchCategoryWidget(this)), + _clearBufferOnMatch(new QCheckBox( + obs_module_text("AdvSceneSwitcher.clearBufferOnMatch"))) { _streamTitle->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); @@ -1280,6 +1303,8 @@ MacroConditionTwitchEdit::MacroConditionTwitchEdit( SLOT(CategoreyChanged(const TwitchCategory &))); QWidget::connect(this, SIGNAL(TempVarsChanged()), window(), SIGNAL(SegmentTempVarsChanged())); + QWidget::connect(_clearBufferOnMatch, SIGNAL(stateChanged(int)), this, + SLOT(ClearBufferOnMatchChanged(int))); PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.twitch.entry"), _layout, @@ -1305,6 +1330,7 @@ MacroConditionTwitchEdit::MacroConditionTwitchEdit( mainLayout->addLayout(chatLayout); mainLayout->addLayout(accountLayout); mainLayout->addWidget(_tokenWarning); + mainLayout->addWidget(_clearBufferOnMatch); setLayout(mainLayout); _tokenCheckTimer.start(1000); @@ -1336,11 +1362,7 @@ void MacroConditionTwitchEdit::ConditionChanged(int idx) void MacroConditionTwitchEdit::TwitchTokenChanged(const QString &token) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->SetToken(GetWeakTwitchTokenByQString(token)); _category->SetToken(_entryData->GetToken()); _channel->SetToken(_entryData->GetToken()); @@ -1390,11 +1412,7 @@ void MacroConditionTwitchEdit::CheckToken() void MacroConditionTwitchEdit::ChannelChanged(const TwitchChannel &channel) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->SetChannel(channel); _pointsReward->SetChannel(channel); _entryData->ResetChatConnection(); @@ -1403,41 +1421,25 @@ void MacroConditionTwitchEdit::ChannelChanged(const TwitchChannel &channel) void MacroConditionTwitchEdit::PointsRewardChanged( const TwitchPointsReward &pointsReward) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->SetPointsReward(pointsReward); } void MacroConditionTwitchEdit::StreamTitleChanged() { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_streamTitle = _streamTitle->text().toStdString(); } void MacroConditionTwitchEdit::ChatMessageChanged() { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_chatMessage = _chatMessage->toPlainText().toStdString(); } void MacroConditionTwitchEdit::RegexTitleChanged(const RegexConfig &conf) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_regexTitle = conf; adjustSize(); @@ -1446,11 +1448,7 @@ void MacroConditionTwitchEdit::RegexTitleChanged(const RegexConfig &conf) void MacroConditionTwitchEdit::RegexChatChanged(const RegexConfig &conf) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_regexChat = conf; adjustSize(); @@ -1459,14 +1457,16 @@ void MacroConditionTwitchEdit::RegexChatChanged(const RegexConfig &conf) void MacroConditionTwitchEdit::CategoreyChanged(const TwitchCategory &category) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_category = category; } +void MacroConditionTwitchEdit::ClearBufferOnMatchChanged(int value) +{ + GUARD_LOADING_AND_LOCK(); + _entryData->_clearBufferOnMatch = value; +} + void MacroConditionTwitchEdit::SetWidgetVisibility() { auto condition = _entryData->GetCondition(); @@ -1492,6 +1492,10 @@ void MacroConditionTwitchEdit::SetWidgetVisibility() MacroConditionTwitch::Condition::CHAT_MESSAGE_RECEIVED); _category->setVisible( condition == MacroConditionTwitch::Condition::CATEGORY_POLLING); + _clearBufferOnMatch->setVisible( + _entryData->IsUsingEventSubCondition() || + _entryData->GetCondition() == + MacroConditionTwitch::Condition::CHAT_MESSAGE_RECEIVED); if (condition == MacroConditionTwitch::Condition::TITLE_POLLING) { RemoveStretchIfPresent(_layout); @@ -1525,6 +1529,7 @@ void MacroConditionTwitchEdit::UpdateEntryData() _regexChat->SetRegexConfig(_entryData->_regexChat); _category->SetToken(_entryData->GetToken()); _category->SetCategory(_entryData->_category); + _clearBufferOnMatch->setChecked(_entryData->_clearBufferOnMatch); SetWidgetVisibility(); } diff --git a/plugins/twitch/macro-condition-twitch.hpp b/plugins/twitch/macro-condition-twitch.hpp index c3f1dee37..f7aebd5d2 100644 --- a/plugins/twitch/macro-condition-twitch.hpp +++ b/plugins/twitch/macro-condition-twitch.hpp @@ -89,6 +89,7 @@ class MacroConditionTwitch : public MacroCondition { void SetPointsReward(const TwitchPointsReward &pointsReward); TwitchPointsReward GetPointsReward() const { return _pointsReward; } void ResetChatConnection(); + bool IsUsingEventSubCondition(); bool CheckCondition(); bool Save(obs_data_t *obj) const; @@ -103,6 +104,7 @@ class MacroConditionTwitch : public MacroCondition { StringVariable _chatMessage; RegexConfig _regexChat = RegexConfig::PartialMatchRegexConfig(); TwitchCategory _category; + bool _clearBufferOnMatch = true; private: bool CheckChannelGenericEvents(TwitchToken &token); @@ -112,7 +114,6 @@ class MacroConditionTwitch : public MacroCondition { void RegisterEventSubscription(); void ResetSubscription(); void SetupEventSubscription(EventSub &); - bool IsUsingEventSubCondition(); bool EventSubscriptionIsSetup(const std::shared_ptr &); void AddChannelGenericEventSubscription( const char *version, bool includeModeratorId = false, @@ -169,14 +170,12 @@ private slots: void RegexTitleChanged(const RegexConfig &); void RegexChatChanged(const RegexConfig &); void CategoreyChanged(const TwitchCategory &); + void ClearBufferOnMatchChanged(int); signals: void HeaderInfoChanged(const QString &); void TempVarsChanged(); -protected: - std::shared_ptr _entryData; - private: void SetWidgetVisibility(); void SetTokenWarning(bool visible, const QString &text = ""); @@ -193,7 +192,9 @@ private slots: VariableTextEdit *_chatMessage; RegexConfigWidget *_regexChat; TwitchCategoryWidget *_category; + QCheckBox *_clearBufferOnMatch; + std::shared_ptr _entryData; bool _loading = true; };