diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 30d47fb2..e92bfc25 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -684,7 +684,7 @@ AdvSceneSwitcher.condition.clipboard.condition.isURL="Clipboard contains an URL" AdvSceneSwitcher.condition.clipboard.condition.matches="Clipboard content matches" AdvSceneSwitcher.condition.clipboard.condition.entry="{{conditions}}{{regex}}{{urlInfo}}" AdvSceneSwitcher.condition.folder="Folder watch" -AdvSceneSwitcher.condition.folder.tooltip="This condition type will allow you to monitor the contents of a folder.\nNote that the monitoring will *not* recursively scan for changes in sub directories within directories of the selected folder!" +AdvSceneSwitcher.condition.folder.tooltip="This condition type will allow you to monitor the contents of a folder.\nNote that the monitoring will *not* recursively scan for changes in sub directories within directories of the selected folder!\nNote that if there are several changes during a short period of time, some of the changes might not emit this signal.\nHowever, the last change in the sequence of changes always will." AdvSceneSwitcher.condition.folder.condition.any="Any change happened" AdvSceneSwitcher.condition.folder.condition.fileAdd="A file was added" AdvSceneSwitcher.condition.folder.condition.fileChange="A file was modified" diff --git a/plugins/base/macro-condition-folder.cpp b/plugins/base/macro-condition-folder.cpp index e438228d..a2bc3843 100644 --- a/plugins/base/macro-condition-folder.cpp +++ b/plugins/base/macro-condition-folder.cpp @@ -37,8 +37,8 @@ MacroConditionFolder::MacroConditionFolder(Macro *m) : MacroCondition(m, true) bool MacroConditionFolder::CheckCondition() { + std::lock_guard lock(_mutex); bool ret = _matched; - if (_lastWatchedValue != _folder.UnresolvedValue()) { SetupWatcher(); } @@ -73,7 +73,7 @@ bool MacroConditionFolder::Load(obs_data_t *obj) _enableFilter = obs_data_get_bool(obj, "enableFilter"); _regex.Load(obj); _regex.SetEnabled(true); // Already controlled via _enableFilter - _filter.Save(obj, "filter"); + _filter.Load(obj, "filter"); _condition = static_cast(obs_data_get_int(obj, "condition")); SetupWatcher(); return true; @@ -108,16 +108,25 @@ static QSet getDirsInDir(const QString &path) return result; } +static void reduceSetToPatternMatch(QSet &set, + const RegexConfig ®ex, + const std::string &pattern) +{ + QSet copy = set; + for (const auto &value : copy) { + if (!regex.Matches(value.toStdString(), pattern)) { + set.remove(value); + } + } +} + void MacroConditionFolder::DirectoryChanged(const QString &path) { + std::lock_guard lock(_mutex); if (MacroIsPaused(GetMacro())) { return; } - if (_enableFilter && !_regex.Matches(path.toStdString(), _filter)) { - return; - } - auto currentFiles = getFilesInDir(path); auto currentDirs = getDirsInDir(path); @@ -133,9 +142,18 @@ void MacroConditionFolder::DirectoryChanged(const QString &path) _removedDirs += _currentDirs - currentDirs; } + if (_enableFilter) { + reduceSetToPatternMatch(_newFiles, _regex, _filter); + reduceSetToPatternMatch(_removedFiles, _regex, _filter); + reduceSetToPatternMatch(_newDirs, _regex, _filter); + reduceSetToPatternMatch(_removedDirs, _regex, _filter); + } + switch (_condition) { case Condition::ANY: - _matched = true; + _matched = _matched || _newFiles.count() > 0 || + _removedFiles.count() > 0 || _newDirs.count() > 0 || + _removedDirs.count() > 0; break; case Condition::FILE_ADD: _matched = _newFiles.count() > 0; @@ -163,13 +181,20 @@ void MacroConditionFolder::DirectoryChanged(const QString &path) void MacroConditionFolder::FileChanged(const QString &path) { + std::lock_guard lock(_mutex); QFileInfo fileInfo(path); if (!fileInfo.exists()) { return; } - _changedFiles << fileInfo.fileName(); - if (_condition == Condition::FILE_CHANGE) { + const auto fileName = fileInfo.fileName(); + if (_enableFilter && !_regex.Matches(fileName.toStdString(), _filter)) { + return; + } + + _changedFiles << fileName; + if (_condition == Condition::FILE_CHANGE || + _condition == Condition::ANY) { _matched = true; } } diff --git a/plugins/base/macro-condition-folder.hpp b/plugins/base/macro-condition-folder.hpp index f2b98a86..6a82f935 100644 --- a/plugins/base/macro-condition-folder.hpp +++ b/plugins/base/macro-condition-folder.hpp @@ -53,6 +53,7 @@ private: std::unique_ptr _watcher; std::string _lastWatchedValue = ""; + std::mutex _mutex; bool _matched = false; QSet _newFiles; QSet _changedFiles;