123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- /*
- * 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
- *
- */
- #include <native/utilities/AssetBuilderInfo.h>
- #include <AzCore/Component/Entity.h>
- namespace AssetProcessor
- {
- #ifdef AZ_PLATFORM_WINDOWS
- const char* const s_assetBuilderRelativePath = "AssetBuilder.exe";
- #else
- const char* const s_assetBuilderRelativePath = "AssetBuilder";
- #endif
- ExternalModuleAssetBuilderInfo::ExternalModuleAssetBuilderInfo(const QString& modulePath)
- : m_builderName(modulePath)
- , m_entity(nullptr)
- , m_componentDescriptorList()
- , m_initializeModuleFunction(nullptr)
- , m_moduleRegisterDescriptorsFunction(nullptr)
- , m_moduleAddComponentsFunction(nullptr)
- , m_uninitializeModuleFunction(nullptr)
- , m_library(modulePath)
- {
- }
- const QString& ExternalModuleAssetBuilderInfo::GetName() const
- {
- return m_builderName;
- }
- QString ExternalModuleAssetBuilderInfo::GetModuleFullPath() const
- {
- return m_library.fileName();
- }
- //! Sanity check for the module's status
- bool ExternalModuleAssetBuilderInfo::IsLoaded() const
- {
- return m_library.isLoaded();
- }
- void ExternalModuleAssetBuilderInfo::Initialize()
- {
- AZ_Error(AssetProcessor::ConsoleChannel, IsLoaded(), "External module %s not loaded.", GetName().toUtf8().data());
- if (GetAssetBuilderType() == AssetBuilderType::Valid)
- {
- m_initializeModuleFunction(AZ::Environment::GetInstance());
- m_moduleRegisterDescriptorsFunction();
- AZStd::string entityName = AZStd::string::format("%s Entity", GetName().toUtf8().data());
- m_entity = aznew AZ::Entity(entityName.c_str());
- m_moduleAddComponentsFunction(m_entity);
- AZ_TracePrintf(AssetProcessor::DebugChannel, "Init Entity %s", GetName().toUtf8().data());
- m_entity->Init();
- //Activate all the components
- m_entity->Activate();
- }
- }
- void ExternalModuleAssetBuilderInfo::UnInitialize()
- {
- AZ_Error(AssetProcessor::ConsoleChannel, IsLoaded(), "External module %s not loaded.", GetName().toUtf8().data());
- AZ_TracePrintf(AssetProcessor::DebugChannel, "Uninitializing builder: %s\n", GetModuleFullPath().toUtf8().data());
- if (m_entity)
- {
- m_entity->Deactivate();
- delete m_entity;
- m_entity = nullptr;
- }
- for (AZ::ComponentDescriptor* componentDesc : m_componentDescriptorList)
- {
- componentDesc->ReleaseDescriptor();
- }
- m_componentDescriptorList.clear();
- for (const AZ::Uuid& builderDescID : m_registeredBuilderDescriptorIDs)
- {
- AssetBuilderRegistrationBus::Broadcast(&AssetBuilderRegistrationBusTraits::UnRegisterBuilderDescriptor, builderDescID);
- }
- m_registeredBuilderDescriptorIDs.clear();
- m_uninitializeModuleFunction();
- if (IsLoaded())
- {
- m_library.unload();
- }
- }
- AssetBuilderType ExternalModuleAssetBuilderInfo::GetAssetBuilderType()
- {
- QStringList missingFunctionsList;
- ResolveModuleFunction<QFunctionPointer>("IsAssetBuilder", missingFunctionsList);
- InitializeModuleFunction initializeModuleAddress = ResolveModuleFunction<InitializeModuleFunction>("InitializeModule", missingFunctionsList);
- ModuleRegisterDescriptorsFunction moduleRegisterDescriptorsAddress = ResolveModuleFunction<ModuleRegisterDescriptorsFunction>("ModuleRegisterDescriptors", missingFunctionsList);
- ModuleAddComponentsFunction moduleAddComponentsAddress = ResolveModuleFunction<ModuleAddComponentsFunction>("ModuleAddComponents", missingFunctionsList);
- UninitializeModuleFunction uninitializeModuleAddress = ResolveModuleFunction<UninitializeModuleFunction>("UninitializeModule", missingFunctionsList);
- if (missingFunctionsList.size() == 0)
- {
- //if we are here then it is a builder
- m_initializeModuleFunction = initializeModuleAddress;
- m_moduleRegisterDescriptorsFunction = moduleRegisterDescriptorsAddress;
- m_moduleAddComponentsFunction = moduleAddComponentsAddress;
- m_uninitializeModuleFunction = uninitializeModuleAddress;
- return AssetBuilderType::Valid;
- }
- else if (missingFunctionsList.size() > 0 && missingFunctionsList.contains("IsAssetBuilder"))
- {
- // This DLL is not a builder and should be ignored.
- return AssetBuilderType::None;
- }
- else
- {
- // This is supposed to be a builder but is invalid
- QString errorMessage = QString("Builder library %1 is missing one or more exported functions: %2").arg(QString(GetName()), missingFunctionsList.join(','));
- AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "One or more builder functions is missing in the library: %s\n", errorMessage.toUtf8().data());
- return AssetBuilderType::Invalid;
- }
- }
- AssetBuilderType ExternalModuleAssetBuilderInfo::Load()
- {
- if (IsLoaded())
- {
- // This builder is already loaded - ignore the duplicate
- AZ_Warning(AssetProcessor::ConsoleChannel, false, "External module %s already loaded.", GetName().toUtf8().data());
- return AssetBuilderType::None;
- }
- if (!m_library.load())
- {
- // Invalid builder - unable to load
- AZ_TracePrintf(AssetProcessor::DebugChannel, "Unable to load builder : %s\n", GetName().toUtf8().data());
- return AssetBuilderType::Invalid;
- }
- return GetAssetBuilderType();
- }
- void ExternalModuleAssetBuilderInfo::RegisterBuilderDesc(const AZ::Uuid& builderDescID)
- {
- if (m_registeredBuilderDescriptorIDs.find(builderDescID) != m_registeredBuilderDescriptorIDs.end())
- {
- AZ_Warning(AssetBuilderSDK::InfoWindow,
- false,
- "Builder description id '%s' already registered to external builder module %s",
- builderDescID.ToString<AZStd::string>().c_str(),
- GetName().toUtf8().data());
- return;
- }
- m_registeredBuilderDescriptorIDs.insert(builderDescID);
- }
- void ExternalModuleAssetBuilderInfo::RegisterComponentDesc(AZ::ComponentDescriptor* descriptor)
- {
- m_componentDescriptorList.push_back(descriptor);
- }
- template<typename T>
- T ExternalModuleAssetBuilderInfo::ResolveModuleFunction(const char* functionName, QStringList& missingFunctionsList)
- {
- T functionAddr = reinterpret_cast<T>(m_library.resolve(functionName));
- if (!functionAddr)
- {
- missingFunctionsList.append(QString(functionName));
- }
- return functionAddr;
- }
- }
|