ScriptCanvasTestUtilities.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  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. #pragma once
  9. #include <AzTest/AzTest.h>
  10. #include <Editor/Framework/ScriptCanvasReporter.h>
  11. #include <Editor/Framework/ScriptCanvasTraceUtilities.h>
  12. #include <Framework/ScriptCanvasTestNodes.h>
  13. #include <ScriptCanvas/Core/Nodeable.h>
  14. #include <AzFramework/Entity/SliceEntityOwnershipServiceBus.h>
  15. #include "AzFramework/Slice/SliceInstantiationTicket.h"
  16. namespace ScriptCanvasTests
  17. {
  18. extern const char* k_tempCoreAssetDir;
  19. extern const char* k_tempCoreAssetName;
  20. extern const char* k_tempCoreAssetPath;
  21. const char* GetUnitTestDirPathRelative();
  22. void ExpectParse(AZStd::string_view graphPath);
  23. void ExpectParseError(AZStd::string_view graphPath);
  24. AZStd::string_view GetGraphNameFromPath(AZStd::string_view graphPath);
  25. void RunUnitTestGraph(AZStd::string_view graphPath);
  26. void RunUnitTestGraph(AZStd::string_view graphPath, ScriptCanvas::ExecutionMode execution);
  27. void RunUnitTestGraph(AZStd::string_view graphPath, ScriptCanvas::ExecutionMode execution, const ScriptCanvasEditor::DurationSpec& duration);
  28. void RunUnitTestGraph(AZStd::string_view graphPath, ScriptCanvas::ExecutionMode execution, AZStd::string_view dependentScriptEvent);
  29. void RunUnitTestGraph(AZStd::string_view graphPath, const ScriptCanvasEditor::DurationSpec& duration);
  30. void RunUnitTestGraph(AZStd::string_view graphPath, const ScriptCanvasEditor::RunSpec& runSpec);
  31. void RunUnitTestGraphMixed(AZStd::string_view graphPath, const ScriptCanvasEditor::DurationSpec& duration);
  32. void RunUnitTestGraphMixed(AZStd::string_view graphPath);
  33. void VerifyReporter(const ScriptCanvasEditor::Reporter& reporter);
  34. template<typename t_NodeType>
  35. t_NodeType* GetTestNode([[maybe_unused]] const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const AZ::EntityId& nodeID)
  36. {
  37. using namespace ScriptCanvas;
  38. t_NodeType* node{};
  39. ScriptCanvas::SystemRequestBus::BroadcastResult(node, &ScriptCanvas::SystemRequests::GetNode<t_NodeType>, nodeID);
  40. EXPECT_TRUE(node != nullptr);
  41. return node;
  42. }
  43. template<typename t_NodeType>
  44. t_NodeType* CreateTestNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, AZ::EntityId& entityOut)
  45. {
  46. using namespace ScriptCanvas;
  47. AZ::Entity* entity{ aznew AZ::Entity };
  48. entity->Init();
  49. entityOut = entity->GetId();
  50. EXPECT_TRUE(entityOut.IsValid());
  51. ScriptCanvas::SystemRequestBus::Broadcast(&ScriptCanvas::SystemRequests::CreateNodeOnEntity, entityOut, scriptCanvasId, azrtti_typeid<t_NodeType>());
  52. return GetTestNode<t_NodeType>(scriptCanvasId, entityOut);
  53. }
  54. template<typename t_Value>
  55. ScriptCanvas::VariableId CreateVariable(ScriptCanvas::ScriptCanvasId scriptCanvasId, const t_Value& value, AZStd::string_view variableName)
  56. {
  57. using namespace ScriptCanvas;
  58. AZ::Outcome<VariableId, AZStd::string> addVariableOutcome = AZ::Failure(AZStd::string());
  59. GraphVariableManagerRequestBus::EventResult(addVariableOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, variableName, Datum(value), false);
  60. if (!addVariableOutcome)
  61. {
  62. AZ_Warning("Script Canvas Test", false, "%s", addVariableOutcome.GetError().data());
  63. return {};
  64. }
  65. return addVariableOutcome.TakeValue();
  66. }
  67. AZ::EntityId CreateClassFunctionNode(const ScriptCanvas::ScriptCanvasId& scriptCanvasId, AZStd::string_view className, AZStd::string_view methodName);
  68. AZStd::string SlotDescriptorToString(ScriptCanvas::SlotDescriptor type);
  69. void DumpSlots(const ScriptCanvas::Node& node);
  70. bool Connect(ScriptCanvas::Graph& graph, const AZ::EntityId& fromNodeID, const char* fromSlotName, const AZ::EntityId& toNodeID, const char* toSlotName, bool dumpSlotsOnFailure = true);
  71. class UnitTestEvents
  72. : public AZ::EBusTraits
  73. {
  74. public:
  75. virtual void Failed(AZStd::string description) = 0;
  76. virtual AZStd::string Result(AZStd::string description) = 0;
  77. virtual void SideEffect(AZStd::string description) = 0;
  78. virtual void Succeeded(AZStd::string description) = 0;
  79. };
  80. using UnitTestEventsBus = AZ::EBus<UnitTestEvents>;
  81. class UnitTestEventsHandler
  82. : public UnitTestEventsBus::Handler
  83. {
  84. public:
  85. ~UnitTestEventsHandler()
  86. {
  87. Clear();
  88. }
  89. void Clear()
  90. {
  91. for (auto iter : m_failures)
  92. {
  93. ADD_FAILURE() << iter.first.c_str();
  94. }
  95. for (auto iter : m_successes)
  96. {
  97. GTEST_SUCCEED();
  98. }
  99. m_failures.clear();
  100. m_results.clear();
  101. m_successes.clear();
  102. m_results.clear();
  103. }
  104. void Failed(AZStd::string description) override
  105. {
  106. auto iter = m_failures.find(description);
  107. if (iter != m_failures.end())
  108. {
  109. ++iter->second;
  110. }
  111. else
  112. {
  113. m_failures.insert(AZStd::make_pair(description, 1));
  114. }
  115. }
  116. int FailureCount(AZStd::string_view description) const
  117. {
  118. auto iter = m_failures.find(description);
  119. return iter != m_failures.end() ? iter->second : 0;
  120. }
  121. bool IsFailed() const
  122. {
  123. return !m_failures.empty();
  124. }
  125. bool IsSucceeded() const
  126. {
  127. return !m_successes.empty();
  128. }
  129. void SideEffect(AZStd::string description) override
  130. {
  131. auto iter = m_sideEffects.find(description);
  132. if (iter != m_sideEffects.end())
  133. {
  134. ++iter->second;
  135. }
  136. else
  137. {
  138. m_sideEffects.insert(AZStd::make_pair(description, 1));
  139. }
  140. }
  141. int SideEffectCount() const
  142. {
  143. int count(0);
  144. for (auto iter : m_sideEffects)
  145. {
  146. count += iter.second;
  147. }
  148. return count;
  149. }
  150. int SideEffectCount(AZStd::string_view description) const
  151. {
  152. auto iter = m_sideEffects.find(description);
  153. return iter != m_sideEffects.end() ? iter->second : 0;
  154. }
  155. void Succeeded(AZStd::string description) override
  156. {
  157. auto iter = m_successes.find(description);
  158. if (iter != m_successes.end())
  159. {
  160. ++iter->second;
  161. }
  162. else
  163. {
  164. m_successes.insert(AZStd::make_pair(description, 1));
  165. }
  166. }
  167. int SuccessCount(AZStd::string_view description) const
  168. {
  169. auto iter = m_successes.find(description);
  170. return iter != m_successes.end() ? iter->second : 0;
  171. }
  172. AZStd::string Result(AZStd::string description) override
  173. {
  174. auto iter = m_results.find(description);
  175. if (iter != m_results.end())
  176. {
  177. ++iter->second;
  178. }
  179. else
  180. {
  181. m_results.insert(AZStd::make_pair(description, 1));
  182. }
  183. return description;
  184. }
  185. int ResultCount(AZStd::string_view description) const
  186. {
  187. auto iter = m_results.find(description);
  188. return iter != m_results.end() ? iter->second : 0;
  189. }
  190. private:
  191. AZStd::unordered_map<AZStd::string, int> m_failures;
  192. AZStd::unordered_map<AZStd::string, int> m_sideEffects;
  193. AZStd::unordered_map<AZStd::string, int> m_successes;
  194. AZStd::unordered_map<AZStd::string, int> m_results;
  195. };
  196. struct TestBehaviorContextProperties
  197. {
  198. AZ_TYPE_INFO(TestBehaviorContextProperties, "{13ECCA93-9A62-4A46-846C-ABFEEA215C48}");
  199. static void Reflect(AZ::ReflectContext* reflectContext)
  200. {
  201. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
  202. {
  203. serializeContext->Class<TestBehaviorContextProperties>()
  204. ->Version(0)
  205. ;
  206. }
  207. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
  208. {
  209. behaviorContext->Class<TestBehaviorContextProperties>("TestBehaviorContextProperties")
  210. ->Property("boolean", BehaviorValueGetter(&TestBehaviorContextProperties::m_booleanProp), BehaviorValueSetter(&TestBehaviorContextProperties::m_booleanProp))
  211. ->Property("number", BehaviorValueGetter(&TestBehaviorContextProperties::m_numberProp), BehaviorValueSetter(&TestBehaviorContextProperties::m_numberProp))
  212. ->Property("string", BehaviorValueGetter(&TestBehaviorContextProperties::m_stringProp), BehaviorValueSetter(&TestBehaviorContextProperties::m_stringProp))
  213. ->Property("getterOnlyNumber", BehaviorValueGetter(&TestBehaviorContextProperties::m_getterOnlyProp), nullptr)
  214. ->Property("setterOnlyNumber", nullptr, BehaviorValueSetter(&TestBehaviorContextProperties::m_setterOnlyProp))
  215. ;
  216. }
  217. }
  218. ScriptCanvas::Data::BooleanType m_booleanProp = false;
  219. ScriptCanvas::Data::NumberType m_numberProp = 0.0f;
  220. ScriptCanvas::Data::StringType m_stringProp;
  221. ScriptCanvas::Data::NumberType m_getterOnlyProp = 0.0f;
  222. ScriptCanvas::Data::NumberType m_setterOnlyProp = 0.0f;
  223. };
  224. class TestBehaviorContextObject
  225. {
  226. public:
  227. AZ_TYPE_INFO(TestBehaviorContextObject, "{52DA0875-8EF6-4D39-9CF6-9F83BAA59A1D}");
  228. static TestBehaviorContextObject MaxReturnByValue(TestBehaviorContextObject lhs, TestBehaviorContextObject rhs);
  229. static const TestBehaviorContextObject* MaxReturnByPointer(const TestBehaviorContextObject* lhs, const TestBehaviorContextObject* rhs);
  230. static const TestBehaviorContextObject& MaxReturnByReference(const TestBehaviorContextObject& lhs, const TestBehaviorContextObject& rhs);
  231. static int MaxReturnByValueInteger(int lhs, int rhs);
  232. static const int* MaxReturnByPointerInteger(const int* lhs, const int* rhs);
  233. static const int& MaxReturnByReferenceInteger(const int& lhs, const int& rhs);
  234. static void Reflect(AZ::ReflectContext* reflectContext);
  235. static AZ::u32 GetCreatedCount() { return s_createdCount; }
  236. static AZ::u32 GetDestroyedCount() { return s_destroyedCount; }
  237. static void ResetCounts() { s_createdCount = s_destroyedCount = 0; }
  238. TestBehaviorContextObject()
  239. {
  240. ++s_createdCount;
  241. }
  242. TestBehaviorContextObject(const TestBehaviorContextObject& src)
  243. : m_value(src.m_value)
  244. {
  245. ++s_createdCount;
  246. }
  247. TestBehaviorContextObject(TestBehaviorContextObject&& src)
  248. : m_value(src.m_value)
  249. {
  250. ++s_createdCount;
  251. }
  252. TestBehaviorContextObject(int value)
  253. : m_value(value)
  254. {
  255. ++s_createdCount;
  256. }
  257. ~TestBehaviorContextObject()
  258. {
  259. [[maybe_unused]] AZ::u32 destroyedCount = ++s_destroyedCount;
  260. AZ_Assert(destroyedCount <= s_createdCount, "ScriptCanvas execution error");
  261. }
  262. TestBehaviorContextObject& operator=(const TestBehaviorContextObject& source)
  263. {
  264. m_value = source.m_value;
  265. return *this;
  266. }
  267. // make a to string
  268. int GetValue() const { return m_value; }
  269. void SetValue(int value) { m_value = value; }
  270. bool IsNormalized() const { return m_isNormalized; }
  271. void Normalize() { m_isNormalized = true; }
  272. void Denormalize() { m_isNormalized = false; }
  273. bool operator>(const TestBehaviorContextObject& other) const
  274. {
  275. return m_value > other.m_value;
  276. }
  277. bool operator>=(const TestBehaviorContextObject& other) const
  278. {
  279. return m_value >= other.m_value;
  280. }
  281. bool operator==(const TestBehaviorContextObject& other) const
  282. {
  283. return m_value == other.m_value;
  284. }
  285. bool operator!=(const TestBehaviorContextObject& other) const
  286. {
  287. return m_value != other.m_value;
  288. }
  289. bool operator<=(const TestBehaviorContextObject& other) const
  290. {
  291. return m_value <= other.m_value;
  292. }
  293. bool operator<(const TestBehaviorContextObject& other) const
  294. {
  295. return m_value < other.m_value;
  296. }
  297. private:
  298. int m_value = -1;
  299. bool m_isNormalized = false;
  300. static AZ::u32 s_createdCount;
  301. static AZ::u32 s_destroyedCount;
  302. };
  303. TestBehaviorContextObject MaxReturnByValue(TestBehaviorContextObject lhs, TestBehaviorContextObject rhs);
  304. const TestBehaviorContextObject* MaxReturnByPointer(const TestBehaviorContextObject* lhs, const TestBehaviorContextObject* rhs);
  305. const TestBehaviorContextObject& MaxReturnByReference(const TestBehaviorContextObject& lhs, const TestBehaviorContextObject& rhs);
  306. class EventTest
  307. : public AZ::ComponentBus
  308. {
  309. public:
  310. virtual void Event() = 0;
  311. virtual int Number(int number) = 0;
  312. virtual AZStd::tuple<int, int> Numbers(int number) = 0;
  313. virtual AZStd::string String(AZStd::string_view string) = 0;
  314. virtual TestBehaviorContextObject Object(const TestBehaviorContextObject& vector) = 0;
  315. };
  316. using EventTestBus = AZ::EBus<EventTest>;
  317. class EventTestHandler
  318. : public EventTestBus::Handler
  319. , public AZ::BehaviorEBusHandler
  320. {
  321. public:
  322. AZ_EBUS_BEHAVIOR_BINDER
  323. (EventTestHandler
  324. , "{29E7F7EE-0867-467A-8389-68B07C184109}"
  325. , AZ::SystemAllocator
  326. , Event
  327. , Number
  328. , Numbers
  329. , String
  330. , Object);
  331. static void Reflect(AZ::ReflectContext* context)
  332. {
  333. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  334. {
  335. serializeContext->Class<EventTestHandler>()
  336. ->Version(0)
  337. ;
  338. }
  339. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  340. {
  341. behaviorContext->EBus<EventTestBus>("EventTestHandler")
  342. ->Handler<EventTestHandler>()
  343. ;
  344. }
  345. }
  346. void Event() override
  347. {
  348. Call(FN_Event);
  349. }
  350. int Number(int input) override
  351. {
  352. int output;
  353. CallResult(output, FN_Number, input);
  354. return output;
  355. }
  356. AZStd::tuple<int, int> Numbers(int number) override
  357. {
  358. AZStd::tuple<int, int> result;
  359. CallResult(result, FN_Numbers, number);
  360. return result;
  361. }
  362. AZStd::string String(AZStd::string_view input) override
  363. {
  364. AZStd::string output;
  365. CallResult(output, FN_String, input);
  366. return output;
  367. }
  368. TestBehaviorContextObject Object(const TestBehaviorContextObject& input) override
  369. {
  370. TestBehaviorContextObject output;
  371. CallResult(output, FN_Object, input);
  372. return output;
  373. }
  374. }; // EventTestHandler
  375. class ConvertibleToString
  376. {
  377. public:
  378. AZ_TYPE_INFO(ConvertibleToString, "{DBF947E7-4097-4C5D-AF0D-E2DB311E8958}");
  379. static AZStd::string ConstCharPtrToString(const char* inputStr)
  380. {
  381. return AZStd::string_view(inputStr);
  382. }
  383. static AZStd::string StringViewToString(AZStd::string_view inputView)
  384. {
  385. return inputView;
  386. }
  387. static void Reflect(AZ::ReflectContext* context)
  388. {
  389. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  390. if (serializeContext)
  391. {
  392. serializeContext->Class<ConvertibleToString>()
  393. ->Version(0)
  394. ;
  395. }
  396. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  397. {
  398. behaviorContext->Class<ConvertibleToString>("ConvertibleToString")
  399. ->Method("ConstCharPtrToString", &ConvertibleToString::ConstCharPtrToString)
  400. ->Method("StringViewToString", &ConvertibleToString::StringViewToString)
  401. ;
  402. }
  403. }
  404. };
  405. class UnitTestEntityContext
  406. : public AzFramework::EntityIdContextQueryBus::MultiHandler
  407. , public AzFramework::EntityContextRequestBus::Handler
  408. , public AzFramework::SliceEntityOwnershipServiceRequestBus::Handler
  409. {
  410. public:
  411. AZ_CLASS_ALLOCATOR(UnitTestEntityContext, AZ::SystemAllocator);
  412. UnitTestEntityContext() { AzFramework::EntityContextRequestBus::Handler::BusConnect(GetOwningContextId()); }
  413. //// EntityIdContextQueryBus::MultiHandler
  414. // Returns a generate Uuid which represents the UnitTest EntityContext
  415. AzFramework::EntityContextId GetOwningContextId() override { return AzFramework::EntityContextId("{36591268-5CE9-4BC1-8277-0AB9AD528447}"); }
  416. ////
  417. //// AzFramework::SliceEntityOwnershipServiceRequests
  418. const AzFramework::RootSliceAsset& GetRootAsset() const override {
  419. static AzFramework::RootSliceAsset invalid;
  420. return invalid;
  421. }
  422. AZ::SliceComponent* GetRootSlice() override { return {}; }
  423. void SetIsDynamic(bool) override {}
  424. void CancelSliceInstantiation(const AzFramework::SliceInstantiationTicket&) override {}
  425. AzFramework::SliceInstantiationTicket GenerateSliceInstantiationTicket() override { return AzFramework::SliceInstantiationTicket(); }
  426. bool HandleRootEntityReloadedFromStream(AZ::Entity*, bool, [[maybe_unused]] AZ::SliceComponent::EntityIdToEntityIdMap* idRemapTable = nullptr) override
  427. {
  428. return false;
  429. }
  430. const AZ::SliceComponent::EntityIdToEntityIdMap& GetLoadedEntityIdMap() override { return m_unitTestEntityIdMap; }
  431. AZ::SliceComponent::SliceInstanceAddress CloneSliceInstance(AZ::SliceComponent::SliceInstanceAddress,
  432. AZ::SliceComponent::EntityIdToEntityIdMap&) override
  433. {
  434. return{};
  435. }
  436. AzFramework::SliceInstantiationTicket InstantiateSlice(const AZ::Data::Asset<AZ::Data::AssetData>&,
  437. [[maybe_unused]] const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper& customIdMapper = nullptr,
  438. [[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilter = nullptr) override
  439. {
  440. return AzFramework::SliceInstantiationTicket();
  441. }
  442. AZ::Data::AssetId CurrentlyInstantiatingSlice() override {
  443. return AZ::Data::AssetId();
  444. };
  445. AZ::Entity* CreateEntity(const char* name) override;
  446. void AddEntity(AZ::Entity* entity) override;
  447. void ActivateEntity(AZ::EntityId entityId) override;
  448. void DeactivateEntity(AZ::EntityId entityId) override;
  449. bool DestroyEntity(AZ::Entity* entity) override;
  450. bool DestroyEntityById(AZ::EntityId entityId) override;
  451. AZ::Entity* CloneEntity(const AZ::Entity& sourceEntity) override;
  452. void ResetContext() override;
  453. AZ::EntityId FindLoadedEntityIdMapping(const AZ::EntityId& staticId) const override;
  454. ////
  455. void AddEntity(AZ::EntityId entityId);
  456. void RemoveEntity(AZ::EntityId entityId);
  457. bool IsOwnedByThisContext(AZ::EntityId entityId) { return m_unitTestEntityIdMap.count(entityId) != 0; }
  458. AZ::SliceComponent::EntityIdToEntityIdMap m_unitTestEntityIdMap;
  459. };
  460. template<typename TBusIdType>
  461. class TemplateEventTest
  462. : public AZ::EBusTraits
  463. {
  464. public:
  465. static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
  466. using BusIdType = TBusIdType;
  467. virtual void GenericEvent() = 0;
  468. virtual AZStd::string UpdateNameEvent(AZStd::string_view) = 0;
  469. virtual AZ::Vector3 VectorCreatedEvent(const AZ::Vector3&) = 0;
  470. };
  471. template<typename TBusIdType>
  472. using TemplateEventTestBus = AZ::EBus<TemplateEventTest<TBusIdType>>;
  473. template<typename TBusIdType>
  474. class TemplateEventTestHandler
  475. : public TemplateEventTestBus<TBusIdType>::Handler
  476. , public AZ::BehaviorEBusHandler
  477. {
  478. public:
  479. AZ_EBUS_BEHAVIOR_BINDER_TEMPLATE(TemplateEventTestHandler, (TemplateEventTestHandler, "{AADA0906-C216-4D98-BD51-76BB0C2F7FAF}", TBusIdType), AZ::SystemAllocator
  480. , GenericEvent
  481. , UpdateNameEvent
  482. , VectorCreatedEvent
  483. );
  484. static void Reflect(AZ::ReflectContext* context)
  485. {
  486. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  487. {
  488. const AZStd::string ebusName(AZ::AzTypeInfo<TemplateEventTestHandler>::Name());
  489. behaviorContext->EBus<TemplateEventTestBus<TBusIdType>>(ebusName.data())
  490. ->template Handler<TemplateEventTestHandler>()
  491. ->Event("Update Name", &TemplateEventTestBus<TBusIdType>::Events::UpdateNameEvent)
  492. ;
  493. }
  494. }
  495. void GenericEvent() override
  496. {
  497. Call(FN_GenericEvent);
  498. }
  499. AZStd::string UpdateNameEvent(AZStd::string_view name) override
  500. {
  501. AZStd::string result;
  502. CallResult(result, FN_UpdateNameEvent, name);
  503. return result;
  504. }
  505. AZ::Vector3 VectorCreatedEvent(const AZ::Vector3& newVector) override
  506. {
  507. AZ::Vector3 result;
  508. CallResult(result, FN_VectorCreatedEvent, newVector);
  509. return result;
  510. }
  511. };
  512. class ScriptUnitTestEventHandler
  513. : public UnitTestEventsBus::Handler
  514. , public AZ::BehaviorEBusHandler
  515. {
  516. public:
  517. AZ_EBUS_BEHAVIOR_BINDER
  518. (ScriptUnitTestEventHandler
  519. , "{3FC89358-837D-43D5-8C4F-61B672A751B2}"
  520. , AZ::SystemAllocator
  521. , Failed
  522. , Result
  523. , SideEffect
  524. , Succeeded);
  525. static void Reflect(AZ::ReflectContext* context)
  526. {
  527. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  528. {
  529. serializeContext->Class<ScriptUnitTestEventHandler>()
  530. ->Version(0)
  531. ;
  532. }
  533. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  534. {
  535. behaviorContext->EBus<UnitTestEventsBus>("UnitTestEventsBus")
  536. ->Handler<ScriptUnitTestEventHandler>()
  537. ->Event("Failed", &UnitTestEventsBus::Events::Failed)
  538. ->Event("Result", &UnitTestEventsBus::Events::Result)
  539. ->Event("SideEffect", &UnitTestEventsBus::Events::SideEffect)
  540. ->Event("Succeeded", &UnitTestEventsBus::Events::Succeeded)
  541. ;
  542. }
  543. }
  544. void Failed(AZStd::string description) override
  545. {
  546. Call(FN_Failed, description);
  547. }
  548. AZStd::string Result(AZStd::string description) override
  549. {
  550. AZStd::string output;
  551. CallResult(output, FN_Result, description);
  552. return output;
  553. }
  554. void SideEffect(AZStd::string description) override
  555. {
  556. Call(FN_SideEffect, description);
  557. }
  558. void Succeeded(AZStd::string description) override
  559. {
  560. Call(FN_Succeeded, description);
  561. }
  562. }; // ScriptUnitTestEventHandler
  563. class ScriptUnitTestNodeNotificationHandler
  564. : private ScriptCanvas::NodeNotificationsBus::Handler
  565. {
  566. public:
  567. AZ_CLASS_ALLOCATOR(ScriptUnitTestNodeNotificationHandler, AZ::SystemAllocator);
  568. ScriptUnitTestNodeNotificationHandler(AZ::EntityId nodeId)
  569. {
  570. ScriptCanvas::NodeNotificationsBus::Handler::BusConnect(nodeId);
  571. }
  572. ~ScriptUnitTestNodeNotificationHandler()
  573. {
  574. ScriptCanvas::NodeNotificationsBus::Handler::BusDisconnect();
  575. }
  576. AZ::u32 GetSlotsAdded() const
  577. {
  578. return m_slotsAdded;
  579. }
  580. AZ::u32 GetSlotsRemoved() const
  581. {
  582. return m_slotsRemoved;
  583. }
  584. private:
  585. void OnSlotAdded([[maybe_unused]] const ScriptCanvas::SlotId& slotId) override
  586. {
  587. ++m_slotsAdded;
  588. }
  589. void OnSlotRemoved([[maybe_unused]] const ScriptCanvas::SlotId& slotId) override
  590. {
  591. ++m_slotsRemoved;
  592. }
  593. AZ::u32 m_slotsAdded = 0;
  594. AZ::u32 m_slotsRemoved = 0;
  595. };
  596. class TestNodeableObject
  597. : public ScriptCanvas::Nodeable
  598. {
  599. public:
  600. AZ_RTTI(TestNodeableObject, "{5FA6967F-AB4D-4077-91C9-1C2CE36733AF}", Nodeable);
  601. AZ_CLASS_ALLOCATOR(Nodeable, AZ::SystemAllocator);
  602. static void Reflect(AZ::ReflectContext* reflectContext)
  603. {
  604. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
  605. {
  606. serializeContext->Class<TestNodeableObject, Nodeable>();
  607. if (auto editContext = serializeContext->GetEditContext())
  608. {
  609. editContext->Class<TestNodeableObject>("TestNodeableObject", "")
  610. ;
  611. }
  612. }
  613. // reflect API for the node
  614. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
  615. {
  616. behaviorContext->Class<TestNodeableObject>("TestNodeableObject")
  617. ->Method("Branch", &TestNodeableObject::Branch)
  618. ;
  619. }
  620. }
  621. void Branch(bool condition)
  622. {
  623. if (condition)
  624. {
  625. ExecutionOut(AZ_CRC_CE("BranchTrue"), true, AZStd::string("called the true version!"));
  626. }
  627. else
  628. {
  629. ExecutionOut(AZ_CRC_CE("BranchFalse"), false, AZStd::string("called the false version!"), AZ::Vector3(1, 2, 3));
  630. }
  631. }
  632. bool IsActive() const override
  633. {
  634. return false;
  635. }
  636. };
  637. // Test class that's used to test inheritance with Script Canvas slots
  638. class TestBaseClass
  639. {
  640. public:
  641. AZ_RTTI(TestBaseClass, "{C1F80F17-BE3C-49B5-862D-3C41F04208E0}");
  642. TestBaseClass() = default;
  643. virtual ~TestBaseClass() = default;
  644. static void Reflect(AZ::ReflectContext* reflectContext)
  645. {
  646. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
  647. {
  648. serializeContext->Class<TestBaseClass>();
  649. if (auto editContext = serializeContext->GetEditContext())
  650. {
  651. editContext->Class<TestBaseClass>("TestBaseClass", "");
  652. }
  653. }
  654. // reflect API for the node
  655. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
  656. {
  657. behaviorContext->Class<TestBaseClass>("TestBaseClass");
  658. }
  659. }
  660. };
  661. // Test class that's used to test inheritance with Script Canvas slots
  662. class TestSubClass : public TestBaseClass
  663. {
  664. public:
  665. AZ_RTTI(TestSubClass, "{2ED5B680-F097-4044-B1C8-0977A0E3F027}", TestBaseClass);
  666. TestSubClass() = default;
  667. ~TestSubClass() override = default;
  668. static void Reflect(AZ::ReflectContext* reflectContext)
  669. {
  670. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
  671. {
  672. serializeContext->Class<TestSubClass, TestBaseClass>();
  673. if (auto editContext = serializeContext->GetEditContext())
  674. {
  675. editContext->Class<TestSubClass>("TestSubClass", "");
  676. }
  677. }
  678. // reflect API for the node
  679. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
  680. {
  681. behaviorContext->Class<TestSubClass>("TestSubClass");
  682. }
  683. }
  684. };
  685. } // namespace ScriptCanvasTests