ReflectComponent.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  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 <AssetBuilderSDK/AssetBuilderSDK.h>
  9. #include <AzCore/Serialization/EditContext.h>
  10. #include <AzCore/Serialization/SerializeContext.h>
  11. #include <AzCore/std/ranges/elements_view.h>
  12. #include <Editor/Framework/Configuration.h>
  13. #include <Editor/Framework/Interpreter.h>
  14. #include <Editor/Include/ScriptCanvas/Components/EditorGraph.h>
  15. #include <Editor/ReflectComponent.h>
  16. #include <Editor/View/Dialogs/SettingsDialog.h>
  17. #include <Editor/View/Widgets/LoggingPanel/LiveWindowSession/LiveLoggingWindowSession.h>
  18. #include <Editor/View/Widgets/NodePalette/CreateNodeMimeEvent.h>
  19. #include <Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h>
  20. #include <Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.h>
  21. #include <Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h>
  22. #include <Editor/View/Widgets/NodePalette/ScriptEventsNodePaletteTreeItemTypes.h>
  23. #include <Editor/View/Widgets/NodePalette/SpecializedNodePaletteTreeItemTypes.h>
  24. #include <Editor/View/Widgets/NodePalette/VariableNodePaletteTreeItemTypes.h>
  25. #include <ScriptCanvas/Bus/UndoBus.h>
  26. #include <ScriptCanvas/Components/EditorDeprecationData.h>
  27. #include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
  28. #include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
  29. namespace CoreCpp
  30. {
  31. static bool ScriptCanvasDataVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootDataElementNode)
  32. {
  33. if (rootDataElementNode.GetVersion() == 0)
  34. {
  35. int scriptCanvasEntityIndex = rootDataElementNode.FindElement(AZ_CRC_CE("m_scriptCanvas"));
  36. if (scriptCanvasEntityIndex == -1)
  37. {
  38. AZ_Error("Script Canvas", false, "Version Converter failed, The Script Canvas Entity is missing");
  39. return false;
  40. }
  41. auto scComponentElements = AZ::Utils::FindDescendantElements(context, rootDataElementNode, AZStd::vector<AZ::Crc32>{AZ_CRC_CE("m_scriptCanvas"),
  42. AZ_CRC_CE("element"), AZ_CRC_CE("Components")});
  43. if (!scComponentElements.empty())
  44. {
  45. scComponentElements.front()->AddElementWithData(context, "element", ScriptCanvasEditor::EditorGraphVariableManagerComponent());
  46. }
  47. }
  48. if (rootDataElementNode.GetVersion() < 4)
  49. {
  50. auto scEntityElements = AZ::Utils::FindDescendantElements(context, rootDataElementNode,
  51. AZStd::vector<AZ::Crc32>{AZ_CRC_CE("m_scriptCanvas"), AZ_CRC_CE("element")});
  52. if (scEntityElements.empty())
  53. {
  54. AZ_Error("Script Canvas", false, "Version Converter failed, The Script Canvas Entity is missing");
  55. return false;
  56. }
  57. auto& scEntityDataElement = *scEntityElements.front();
  58. AZ::Entity scEntity;
  59. if (!scEntityDataElement.GetData(scEntity))
  60. {
  61. AZ_Error("Script Canvas", false, "Unable to retrieve entity data from the Data Element");
  62. return false;
  63. }
  64. auto graph = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Graph>(&scEntity);
  65. if (!graph)
  66. {
  67. AZ_Error("Script Canvas", false, "Script Canvas graph component could not be found on Script Canvas Entity for ScriptCanvasData version %u", rootDataElementNode.GetVersion());
  68. return false;
  69. }
  70. auto variableManager = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::GraphVariableManagerComponent>(&scEntity);
  71. if (!variableManager)
  72. {
  73. AZ_Error("Script Canvas", false, "Script Canvas variable manager component could not be found on Script Canvas Entity for ScriptCanvasData version %u", rootDataElementNode.GetVersion());
  74. return false;
  75. }
  76. variableManager->ConfigureScriptCanvasId(graph->GetScriptCanvasId());
  77. if (!scEntityDataElement.SetData(context, scEntity))
  78. {
  79. AZ_Error("Script Canvas", false, "Failed to set converted Script Canvas Entity back on data element node when transitioning from version %u to version 4", rootDataElementNode.GetVersion());
  80. return false;
  81. }
  82. }
  83. return true;
  84. }
  85. }
  86. namespace ScriptCanvas
  87. {
  88. void ScriptCanvasData::Reflect(AZ::ReflectContext* reflectContext)
  89. {
  90. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
  91. {
  92. serializeContext->Class<ScriptCanvasData>()
  93. ->Version(4, &CoreCpp::ScriptCanvasDataVersionConverter)
  94. ->Field("m_scriptCanvas", &ScriptCanvasData::m_scriptCanvasEntity)
  95. ;
  96. }
  97. }
  98. }
  99. namespace ScriptCanvasEditor
  100. {
  101. void ReflectComponent::Reflect(AZ::ReflectContext* context)
  102. {
  103. Configuration::Reflect(context);
  104. Interpreter::Reflect(context);
  105. ScriptCanvas::ScriptCanvasData::Reflect(context);
  106. Deprecated::ScriptCanvasAssetHolder::Reflect(context);
  107. EditorSettings::EditorWorkspace::Reflect(context);
  108. EditorSettings::ScriptCanvasEditorSettings::Reflect(context);
  109. LiveLoggingUserSettings::Reflect(context);
  110. UndoData::Reflect(context);
  111. // Base Mime Event
  112. CreateNodeMimeEvent::Reflect(context);
  113. SpecializedCreateNodeMimeEvent::Reflect(context);
  114. MultiCreateNodeMimeEvent::Reflect(context);
  115. // Specific Mime Event Implementations
  116. CreateClassMethodMimeEvent::Reflect(context);
  117. CreateGlobalMethodMimeEvent::Reflect(context);
  118. CreateNodeGroupMimeEvent::Reflect(context);
  119. CreateCommentNodeMimeEvent::Reflect(context);
  120. CreateCustomNodeMimeEvent::Reflect(context);
  121. CreateEBusHandlerMimeEvent::Reflect(context);
  122. CreateEBusHandlerEventMimeEvent::Reflect(context);
  123. CreateEBusSenderMimeEvent::Reflect(context);
  124. CreateGetVariableNodeMimeEvent::Reflect(context);
  125. CreateSetVariableNodeMimeEvent::Reflect(context);
  126. CreateVariableChangedNodeMimeEvent::Reflect(context);
  127. CreateVariableSpecificNodeMimeEvent::Reflect(context);
  128. CreateFunctionMimeEvent::Reflect(context);
  129. // Script Events
  130. CreateScriptEventsHandlerMimeEvent::Reflect(context);
  131. CreateScriptEventsReceiverMimeEvent::Reflect(context);
  132. CreateScriptEventsSenderMimeEvent::Reflect(context);
  133. CreateSendOrReceiveScriptEventsMimeEvent::Reflect(context);
  134. if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
  135. {
  136. serialize->Class<ReflectComponent, AZ::Component>()
  137. ->Version(0)
  138. ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector<AZ::Crc32>({ AssetBuilderSDK::ComponentTags::AssetBuilder }));
  139. ;
  140. if (AZ::EditContext* ec = serialize->GetEditContext())
  141. {
  142. ec->Class<ReflectComponent>("Script Canvas Reflections", "Script Canvas Reflect Component")
  143. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  144. ->Attribute(AZ::Edit::Attributes::Category, "Scripting")
  145. ;
  146. }
  147. }
  148. }
  149. void ReflectComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  150. {
  151. provided.push_back(AZ_CRC_CE("ScriptCanvasReflectService"));
  152. }
  153. void ReflectComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  154. {
  155. incompatible.push_back(AZ_CRC_CE("ScriptCanvasReflectService"));
  156. }
  157. void ReflectComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  158. {
  159. required.push_back(AZ_CRC_CE("ScriptCanvasService"));
  160. }
  161. void ReflectComponent::Activate()
  162. {
  163. ReflectEventTypes();
  164. }
  165. void ReflectComponent::Deactivate()
  166. {
  167. }
  168. void ReflectComponent::ReflectEventTypes()
  169. {
  170. AZ::BehaviorContext* behaviorContext{};
  171. AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationBus::Events::GetBehaviorContext);
  172. AZ_Assert(behaviorContext, "BehaviorContext is required to lookup methods returning AZ::Event");
  173. AZ::SerializeContext* serializeContext{};
  174. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
  175. AZ_Assert(serializeContext, "SerializeContext is required to register AZ::Event type");
  176. auto ReflectEventTypeOnDemand = [](AZ::SerializeContext* context, const AZ::BehaviorMethod& behaviorMethod) -> void
  177. {
  178. if (AZ::MethodReturnsAzEventByReferenceOrPointer(behaviorMethod))
  179. {
  180. const AZ::BehaviorParameter* resultParameter = behaviorMethod.GetResult();
  181. AZ::SerializeContext::ClassData classData;
  182. classData.m_name = resultParameter->m_name;
  183. classData.m_typeId = resultParameter->m_typeId;
  184. classData.m_azRtti = resultParameter->m_azRtti;
  185. auto EventPlaceholderAnyCreator = [](AZ::SerializeContext*) -> AZStd::any
  186. {
  187. return AZStd::make_any<AZStd::monostate>();
  188. };
  189. context->RegisterType(resultParameter->m_typeId, AZStd::move(classData), EventPlaceholderAnyCreator);
  190. }
  191. };
  192. // Behavior Context Global Methods
  193. for (auto behaviorMethod : AZStd::ranges::views::values(behaviorContext->m_methods))
  194. {
  195. if (behaviorMethod != nullptr)
  196. {
  197. ReflectEventTypeOnDemand(serializeContext, *behaviorMethod);
  198. }
  199. }
  200. // Behavior Context Global Properties
  201. for (auto behaviorProperty : AZStd::ranges::views::values(behaviorContext->m_properties))
  202. {
  203. // Only the getter can reflect a method that returns an AZ::Event& or AZ::Event*
  204. if (behaviorProperty != nullptr && behaviorProperty->m_getter != nullptr)
  205. {
  206. ReflectEventTypeOnDemand(serializeContext, *behaviorProperty->m_getter);
  207. }
  208. }
  209. // Behavior Context Class Methods
  210. // Behavior Context Getter Property Methods
  211. for (auto behaviorClass : AZStd::ranges::views::values(behaviorContext->m_classes))
  212. {
  213. if (behaviorClass != nullptr)
  214. {
  215. for (auto behaviorClassMethod : AZStd::ranges::views::values(behaviorClass->m_methods))
  216. {
  217. if (behaviorClassMethod != nullptr)
  218. {
  219. ReflectEventTypeOnDemand(serializeContext, *behaviorClassMethod);
  220. }
  221. }
  222. // Behavior Context Global Properties
  223. for (auto behaviorClassProperty : AZStd::ranges::views::values(behaviorClass->m_properties))
  224. {
  225. // Only the getter can reflect a method that returns an AZ::Event& or AZ::Event*
  226. if (behaviorClassProperty != nullptr && behaviorClassProperty->m_getter != nullptr)
  227. {
  228. ReflectEventTypeOnDemand(serializeContext, *behaviorClassProperty->m_getter);
  229. }
  230. }
  231. }
  232. }
  233. // Behavior Context EBus event sender
  234. for (auto behaviorEbus : AZStd::ranges::views::values(behaviorContext->m_ebuses))
  235. {
  236. if (behaviorEbus != nullptr)
  237. {
  238. for (auto behaviorEventSender : AZStd::ranges::views::values(behaviorEbus->m_events))
  239. {
  240. // An event sender has the same signature for all of its functions and it's guaranteed
  241. // that it will have a valid m_broadcast.
  242. // So use that to reflect the any EBus event that returns an AZ Event pointer or reference
  243. if (behaviorEventSender.m_broadcast != nullptr)
  244. {
  245. ReflectEventTypeOnDemand(serializeContext, *behaviorEventSender.m_broadcast);
  246. }
  247. }
  248. }
  249. }
  250. }
  251. }