ce0bb1ca2b
This change reworks the AssetProcessor's FileWatcher so that it only uses one thread. This is motivated by getting better support for inotify on Linux. The previous architecture required calling `inotify_init` once for each directory that was being watched, and using separate inotify instances for each watched tree. In addition, having separate threads per watched tree is not necessary, and just consumes system resources. Each platform supports watching multiple directories with the same platform-specific watcher API, so each platform has been updated accordingly. The interface to the FileWatcher class is greatly simplified. Previously, it supported client-supplied filtering of the paths that would generate notifications. This was done by subclassing `FolderWatchBase` and implementing `OnFileChange`. However, only one filter was ever used, so that filter is now hard-coded in the FileWatcher class, and the classes driving the old filtering mechanism are removed. Users of the interface now have a much easier time, they just call `AddFolderWatch` with the path to watch, and only have to connect to one set of signals, instead of separate signals per watched directory. Signed-off-by: Chris Burel <burelc@amazon.com>
249 lines
9.8 KiB
C++
249 lines
9.8 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#if !defined(Q_MOC_RUN)
|
|
#include <AzCore/std/string/string.h>
|
|
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
|
#include <AzCore/std/containers/vector.h>
|
|
#include <AzCore/Debug/TraceMessageBus.h>
|
|
#include <AzToolsFramework/API/AssetDatabaseBus.h>
|
|
#include <native/FileWatcher/FileWatcher.h>
|
|
#include <native/utilities/ApplicationManager.h>
|
|
#include <native/utilities/AssetBuilderInfo.h>
|
|
#include <native/utilities/BuilderManager.h>
|
|
#endif
|
|
|
|
namespace AzToolsFramework
|
|
{
|
|
class ProcessWatcher;
|
|
class Ticker;
|
|
}
|
|
|
|
namespace AssetProcessor
|
|
{
|
|
class AssetCatalog;
|
|
class AssetProcessorManager;
|
|
class AssetRequestHandler;
|
|
class AssetScanner;
|
|
class AssetServerHandler;
|
|
class BuilderConfigurationManager;
|
|
class BuilderManager;
|
|
class ExternalModuleAssetBuilderInfo;
|
|
class FileProcessor;
|
|
class FileStateBase;
|
|
class FileStateCache;
|
|
class InternalAssetBuilderInfo;
|
|
class PlatformConfiguration;
|
|
class RCController;
|
|
class SettingsRegistryBuilder;
|
|
}
|
|
|
|
class ApplicationServer;
|
|
class ConnectionManager;
|
|
class ControlRequestHandler;
|
|
|
|
class ApplicationManagerBase
|
|
: public ApplicationManager
|
|
, public AssetBuilderSDK::AssetBuilderBus::Handler
|
|
, public AssetProcessor::AssetBuilderInfoBus::Handler
|
|
, public AssetProcessor::AssetBuilderRegistrationBus::Handler
|
|
, public AZ::Debug::TraceMessageBus::Handler
|
|
, protected AzToolsFramework::AssetDatabase::AssetDatabaseRequests::Bus::Handler
|
|
, public AssetProcessor::DiskSpaceInfoBus::Handler
|
|
, protected AzToolsFramework::SourceControlNotificationBus::Handler
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit ApplicationManagerBase(int* argc, char*** argv, QObject* parent = 0);
|
|
virtual ~ApplicationManagerBase();
|
|
ApplicationManager::BeforeRunStatus BeforeRun() override;
|
|
void Destroy() override;
|
|
bool Run() override;
|
|
void HandleFileRelocation() const;
|
|
bool Activate() override;
|
|
bool PostActivate() override;
|
|
|
|
AssetProcessor::PlatformConfiguration* GetPlatformConfiguration() const;
|
|
|
|
AssetProcessor::AssetProcessorManager* GetAssetProcessorManager() const;
|
|
|
|
AssetProcessor::AssetScanner* GetAssetScanner() const;
|
|
|
|
AssetProcessor::RCController* GetRCController() const;
|
|
|
|
ConnectionManager* GetConnectionManager() const;
|
|
ApplicationServer* GetApplicationServer() const;
|
|
|
|
int ProcessedAssetCount() const;
|
|
int FailedAssetsCount() const;
|
|
void ResetProcessedAssetCount();
|
|
void ResetFailedAssetCount();
|
|
|
|
//! AssetBuilderSDK::AssetBuilderBus Interface
|
|
void RegisterBuilderInformation(const AssetBuilderSDK::AssetBuilderDesc& builderDesc) override;
|
|
void RegisterComponentDescriptor(AZ::ComponentDescriptor* descriptor) override;
|
|
void BuilderLog(const AZ::Uuid& builderId, const char* message, ...) override;
|
|
void BuilderLogV(const AZ::Uuid& builderId, const char* message, va_list list) override;
|
|
bool FindBuilderInformation(const AZ::Uuid& builderGuid, AssetBuilderSDK::AssetBuilderDesc& descriptionOut) override;
|
|
|
|
//! AssetBuilderSDK::InternalAssetBuilderBus Interface
|
|
void UnRegisterBuilderDescriptor(const AZ::Uuid& builderId) override;
|
|
|
|
//! AssetProcessor::AssetBuilderInfoBus Interface
|
|
void GetMatchingBuildersInfo(const AZStd::string& assetPath, AssetProcessor::BuilderInfoList& builderInfoList) override;
|
|
void GetAllBuildersInfo(AssetProcessor::BuilderInfoList& builderInfoList) override;
|
|
|
|
//! TraceMessageBus Interface
|
|
bool OnError(const char* window, const char* message) override;
|
|
|
|
//! DiskSpaceInfoBus::Handler
|
|
bool CheckSufficientDiskSpace(const QString& savePath, qint64 requiredSpace, bool shutdownIfInsufficient) override;
|
|
|
|
//! AzFramework::SourceControlNotificationBus::Handler
|
|
void ConnectivityStateChanged(const AzToolsFramework::SourceControlState newState) override;
|
|
|
|
void RemoveOldTempFolders();
|
|
|
|
void Rescan();
|
|
|
|
bool IsAssetProcessorManagerIdle() const override;
|
|
bool CheckFullIdle();
|
|
Q_SIGNALS:
|
|
void CheckAssetProcessorManagerIdleState();
|
|
void ConnectionStatusMsg(QString message);
|
|
void SourceControlReady();
|
|
void OnBuildersRegistered();
|
|
void AssetProcesserManagerIdleStateChange(bool isIdle);
|
|
void FullIdle(bool isIdle);
|
|
public Q_SLOTS:
|
|
void OnAssetProcessorManagerIdleState(bool isIdle);
|
|
|
|
protected:
|
|
virtual void InitAssetProcessorManager();//Deletion of assetProcessor Manager will be handled by the ThreadController
|
|
virtual void InitAssetCatalog();//Deletion of AssetCatalog will be handled when the ThreadController is deleted by the base ApplicationManager
|
|
virtual void InitRCController();
|
|
virtual void DestroyRCController();
|
|
virtual void InitAssetScanner();
|
|
virtual void DestroyAssetScanner();
|
|
virtual bool InitPlatformConfiguration();
|
|
virtual void DestroyPlatformConfiguration();
|
|
virtual void InitFileMonitor();
|
|
virtual void DestroyFileMonitor();
|
|
virtual bool InitBuilderConfiguration();
|
|
virtual void InitControlRequestHandler();
|
|
virtual void DestroyControlRequestHandler();
|
|
virtual bool InitApplicationServer() = 0;
|
|
void DestroyApplicationServer();
|
|
virtual void InitConnectionManager();
|
|
void DestroyConnectionManager();
|
|
void InitAssetRequestHandler(AssetProcessor::AssetRequestHandler* assetRequestHandler);
|
|
void InitFileStateCache();
|
|
void CreateQtApplication() override;
|
|
|
|
bool InitializeInternalBuilders();
|
|
void InitBuilderManager();
|
|
void ShutdownBuilderManager();
|
|
bool InitAssetDatabase();
|
|
void ShutDownAssetDatabase();
|
|
void InitAssetServerHandler();
|
|
void DestroyAssetServerHandler();
|
|
void InitFileProcessor();
|
|
void ShutDownFileProcessor();
|
|
virtual void InitSourceControl() = 0;
|
|
void InitInputThread();
|
|
void InputThread();
|
|
|
|
// Give an opportunity to derived classes to make connections before the application server starts listening
|
|
virtual void MakeActivationConnections() {}
|
|
virtual bool GetShouldExitOnIdle() const = 0;
|
|
virtual void TryScanProductDependencies() {}
|
|
virtual void TryHandleFileRelocation() {}
|
|
// IMPLEMENTATION OF -------------- AzToolsFramework::AssetDatabase::AssetDatabaseRequests::Bus::Listener
|
|
bool GetAssetDatabaseLocation(AZStd::string& location) override;
|
|
// ------------------------------------------------------------
|
|
|
|
AssetProcessor::AssetCatalog* GetAssetCatalog() const { return m_assetCatalog; }
|
|
|
|
ApplicationServer* m_applicationServer = nullptr;
|
|
ConnectionManager* m_connectionManager = nullptr;
|
|
|
|
// keep track of the critical loading point where we are loading other dlls so the error messages can be better.
|
|
bool m_isCurrentlyLoadingGems = false;
|
|
|
|
public Q_SLOTS:
|
|
void OnActiveJobsCountChanged(unsigned int count);
|
|
protected Q_SLOTS:
|
|
void CheckForIdle();
|
|
|
|
protected:
|
|
int m_processedAssetCount = 0;
|
|
int m_failedAssetsCount = 0;
|
|
int m_warningCount = 0;
|
|
int m_errorCount = 0;
|
|
bool m_AssetProcessorManagerIdleState = false;
|
|
bool m_sourceControlReady = false;
|
|
bool m_fullIdle = false;
|
|
|
|
FileWatcher m_fileWatcher;
|
|
AssetProcessor::PlatformConfiguration* m_platformConfiguration = nullptr;
|
|
AssetProcessor::AssetProcessorManager* m_assetProcessorManager = nullptr;
|
|
AssetProcessor::AssetCatalog* m_assetCatalog = nullptr;
|
|
AssetProcessor::AssetScanner* m_assetScanner = nullptr;
|
|
AssetProcessor::RCController* m_rcController = nullptr;
|
|
AssetProcessor::AssetRequestHandler* m_assetRequestHandler = nullptr;
|
|
AssetProcessor::BuilderManager* m_builderManager = nullptr;
|
|
AssetProcessor::AssetServerHandler* m_assetServerHandler = nullptr;
|
|
ControlRequestHandler* m_controlRequestHandler = nullptr;
|
|
|
|
AZStd::unique_ptr<AssetProcessor::FileStateBase> m_fileStateCache;
|
|
|
|
AZStd::unique_ptr<AssetProcessor::FileProcessor> m_fileProcessor;
|
|
|
|
AZStd::unique_ptr<AssetProcessor::BuilderConfigurationManager> m_builderConfig;
|
|
|
|
// The internal builders
|
|
AZStd::shared_ptr<AssetProcessor::InternalRecognizerBasedBuilder> m_internalBuilder;
|
|
AZStd::shared_ptr<AssetProcessor::SettingsRegistryBuilder> m_settingsRegistryBuilder;
|
|
|
|
bool m_builderRegistrationComplete = false;
|
|
|
|
// Builder description map based on the builder id
|
|
AZStd::unordered_map<AZ::Uuid, AssetBuilderSDK::AssetBuilderDesc> m_builderDescMap;
|
|
|
|
// Lookup for builder ids based on the name. The builder name must be unique
|
|
AZStd::unordered_map<AZStd::string, AZ::Uuid> m_builderNameToId;
|
|
|
|
// Builder pattern matchers to used to locate the builder descriptors that match a pattern
|
|
AZStd::list<AssetUtilities::BuilderFilePatternMatcher> m_matcherBuilderPatterns;
|
|
|
|
// Collection of all the external module builders
|
|
AZStd::list<AssetProcessor::ExternalModuleAssetBuilderInfo*> m_externalAssetBuilders;
|
|
|
|
AssetProcessor::ExternalModuleAssetBuilderInfo* m_currentExternalAssetBuilder = nullptr;
|
|
|
|
QAtomicInt m_connectionsAwaitingAssetCatalogSave = 0;
|
|
int m_remainingAPMJobs = 0;
|
|
bool m_assetProcessorManagerIsReady = false;
|
|
|
|
// When job priority and escalation is equal, jobs sort in order by job key.
|
|
// This switches that behavior to instead sort by the DB source name, which
|
|
// allows automated tests to get deterministic behavior out of Asset Processor.
|
|
bool m_sortJobsByDBSourceName = false;
|
|
|
|
unsigned int m_highestConnId = 0;
|
|
AzToolsFramework::Ticker* m_ticker = nullptr; // for ticking the tickbus.
|
|
|
|
QList<QMetaObject::Connection> m_connectionsToRemoveOnShutdown;
|
|
QString m_dependencyScanPattern;
|
|
QString m_fileDependencyScanPattern;
|
|
AZStd::vector<AZStd::string> m_dependencyAddtionalScanFolders;
|
|
int m_dependencyScanMaxIteration = AssetProcessor::MissingDependencyScanner::DefaultMaxScanIteration; // The maximum number of times to recurse when scanning a file for missing dependencies.
|
|
};
|