ScriptCanvas_VM.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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/EBus/EBus.h>
  9. #include <AzCore/Math/MathReflection.h>
  10. #include <AzCore/RTTI/BehaviorContext.h>
  11. #include <AzCore/Serialization/SerializeContext.h>
  12. #include <ScriptCanvas/Core/EBusHandler.h>
  13. #include <ScriptCanvas/Core/SubgraphInterfaceUtility.h>
  14. #include <ScriptCanvas/Core/Nodeable.h>
  15. #include <ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h>
  16. #include <Source/Framework/ScriptCanvasTestFixture.h>
  17. #include <Source/Framework/ScriptCanvasTestNodes.h>
  18. #include <Source/Framework/ScriptCanvasTestUtilities.h>
  19. #include <Source/ScriptCanvasTestBus.h>
  20. #include <ScriptCanvas/Translation/GraphToLuaUtility.h>
  21. using namespace ScriptCanvas;
  22. using namespace ScriptCanvasTests;
  23. using namespace TestNodes;
  24. using namespace ScriptCanvas::Execution;
  25. class Grandparent
  26. {
  27. public:
  28. AZ_RTTI(Grandparent, "{76EF13EE-7F5E-41C8-A789-A86836D66D10}");
  29. AZ_CLASS_ALLOCATOR(Grandparent, AZ::SystemAllocator);
  30. virtual ~Grandparent() = default;
  31. static void Reflect(AZ::ReflectContext* reflectContext)
  32. {
  33. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
  34. {
  35. serializeContext->Class<Grandparent>();
  36. }
  37. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
  38. {
  39. behaviorContext->Class<Grandparent>("Grandparent")
  40. ->Method("GetGeneration", &Grandparent::GetGeneration);
  41. ;
  42. }
  43. }
  44. virtual int GetGeneration() const
  45. {
  46. return 1;
  47. }
  48. };
  49. class Parent
  50. : public Grandparent
  51. {
  52. public:
  53. AZ_RTTI(Parent, "{2ABA91B7-24F7-495A-ACC6-4F93DE47B507}", Grandparent);
  54. AZ_CLASS_ALLOCATOR(Parent, AZ::SystemAllocator);
  55. ~Parent() override = default;
  56. static void Reflect(AZ::ReflectContext* reflectContext)
  57. {
  58. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
  59. {
  60. serializeContext->Class<Parent, Grandparent>();
  61. }
  62. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
  63. {
  64. behaviorContext->Class<Parent>("Parent")
  65. ;
  66. }
  67. }
  68. int GetGeneration() const override
  69. {
  70. return 2;
  71. }
  72. };
  73. class Child
  74. : public Parent
  75. {
  76. public:
  77. AZ_RTTI(Child, "{826DB77C-11B7-42C4-8F3F-3438AFE5B29B}", Parent);
  78. AZ_CLASS_ALLOCATOR(Parent, AZ::SystemAllocator);
  79. ~Child() override = default;
  80. static void Reflect(AZ::ReflectContext* reflectContext)
  81. {
  82. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
  83. {
  84. serializeContext->Class<Child, Parent>();
  85. }
  86. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
  87. {
  88. behaviorContext->Class<Child>("Child")
  89. ;
  90. }
  91. }
  92. int GetGeneration() const override
  93. {
  94. return 3;
  95. }
  96. };
  97. // TEST_F(ScriptCanvasTestFixture, CreateUuidsFast)
  98. // {
  99. // using namespace ScriptCanvas::Execution;
  100. //
  101. // ScriptCanvasEditor::ScopedOutputSuppression outputSuppression;
  102. //
  103. // AZ::Uuid candidate;
  104. // AZ::Uuid reference;
  105. // AZStd::string candidateString;
  106. // AZStd::string referenceString;
  107. //
  108. // candidateString = /**************/ "0123ABCD4567EFAB0123ABCD4567EFAB";
  109. // candidate = CreateIdFromStringFast(candidateString.data());
  110. // reference = AZ::Uuid::CreateString("0123abcd4567efab0123abcd4567efab");
  111. // EXPECT_EQ(candidate, reference);
  112. // referenceString = CreateStringFastFromId(candidate);
  113. // EXPECT_EQ(candidateString, referenceString);
  114. //
  115. // candidateString = /**************/ "12345678909876543345676524676553";
  116. // candidate = CreateIdFromStringFast(candidateString.data());
  117. // reference = AZ::Uuid::CreateString("12345678909876543345676524676553");
  118. // EXPECT_EQ(candidate, reference);
  119. // referenceString = CreateStringFastFromId(candidate);
  120. // EXPECT_EQ(candidateString, referenceString);
  121. //
  122. // candidateString = /**************/ "ABCDEFABCDEFABCDEFABCDEFABCDEFAB";
  123. // candidate = CreateIdFromStringFast(candidateString.data());
  124. // reference = AZ::Uuid::CreateString("abcdefabcdefabcdefabcdefabcdefab");
  125. // EXPECT_EQ(candidate, reference);
  126. // referenceString = CreateStringFastFromId(candidate);
  127. // EXPECT_EQ(candidateString, referenceString);
  128. //
  129. // candidateString = /**************/ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
  130. // candidate = CreateIdFromStringFast(candidateString.data());
  131. // reference = AZ::Uuid::CreateString("ffffffffffffffffffffffffffffffff");
  132. // EXPECT_EQ(candidate, reference);
  133. // referenceString = CreateStringFastFromId(candidate);
  134. // EXPECT_EQ(candidateString, referenceString);
  135. //
  136. // candidateString = /**************/ "00000000000000000000000000000000";
  137. // candidate = CreateIdFromStringFast(candidateString.data());
  138. // reference = AZ::Uuid::CreateString("00000000000000000000000000000000");
  139. // EXPECT_EQ(candidate, reference);
  140. // referenceString = CreateStringFastFromId(candidate);
  141. // EXPECT_EQ(candidateString, referenceString);
  142. //
  143. // candidateString = /**************/ "00000000000000000000000000000001";
  144. // candidate = CreateIdFromStringFast(candidateString.data());
  145. // reference = AZ::Uuid::CreateString("00000000000000000000000000000001");
  146. // EXPECT_EQ(candidate, reference);
  147. // referenceString = CreateStringFastFromId(candidate);
  148. // EXPECT_EQ(candidateString, referenceString);
  149. //
  150. // candidateString = /**************/ "80000000000000000000000000000000";
  151. // candidate = CreateIdFromStringFast(candidateString.data());
  152. // reference = AZ::Uuid::CreateString("80000000000000000000000000000000");
  153. // EXPECT_EQ(candidate, reference);
  154. // referenceString = CreateStringFastFromId(candidate);
  155. // EXPECT_EQ(candidateString, referenceString);
  156. //
  157. // // ................................."0123ABCD4567EFAB0123ABCD4567EFAB"
  158. // EXPECT_DEATH(CreateIdFromStringFast("0123ABCD4567EFAB0123ABCD4567EFA"), "");
  159. // EXPECT_DEATH(CreateIdFromStringFast("0123ABCD4567EFA"), "");
  160. // EXPECT_DEATH(CreateIdFromStringFast("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"), "");
  161. // EXPECT_DEATH(CreateIdFromStringFast("0123ABCD4567EFAB0123ABCD4567EFAB0"), "");
  162. // }
  163. TEST_F(ScriptCanvasTestFixture, InterpretedHelloWorld)
  164. {
  165. RunUnitTestGraph("LY_SC_UnitTest_HelloWorld");
  166. }
  167. TEST_F(ScriptCanvasTestFixture, TypeInheritance)
  168. {
  169. using namespace ScriptCanvas;
  170. using namespace ScriptCanvas::Grammar;
  171. // \todo make a version of this to test in the editor for node connections
  172. // \todo make a version of this using events to check the methods results using self and table explicit calls
  173. Grandparent::Reflect(m_serializeContext);
  174. Grandparent::Reflect(m_behaviorContext);
  175. Parent::Reflect(m_serializeContext);
  176. Parent::Reflect(m_behaviorContext);
  177. Child::Reflect(m_serializeContext);
  178. Child::Reflect(m_behaviorContext);
  179. Data::Type grandparentType = Data::Type::BehaviorContextObject(azrtti_typeid<Grandparent>());
  180. Data::Type grandparentType2 = Data::Type::BehaviorContextObject(azrtti_typeid<Grandparent>());
  181. Data::Type parentType = Data::Type::BehaviorContextObject(azrtti_typeid<Parent>());
  182. Data::Type parentType2 = Data::Type::BehaviorContextObject(azrtti_typeid<Parent>());
  183. Data::Type childType = Data::Type::BehaviorContextObject(azrtti_typeid<Child>());
  184. Data::Type childType2 = Data::Type::BehaviorContextObject(azrtti_typeid<Child>());
  185. EXPECT_TRUE(grandparentType.IS_A(grandparentType2));
  186. EXPECT_TRUE(grandparentType.IS_EXACTLY_A(grandparentType2));
  187. EXPECT_FALSE(grandparentType.IS_A(parentType));
  188. EXPECT_FALSE(grandparentType.IS_EXACTLY_A(parentType));
  189. EXPECT_FALSE(grandparentType.IS_A(childType));
  190. EXPECT_FALSE(grandparentType.IS_EXACTLY_A(childType));
  191. EXPECT_TRUE(parentType.IS_A(grandparentType));
  192. EXPECT_FALSE(parentType.IS_EXACTLY_A(grandparentType));
  193. EXPECT_TRUE(parentType.IS_A(parentType2));
  194. EXPECT_TRUE(parentType.IS_EXACTLY_A(parentType2));
  195. EXPECT_FALSE(parentType.IS_A(childType));
  196. EXPECT_FALSE(parentType.IS_EXACTLY_A(childType));
  197. EXPECT_TRUE(childType.IS_A(grandparentType));
  198. EXPECT_FALSE(childType.IS_EXACTLY_A(grandparentType));
  199. EXPECT_TRUE(childType.IS_A(parentType));
  200. EXPECT_FALSE(childType.IS_EXACTLY_A(parentType));
  201. EXPECT_TRUE(childType.IS_A(childType2));
  202. EXPECT_TRUE(childType.IS_EXACTLY_A(childType2));
  203. }
  204. TEST_F(ScriptCanvasTestFixture, TestLuaStringHandling)
  205. {
  206. AZ::ScriptContext sc;
  207. AZStd::string testingStrings[11] = {
  208. "test",
  209. "test]",
  210. "[test]",
  211. "=[test]=",
  212. "[=[test]=]",
  213. "[==[=[test]=]==]",
  214. "==[=[test]=]==",
  215. "test]=",
  216. "[=[==[test]==]=]",
  217. "[===[=[==[test]==]=]===]",
  218. "\"\\/.'].["
  219. };
  220. for (AZStd::string item : testingStrings)
  221. {
  222. AZStd::string safeStringLiteral = Translation::MakeRuntimeSafeStringLiteral(item);
  223. EXPECT_TRUE(sc.Execute(AZStd::string::format("print(%s)", safeStringLiteral.c_str()).c_str()));
  224. }
  225. }
  226. // \todo turn this into a unit test nodeable that adds a unit test failure on destruction if it was never triggered (or triggered the required number of times)
  227. class Marker
  228. {
  229. public:
  230. AZ_TYPE_INFO(Marker, "{BEEB4BF4-81B8-45A0-AD3F-D1875703315B}");
  231. AZ_CLASS_ALLOCATOR(Marker, AZ::SystemAllocator);
  232. static AZStd::vector<int> s_markedPositions;
  233. static void MarkPosition(int mark)
  234. {
  235. s_markedPositions.push_back(mark);
  236. }
  237. static void Reflect(AZ::ReflectContext* reflectContext)
  238. {
  239. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
  240. {
  241. behaviorContext->Class<Marker>("Marker")->Method("MarkPosition", &MarkPosition);
  242. }
  243. }
  244. };
  245. AZStd::vector<int> Marker::s_markedPositions;