[LYN-9953] Asset Processor: Fix file watcher event handlers calling APM methods directly instead … (#7289)

* Fix file watcher event handlers calling APM methods directly instead of queuing them to run on the APM thread

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Add unit test

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Fix compile errors

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Fix compile errors

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Fix compile errors

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Fix compile errors

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Change ASSERT_ checks to EXPECT_ checks

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Refactored Test

Removed leftover direct call
Changed invokeMethod to use lambda form

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>

* Fix compile error

Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
This commit is contained in:
amzn-mike
2022-02-14 11:09:39 -06:00
committed by GitHub
parent 6f52fcb9f0
commit 5dd88ba05c
18 changed files with 452 additions and 73 deletions
@@ -431,79 +431,114 @@ void ApplicationManagerBase::DestroyPlatformConfiguration()
}
}
void ApplicationManagerBase::InitFileMonitor()
void ApplicationManagerBase::InitFileMonitor(AZStd::unique_ptr<FileWatcher> fileWatcher)
{
m_fileWatcher = AZStd::move(fileWatcher);
for (int folderIdx = 0; folderIdx < m_platformConfiguration->GetScanFolderCount(); ++folderIdx)
{
const AssetProcessor::ScanFolderInfo& info = m_platformConfiguration->GetScanFolderAt(folderIdx);
m_fileWatcher.AddFolderWatch(info.ScanPath(), info.RecurseSubFolders());
m_fileWatcher->AddFolderWatch(info.ScanPath(), info.RecurseSubFolders());
}
QDir cacheRoot;
if (AssetUtilities::ComputeProjectCacheRoot(cacheRoot))
{
m_fileWatcher.AddFolderWatch(cacheRoot.absolutePath(), true);
m_fileWatcher->AddFolderWatch(cacheRoot.absolutePath(), true);
}
if (m_platformConfiguration->GetScanFolderCount() || !cacheRoot.path().isEmpty())
{
const auto cachePath = QDir::toNativeSeparators(cacheRoot.absolutePath());
// For the handlers below, we need to make sure to use invokeMethod on any QObjects so Qt can queue
// the callback to run on the QObject's thread if needed. The APM methods for example are not thread-safe.
const auto OnFileAdded = [this, cachePath](QString path)
{
const bool isCacheRoot = path.startsWith(cachePath);
if (isCacheRoot)
if (!isCacheRoot)
{
m_fileStateCache->AddFile(path);
}
else
{
m_assetProcessorManager->AssessAddedFile(path);
m_fileStateCache->AddFile(path);
AZ::Interface<AssetProcessor::ExcludedFolderCacheInterface>::Get()->FileAdded(path);
m_fileProcessor->AssetProcessor::FileProcessor::AssessAddedFile(path);
[[maybe_unused]] bool result = QMetaObject::invokeMethod(m_assetProcessorManager, [this, path]()
{
m_assetProcessorManager->AssessAddedFile(path);
}, Qt::QueuedConnection);
AZ_Assert(result, "Failed to invoke m_assetProcessorManager::AssessAddedFile");
result = QMetaObject::invokeMethod(m_fileProcessor.get(), [this, path]()
{
m_fileProcessor->AssessAddedFile(path);
}, Qt::QueuedConnection);
AZ_Assert(result, "Failed to invoke m_fileProcessor::AssessAddedFile");
auto cache = AZ::Interface<AssetProcessor::ExcludedFolderCacheInterface>::Get();
if(cache)
{
cache->FileAdded(path);
}
else
{
AZ_Error("AssetProcessor", false, "ExcludedFolderCacheInterface not found");
}
}
m_fileStateCache->AddFile(path);
};
const auto OnFileModified = [this, cachePath](QString path)
{
const bool isCacheRoot = path.startsWith(cachePath);
if (isCacheRoot)
if (!isCacheRoot)
{
m_assetProcessorManager->AssessModifiedFile(path);
}
else
{
m_assetProcessorManager->AssessModifiedFile(path);
m_fileStateCache->UpdateFile(path);
}
[[maybe_unused]] bool result = QMetaObject::invokeMethod(
m_assetProcessorManager,
[this, path]
{
m_assetProcessorManager->AssessModifiedFile(path);
}, Qt::QueuedConnection);
AZ_Assert(result, "Failed to invoke m_assetProcessorManager::AssessModifiedFile");
};
const auto OnFileRemoved = [this, cachePath](QString path)
{
[[maybe_unused]] bool result = false;
const bool isCacheRoot = path.startsWith(cachePath);
if (isCacheRoot)
if (!isCacheRoot)
{
m_fileStateCache->RemoveFile(path);
m_assetProcessorManager->AssessDeletedFile(path);
result = QMetaObject::invokeMethod(m_fileProcessor.get(), [this, path]()
{
m_fileProcessor->AssessDeletedFile(path);
}, Qt::QueuedConnection);
AZ_Assert(result, "Failed to invoke m_fileProcessor::AssessDeletedFile");
}
else
result = QMetaObject::invokeMethod(m_assetProcessorManager, [this, path]()
{
m_assetProcessorManager->AssessDeletedFile(path);
m_fileStateCache->RemoveFile(path);
m_fileProcessor->AssessDeletedFile(path);
}
}, Qt::QueuedConnection);
AZ_Assert(result, "Failed to invoke m_assetProcessorManager::AssessDeletedFile");
m_fileStateCache->RemoveFile(path);
};
connect(&m_fileWatcher, &FileWatcher::fileAdded, OnFileAdded);
connect(&m_fileWatcher, &FileWatcher::fileModified, OnFileModified);
connect(&m_fileWatcher, &FileWatcher::fileRemoved, OnFileRemoved);
connect(m_fileWatcher.get(), &FileWatcher::fileAdded, OnFileAdded);
connect(m_fileWatcher.get(), &FileWatcher::fileModified, OnFileModified);
connect(m_fileWatcher.get(), &FileWatcher::fileRemoved, OnFileRemoved);
}
}
void ApplicationManagerBase::DestroyFileMonitor()
{
m_fileWatcher.ClearFolderWatches();
if(m_fileWatcher)
{
m_fileWatcher->ClearFolderWatches();
m_fileWatcher = nullptr;
}
}
void ApplicationManagerBase::DestroyApplicationServer()
@@ -1357,7 +1392,7 @@ bool ApplicationManagerBase::Activate()
InitFileProcessor();
InitAssetCatalog();
InitFileMonitor();
InitFileMonitor(AZStd::make_unique<FileWatcher>());
InitAssetScanner();
InitAssetServerHandler();
InitRCController();