diff --git a/src/tiled/automapper.cpp b/src/tiled/automapper.cpp index cbf8d1ea59..06359532ab 100644 --- a/src/tiled/automapper.cpp +++ b/src/tiled/automapper.cpp @@ -674,7 +674,7 @@ void AutoMapper::setupRules() #endif } -void AutoMapper::prepareAutoMap(AutoMappingContext &context) +void AutoMapper::prepareAutoMap(AutoMappingContext &context) const { setupWorkMapLayers(context); diff --git a/src/tiled/automapper.h b/src/tiled/automapper.h index a8ca7da548..a869d5a9fe 100644 --- a/src/tiled/automapper.h +++ b/src/tiled/automapper.h @@ -351,7 +351,7 @@ class TILED_EDITOR_EXPORT AutoMapper * painful to keep these data structures up to date all time. (indices of * layers of the working map) */ - void prepareAutoMap(AutoMappingContext &context); + void prepareAutoMap(AutoMappingContext &context) const; /** * Here is done all the AutoMapping. diff --git a/src/tiled/automapperwrapper.cpp b/src/tiled/automapperwrapper.cpp index 3fc4ae1735..749b5fbce8 100644 --- a/src/tiled/automapperwrapper.cpp +++ b/src/tiled/automapperwrapper.cpp @@ -36,7 +36,7 @@ using namespace Tiled; AutoMapperWrapper::AutoMapperWrapper(MapDocument *mapDocument, - const QVector &autoMappers, + const QVector &autoMappers, const QRegion &where, const TileLayer *touchedLayer) : PaintTileLayer(mapDocument) diff --git a/src/tiled/automapperwrapper.h b/src/tiled/automapperwrapper.h index ae2bba35b8..a83a76a2b5 100644 --- a/src/tiled/automapperwrapper.h +++ b/src/tiled/automapperwrapper.h @@ -40,7 +40,7 @@ class AutoMapperWrapper : public PaintTileLayer { public: AutoMapperWrapper(MapDocument *mapDocument, - const QVector &autoMappers, + const QVector &autoMappers, const QRegion &where, const TileLayer *touchedLayer = nullptr); }; diff --git a/src/tiled/automappingmanager.cpp b/src/tiled/automappingmanager.cpp index b84070d0f4..7f9a095f5b 100644 --- a/src/tiled/automappingmanager.cpp +++ b/src/tiled/automappingmanager.cpp @@ -26,7 +26,6 @@ #include "logginginterface.h" #include "map.h" #include "mapdocument.h" -#include "preferences.h" #include "project.h" #include "projectmanager.h" #include "tilelayer.h" @@ -138,12 +137,12 @@ void AutomappingManager::autoMapInternal(const QRegion &where, // Determine the list of AutoMappers that is relevant for this map const QString mapFileName = QFileInfo(mMapDocument->fileName()).fileName(); - QVector autoMappers; - autoMappers.reserve(mAutoMappers.size()); - for (const auto &autoMapper : mAutoMappers) { + QVector autoMappers; + autoMappers.reserve(mActiveAutoMappers.size()); + for (auto autoMapper : mActiveAutoMappers) { const auto &mapNameFilter = autoMapper->mapNameFilter(); if (!mapNameFilter.isValid() || mapNameFilter.match(mapFileName).hasMatch()) - autoMappers.append(autoMapper.get()); + autoMappers.append(autoMapper); } if (autoMappers.isEmpty()) @@ -154,7 +153,7 @@ void AutomappingManager::autoMapInternal(const QRegion &where, if (touchedLayer) { if (std::none_of(autoMappers.cbegin(), autoMappers.cend(), - [=] (AutoMapper *autoMapper) { return autoMapper->ruleLayerNameUsed(touchedLayer->name()); })) + [=] (const AutoMapper *autoMapper) { return autoMapper->ruleLayerNameUsed(touchedLayer->name()); })) return; } @@ -254,6 +253,12 @@ bool AutomappingManager::loadRulesFile(const QString &filePath) bool AutomappingManager::loadRuleMap(const QString &filePath) { + auto it = mLoadedAutoMappers.find(filePath); + if (it != mLoadedAutoMappers.end()) { + mActiveAutoMappers.push_back(it->second.get()); + return true; + } + QString errorString; std::unique_ptr rules { readMap(filePath, &errorString) }; @@ -272,7 +277,9 @@ bool AutomappingManager::loadRuleMap(const QString &filePath) mWarning += autoMapper->warningString(); const QString error = autoMapper->errorString(); if (error.isEmpty()) { - mAutoMappers.push_back(std::move(autoMapper)); + auto autoMapperPtr = autoMapper.get(); + mLoadedAutoMappers.insert(std::make_pair(filePath, std::move(autoMapper))); + mActiveAutoMappers.push_back(autoMapperPtr); mWatcher.addPath(filePath); } else { mError += error; @@ -339,14 +346,18 @@ void AutomappingManager::refreshRulesFile(const QString &ruleFileOverride) void AutomappingManager::cleanUp() { - mAutoMappers.clear(); + mActiveAutoMappers.clear(); mLoaded = false; - if (!mWatcher.files().isEmpty()) - mWatcher.removePaths(mWatcher.files()); } -void AutomappingManager::onFileChanged() +void AutomappingManager::onFileChanged(const QString &path) { + // Make sure the changed file will be reloaded + mLoadedAutoMappers.erase(path); + + // File will be re-added when it is still relevant + mWatcher.removePath(path); + cleanUp(); } diff --git a/src/tiled/automappingmanager.h b/src/tiled/automappingmanager.h index 52f0750f6d..d47ed7ce3b 100644 --- a/src/tiled/automappingmanager.h +++ b/src/tiled/automappingmanager.h @@ -82,7 +82,7 @@ class AutomappingManager : public QObject private: void onRegionEdited(const QRegion &where, TileLayer *touchedLayer); void onMapFileNameChanged(); - void onFileChanged(); + void onFileChanged(const QString &path); bool loadFile(const QString &filePath); bool loadRulesFile(const QString &filePath); @@ -107,10 +107,19 @@ class AutomappingManager : public QObject MapDocument *mMapDocument = nullptr; /** - * For each new file of rules a new AutoMapper is setup. In this vector we - * can store all of the AutoMappers in order. + * For each rule map references by the rules file a new AutoMapper is + * setup. In this map we store all loaded AutoMappers instances. */ - std::vector> mAutoMappers; + std::unordered_map> mLoadedAutoMappers; + + /** + * The active list of AutoMapper instances, in the order they were + * encountered in the rules file. + * + * Some loaded rule maps might not be active, and some might be active + * multiple times. + */ + std::vector mActiveAutoMappers; /** * This tells you if the rules for the current map document were already