2
0

ScriptEventsSystemEditorComponent.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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 "ScriptEventsSystemEditorComponent.h"
  9. #include <ScriptEvents/Internal/VersionedProperty.h>
  10. #include <AzToolsFramework/UI/PropertyEditor/GenericComboBoxCtrl.h>
  11. #include <ScriptEvents/ScriptEventDefinition.h>
  12. #include <ScriptEvents/ScriptEvent.h>
  13. #include <AzCore/Component/TickBus.h>
  14. #include <ScriptEvents/ScriptEventsBus.h>
  15. #include <ScriptEvents/ScriptEventSystem.h>
  16. #include <ScriptEvents/ScriptEvent.h>
  17. #if defined(SCRIPTEVENTS_EDITOR)
  18. AZ_DECLARE_BUDGET(AzToolsFramework);
  19. namespace ScriptEventsEditor
  20. {
  21. ////////////////////////////
  22. // ScriptEventAssetHandler
  23. ////////////////////////////
  24. ScriptEventAssetHandler::ScriptEventAssetHandler(const char* displayName, const char* group, const char* extension, const AZ::Uuid& componentTypeId, AZ::SerializeContext* serializeContext)
  25. : AzFramework::GenericAssetHandler<ScriptEvents::ScriptEventsAsset>(displayName, group, extension, componentTypeId, serializeContext)
  26. {
  27. }
  28. AZ::Data::AssetPtr ScriptEventAssetHandler::CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type)
  29. {
  30. if (type != azrtti_typeid<ScriptEvents::ScriptEventsAsset>())
  31. {
  32. return nullptr;
  33. }
  34. AZ::Data::AssetPtr assetPtr = AzFramework::GenericAssetHandler<ScriptEvents::ScriptEventsAsset>::CreateAsset(id, type);
  35. if (!AzToolsFramework::AssetEditor::AssetEditorValidationRequestBus::MultiHandler::BusIsConnectedId(id))
  36. {
  37. AzToolsFramework::AssetEditor::AssetEditorValidationRequestBus::MultiHandler::BusConnect(id);
  38. }
  39. return assetPtr;
  40. }
  41. void ScriptEventAssetHandler::InitAsset(const AZ::Data::Asset<AZ::Data::AssetData>& asset, bool loadStageSucceeded, bool isReload)
  42. {
  43. AssetHandler::InitAsset(asset, loadStageSucceeded, isReload);
  44. if (loadStageSucceeded && !isReload)
  45. {
  46. const ScriptEvents::ScriptEvent& definition = asset.GetAs<ScriptEvents::ScriptEventsAsset>()->m_definition;
  47. AZStd::intrusive_ptr<ScriptEvents::Internal::ScriptEventRegistration> scriptEvent;
  48. ScriptEvents::ScriptEventBus::BroadcastResult(scriptEvent, &ScriptEvents::ScriptEventRequests::RegisterScriptEvent, asset.GetId(), definition.GetVersion());
  49. }
  50. }
  51. AZ::Data::AssetHandler::LoadResult ScriptEventAssetHandler::LoadAssetData(
  52. const AZ::Data::Asset<AZ::Data::AssetData>& asset,
  53. AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
  54. const AZ::Data::AssetFilterCB& assetLoadFilterCB)
  55. {
  56. AZ::Data::AssetHandler::LoadResult loadedData = AzFramework::GenericAssetHandler<ScriptEvents::ScriptEventsAsset>::LoadAssetData(asset, stream, assetLoadFilterCB);
  57. if (loadedData == AZ::Data::AssetHandler::LoadResult::LoadComplete)
  58. {
  59. ScriptEvents::ScriptEventsAsset* assetData = asset.GetAs<ScriptEvents::ScriptEventsAsset>();
  60. if (assetData)
  61. {
  62. auto busIter = m_previousEbusNames.find(asset.GetId());
  63. bool registerBus = true;
  64. if (busIter != m_previousEbusNames.end())
  65. {
  66. if (busIter->second.m_version < assetData->m_definition.GetVersion())
  67. {
  68. ScriptEvents::Internal::Utils::DestroyScriptEventBehaviorEBus(busIter->second.m_previousName);
  69. m_previousEbusNames.erase(busIter);
  70. }
  71. else
  72. {
  73. registerBus = false;
  74. }
  75. }
  76. if (registerBus)
  77. {
  78. // LoadAssetData is being called from an Asset system thread,
  79. // we need to complete registering with the BehaviorContext in the main thread
  80. auto registerBusFn = [this, assetData, asset]()
  81. {
  82. if (ScriptEvents::Internal::Utils::ConstructAndRegisterScriptEventBehaviorEBus(assetData->m_definition))
  83. {
  84. PreviousNameSettings previousSettings;
  85. previousSettings.m_previousName = assetData->m_definition.GetName().c_str();
  86. previousSettings.m_version = assetData->m_definition.GetVersion();
  87. m_previousEbusNames[asset.GetId()] = previousSettings;
  88. }
  89. };
  90. AZ::TickBus::QueueFunction(registerBusFn);
  91. }
  92. }
  93. }
  94. return loadedData;
  95. }
  96. bool ScriptEventAssetHandler::SaveAssetData(const AZ::Data::Asset<AZ::Data::AssetData>& asset, AZ::IO::GenericStream* stream)
  97. {
  98. AZ_TracePrintf("ScriptEvent", "Trying to save Asset with ID: %s - SCRIPTEVENT", asset.Get()->GetId().ToString<AZStd::string>().c_str());
  99. // Attempt to Save the data to a temporary stream in order to see if any
  100. AZ::Outcome<bool, AZStd::string> outcome = AZ::Failure(AZStd::string::format("AssetEditorValidationRequests is not connected ID: %s", asset.Get()->GetId().ToString<AZStd::string>().c_str()));
  101. // Verify that the asset is in a valid state that can be saved.
  102. AzToolsFramework::AssetEditor::AssetEditorValidationRequestBus::EventResult(outcome, asset.Get()->GetId(), &AzToolsFramework::AssetEditor::AssetEditorValidationRequests::IsAssetDataValid, asset);
  103. if (!outcome.IsSuccess())
  104. {
  105. AZ_Error("Asset Editor", false, "%s", outcome.GetError().c_str());
  106. return false;
  107. }
  108. ScriptEvents::ScriptEventsAsset* assetData = asset.GetAs<ScriptEvents::ScriptEventsAsset>();
  109. AZ_Assert(assetData, "Asset is of the wrong type.");
  110. if (assetData && m_serializeContext)
  111. {
  112. return AZ::Utils::SaveObjectToStream<ScriptEvents::ScriptEventsAsset>(*stream,
  113. m_saveAsBinary ? AZ::ObjectStream::ST_BINARY : AZ::ObjectStream::ST_XML,
  114. assetData,
  115. m_serializeContext);
  116. }
  117. return false;
  118. }
  119. AZ::Outcome<bool, AZStd::string> ScriptEventAssetHandler::IsAssetDataValid(const AZ::Data::Asset<AZ::Data::AssetData>& asset)
  120. {
  121. ScriptEvents::ScriptEventsAsset* assetData = asset.GetAs<ScriptEvents::ScriptEventsAsset>();
  122. if (!assetData)
  123. {
  124. return AZ::Failure(AZStd::string::format("Unable to validate asset with id: %s it has not been registered with the Script Event system component.", asset.GetId().ToString<AZStd::string>().c_str()));
  125. }
  126. const ScriptEvents::ScriptEvent* definition = &assetData->m_definition;
  127. AZ_Assert(definition, "The AssetData should have a valid definition");
  128. return definition->Validate();
  129. }
  130. void ScriptEventAssetHandler::PreAssetSave(AZ::Data::Asset<AZ::Data::AssetData> asset)
  131. {
  132. ScriptEvents::ScriptEventsAsset* scriptEventAsset = asset.GetAs<ScriptEvents::ScriptEventsAsset>();
  133. scriptEventAsset->m_definition.IncreaseVersion();
  134. }
  135. void ScriptEventAssetHandler::BeforePropertyEdit(AzToolsFramework::InstanceDataNode* node, [[maybe_unused]] AZ::Data::Asset<AZ::Data::AssetData> asset)
  136. {
  137. ScriptEventData::VersionedProperty* property = nullptr;
  138. AzToolsFramework::InstanceDataNode* parent = node;
  139. while (parent)
  140. {
  141. if (parent->GetClassMetadata()->m_typeId == azrtti_typeid<ScriptEventData::VersionedProperty>())
  142. {
  143. property = static_cast<ScriptEventData::VersionedProperty*>(parent->GetInstance(0));
  144. break;
  145. }
  146. parent = parent->GetParent();
  147. }
  148. if (property)
  149. {
  150. property->OnPropertyChange();
  151. }
  152. }
  153. void ScriptEventEditorSystemComponent::Reflect(AZ::ReflectContext* context)
  154. {
  155. if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
  156. {
  157. serialize->Class<ScriptEventEditorSystemComponent, AZ::Component>()
  158. ->Version(3)
  159. ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector<AZ::Crc32>({ AZ_CRC_CE("AssetBuilder") }));
  160. ;
  161. }
  162. using namespace ScriptEvents;
  163. ScriptEventData::VersionedProperty::Reflect(context);
  164. Parameter::Reflect(context);
  165. Method::Reflect(context);
  166. ScriptEvent::Reflect(context);
  167. ScriptEventsAsset::Reflect(context);
  168. ScriptEventsAssetRef::Reflect(context);
  169. ScriptEventsAssetPtr::Reflect(context);
  170. }
  171. void ScriptEventEditorSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  172. {
  173. provided.push_back(AZ_CRC_CE("ScriptEventsService"));
  174. }
  175. void ScriptEventEditorSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  176. {
  177. incompatible.push_back(AZ_CRC_CE("ScriptEventsService"));
  178. }
  179. ////////////////////
  180. // SystemComponent
  181. ////////////////////
  182. void ScriptEventEditorSystemComponent::Activate()
  183. {
  184. using namespace ScriptEvents;
  185. ScriptEventsSystemComponentImpl* moduleConfiguration = nullptr;
  186. ScriptEventModuleConfigurationRequestBus::BroadcastResult(moduleConfiguration, &ScriptEventModuleConfigurationRequests::GetSystemComponentImpl);
  187. if (moduleConfiguration)
  188. {
  189. moduleConfiguration->RegisterAssetHandler();
  190. }
  191. AzToolsFramework::RegisterGenericComboBoxHandler<ScriptEventData::VersionedProperty>();
  192. }
  193. void ScriptEventEditorSystemComponent::Deactivate()
  194. {
  195. using namespace ScriptEvents;
  196. ScriptEventsSystemComponentImpl* moduleConfiguration = nullptr;
  197. ScriptEventModuleConfigurationRequestBus::BroadcastResult(moduleConfiguration, &ScriptEventModuleConfigurationRequests::GetSystemComponentImpl);
  198. if (moduleConfiguration)
  199. {
  200. moduleConfiguration->UnregisterAssetHandler();
  201. moduleConfiguration->CleanUp();
  202. }
  203. }
  204. }
  205. #endif