AssetBuilderInfo.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Component/ComponentApplicationBus.h>
  9. #include <AzCore/Component/Entity.h>
  10. #include <AssetBuilderInfo.h>
  11. #include <AssetBuilderApplication.h>
  12. namespace AssetBuilder
  13. {
  14. ExternalModuleAssetBuilderInfo::ExternalModuleAssetBuilderInfo(const QString& modulePath)
  15. : m_builderName(modulePath)
  16. , m_entity(nullptr)
  17. , m_componentDescriptorList()
  18. , m_initializeModuleFunction(nullptr)
  19. , m_moduleRegisterDescriptorsFunction(nullptr)
  20. , m_moduleAddComponentsFunction(nullptr)
  21. , m_uninitializeModuleFunction(nullptr)
  22. , m_modulePath(modulePath)
  23. , m_library(modulePath)
  24. {
  25. Load();
  26. }
  27. ExternalModuleAssetBuilderInfo::~ExternalModuleAssetBuilderInfo()
  28. {
  29. Unload();
  30. }
  31. const QString& ExternalModuleAssetBuilderInfo::GetName() const
  32. {
  33. return m_builderName;
  34. }
  35. //! Sanity check for the module's status
  36. bool ExternalModuleAssetBuilderInfo::IsLoaded() const
  37. {
  38. return m_library.isLoaded();
  39. }
  40. void ExternalModuleAssetBuilderInfo::Initialize()
  41. {
  42. AZ_Error("AssetBuilder", IsLoaded(), "External module %s not loaded.", m_builderName.toUtf8().data());
  43. m_initializeModuleFunction(AZ::Environment::GetInstance());
  44. m_moduleRegisterDescriptorsFunction();
  45. AZStd::string entityName = AZStd::string::format("%s Entity", GetName().toUtf8().data());
  46. m_entity = aznew AZ::Entity(entityName.c_str());
  47. m_moduleAddComponentsFunction(m_entity);
  48. AZ_TracePrintf("AssetBuilder", "Init Entity %s\n", GetName().toUtf8().data());
  49. m_entity->Init();
  50. //Activate all the components
  51. m_entity->Activate();
  52. }
  53. void ExternalModuleAssetBuilderInfo::UnInitialize()
  54. {
  55. AZ_Error("AssetBuilder", IsLoaded(), "External module %s not loaded.", m_builderName.toUtf8().data());
  56. AZ_TracePrintf("AssetBuilder", "Uninitializing builder: %s\n", m_modulePath.toUtf8().data());
  57. if (m_entity)
  58. {
  59. m_entity->Deactivate();
  60. delete m_entity;
  61. m_entity = nullptr;
  62. }
  63. for (AZ::ComponentDescriptor* componentDesc : m_componentDescriptorList)
  64. {
  65. AZ::ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationRequests::UnregisterComponentDescriptor, componentDesc);
  66. componentDesc->ReleaseDescriptor(); // this kills the descriptor.
  67. }
  68. m_componentDescriptorList.clear();
  69. m_registeredBuilderDescriptorIDs.clear();
  70. m_uninitializeModuleFunction();
  71. }
  72. AssetBuilderType ExternalModuleAssetBuilderInfo::GetAssetBuilderType()
  73. {
  74. QStringList missingFunctionsList;
  75. ResolveModuleFunction<QFunctionPointer>("IsAssetBuilder", missingFunctionsList);
  76. InitializeModuleFunction initializeModuleAddress = ResolveModuleFunction<InitializeModuleFunction>("InitializeModule", missingFunctionsList);
  77. ModuleRegisterDescriptorsFunction moduleRegisterDescriptorsAddress = ResolveModuleFunction<ModuleRegisterDescriptorsFunction>("ModuleRegisterDescriptors", missingFunctionsList);
  78. ModuleAddComponentsFunction moduleAddComponentsAddress = ResolveModuleFunction<ModuleAddComponentsFunction>("ModuleAddComponents", missingFunctionsList);
  79. UninitializeModuleFunction uninitializeModuleAddress = ResolveModuleFunction<UninitializeModuleFunction>("UninitializeModule", missingFunctionsList);
  80. if (missingFunctionsList.empty())
  81. {
  82. // a valid builder
  83. m_initializeModuleFunction = initializeModuleAddress;
  84. m_moduleRegisterDescriptorsFunction = moduleRegisterDescriptorsAddress;
  85. m_moduleAddComponentsFunction = moduleAddComponentsAddress;
  86. m_uninitializeModuleFunction = uninitializeModuleAddress;
  87. return AssetBuilderType::Valid;
  88. }
  89. else if (missingFunctionsList.size() > 0 && missingFunctionsList.contains("IsAssetBuilder"))
  90. {
  91. // This DLL is not a builder and should be ignored.
  92. return AssetBuilderType::None;
  93. }
  94. else
  95. {
  96. // This is supposed to be a builder but is invalid
  97. QString errorMessage = QString("Builder library %1 is missing one or more exported functions: %2").arg(QString(GetName()), missingFunctionsList.join(','));
  98. AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "One or more builder functions is missing in the library: %s\n", errorMessage.toUtf8().data());
  99. return AssetBuilderType::Invalid;
  100. }
  101. }
  102. AssetBuilderType ExternalModuleAssetBuilderInfo::Load()
  103. {
  104. if (IsLoaded())
  105. {
  106. AZ_Warning("AssetBuilder", false, "External module %s already loaded.", m_builderName.toUtf8().data());
  107. return AssetBuilderType::None;
  108. }
  109. m_library.setFileName(m_modulePath);
  110. if (!m_library.load())
  111. {
  112. AZ_TracePrintf("AssetBuilder", "Unable to load builder : %s\n", GetName().toUtf8().data());
  113. return AssetBuilderType::Invalid;
  114. }
  115. return GetAssetBuilderType();
  116. }
  117. void ExternalModuleAssetBuilderInfo::Unload()
  118. {
  119. if (IsLoaded())
  120. {
  121. m_library.unload();
  122. }
  123. m_initializeModuleFunction = nullptr;
  124. m_moduleRegisterDescriptorsFunction = nullptr;
  125. m_moduleAddComponentsFunction = nullptr;
  126. m_uninitializeModuleFunction = nullptr;
  127. }
  128. void ExternalModuleAssetBuilderInfo::RegisterBuilderDesc(const AZ::Uuid& builderDescID)
  129. {
  130. if (m_registeredBuilderDescriptorIDs.find(builderDescID) != m_registeredBuilderDescriptorIDs.end())
  131. {
  132. AZ_Warning(AssetBuilderSDK::InfoWindow,
  133. false,
  134. "Builder description id '%s' already registered to external builder module %s",
  135. builderDescID.ToString<AZStd::string>().c_str(),
  136. m_builderName.toUtf8().data());
  137. return;
  138. }
  139. m_registeredBuilderDescriptorIDs.insert(builderDescID);
  140. }
  141. void ExternalModuleAssetBuilderInfo::RegisterComponentDesc(AZ::ComponentDescriptor* descriptor)
  142. {
  143. m_componentDescriptorList.push_back(descriptor);
  144. AZ::ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationRequests::RegisterComponentDescriptor, descriptor);
  145. }
  146. template<typename T>
  147. T ExternalModuleAssetBuilderInfo::ResolveModuleFunction(const char* functionName, QStringList& missingFunctionsList)
  148. {
  149. T functionAddr = reinterpret_cast<T>(m_library.resolve(functionName));
  150. if (!functionAddr)
  151. {
  152. missingFunctionsList.append(QString(functionName));
  153. }
  154. return functionAddr;
  155. }
  156. }