[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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user