Integrating latest 47acbe8

This commit is contained in:
alexpete
2021-03-25 13:57:57 -07:00
parent 448c549698
commit 75dc720198
10312 changed files with 2711566 additions and 671451 deletions
@@ -12,29 +12,32 @@
#pragma once
#include "ScriptCanvasTestApplication.h"
#include "ScriptCanvasTestNodes.h"
#include "EntityRefTests.h"
#include "ScriptCanvasTestUtilities.h"
#include <AzCore/Asset/AssetManagerComponent.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Driller/Driller.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/Memory/MemoryComponent.h>
#include <AzCore/Memory/MemoryDriller.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/containers/vector.h>
#include <AzFramework/IO/LocalFileIO.h>
#include <AzTest/AzTest.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/SlotConfigurationDefaults.h>
#include <AzTest/AzTest.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Driller/Driller.h>
#include <AzCore/Memory/MemoryDriller.h>
#include <ScriptCanvas/ScriptCanvasGem.h>
#include <AzCore/Memory/MemoryComponent.h>
#include <AzCore/Asset/AssetManagerComponent.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <ScriptCanvas/SystemComponent.h>
#include <AzFramework/IO/LocalFileIO.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include "EntityRefTests.h"
#include "ScriptCanvasTestApplication.h"
#include "ScriptCanvasTestBus.h"
#include "ScriptCanvasTestNodes.h"
#include "ScriptCanvasTestUtilities.h"
#include <Nodes/Nodeables/SharedDataSlotExample.h>
#include <Nodes/Nodeables/ValuePointerReferenceExample.h>
#define SC_EXPECT_DOUBLE_EQ(candidate, reference) EXPECT_NEAR(candidate, reference, 0.001)
#define SC_EXPECT_FLOAT_EQ(candidate, reference) EXPECT_NEAR(candidate, reference, 0.001f)
@@ -44,7 +47,7 @@ namespace ScriptCanvasTests
class ScriptCanvasTestFixture
: public ::testing::Test
, protected NodeAccessor
//, protected NodeAccessor
{
public:
static AZStd::atomic_bool s_asyncOperationActive;
@@ -75,6 +78,10 @@ namespace ScriptCanvasTests
descriptor.m_modules.push_back(dynamicModuleDescriptor);
dynamicModuleDescriptor.m_dynamicLibraryPath = "Gem.ScriptCanvasGem.Editor.869a0d0ec11a45c299917d45c81555e6.v0.1.0";
descriptor.m_modules.push_back(dynamicModuleDescriptor);
dynamicModuleDescriptor.m_dynamicLibraryPath = "Gem.ExpressionEvaluation.4c6f9df57ca2468f93c8d860ee6a1167.v0.1.0";
descriptor.m_modules.push_back(dynamicModuleDescriptor);
dynamicModuleDescriptor.m_dynamicLibraryPath = "Gem.ScriptEvents.32d8ba21703e4bbbb08487366e48dd69.v0.1.0";
descriptor.m_modules.push_back(dynamicModuleDescriptor);
s_application->Start(descriptor, appStartup);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
@@ -99,6 +106,32 @@ namespace ScriptCanvasTests
s_setupSucceeded = fileIO->GetAlias("@engroot@") != nullptr;
AZ::TickBus::AllowFunctionQueuing(true);
auto m_serializeContext = s_application->GetSerializeContext();
auto m_behaviorContext = s_application->GetBehaviorContext();
ScriptCanvasTesting::GlobalBusTraits::Reflect(m_serializeContext);
ScriptCanvasTesting::GlobalBusTraits::Reflect(m_behaviorContext);
ScriptCanvasTesting::LocalBusTraits::Reflect(m_serializeContext);
ScriptCanvasTesting::LocalBusTraits::Reflect(m_behaviorContext);
ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(m_serializeContext);
ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(m_behaviorContext);
ScriptCanvasTesting::TestTupleMethods::Reflect(m_behaviorContext);
::Nodes::InputMethodSharedDataSlotExampleNode::Reflect(m_serializeContext);
::Nodes::InputMethodSharedDataSlotExampleNode::Reflect(m_behaviorContext);
::Nodes::BranchMethodSharedDataSlotExampleNode::Reflect(m_serializeContext);
::Nodes::BranchMethodSharedDataSlotExampleNode::Reflect(m_behaviorContext);
::Nodes::ReturnTypeExampleNode::Reflect(m_serializeContext);
::Nodes::ReturnTypeExampleNode::Reflect(m_behaviorContext);
::Nodes::InputTypeExampleNode::Reflect(m_serializeContext);
::Nodes::InputTypeExampleNode::Reflect(m_behaviorContext);
::Nodes::BranchInputTypeExampleNode::Reflect(m_serializeContext);
::Nodes::BranchInputTypeExampleNode::Reflect(m_behaviorContext);
TestNodeableObject::Reflect(m_serializeContext);
TestNodeableObject::Reflect(m_behaviorContext);
ScriptUnitTestEventHandler::Reflect(m_serializeContext);
ScriptUnitTestEventHandler::Reflect(m_behaviorContext);
}
static void TearDownTestCase()
@@ -117,7 +150,7 @@ namespace ScriptCanvasTests
delete s_application;
s_application = nullptr;
}
s_allocatorSetup.TeardownAllocator();
}
@@ -148,33 +181,21 @@ namespace ScriptCanvasTests
m_stringToNumberMapType = ScriptCanvas::Data::Type::BehaviorContextObject(azrtti_typeid<AZStd::unordered_map<ScriptCanvas::Data::StringType, ScriptCanvas::Data::NumberType>>());
m_dataSlotConfigurationType = ScriptCanvas::Data::Type::BehaviorContextObject(azrtti_typeid<ScriptCanvas::DataSlotConfiguration>());
ScriptUnitTestEventHandler::Reflect(m_serializeContext);
ScriptUnitTestEventHandler::Reflect(m_behaviorContext);
}
void TearDown() override
{
delete m_graph;
m_graph = nullptr;
ASSERT_TRUE(s_setupSucceeded) << "ScriptCanvasTestFixture set up failed, unit tests can't work properly";
m_serializeContext->EnableRemoveReflection();
m_behaviorContext->EnableRemoveReflection();
ScriptUnitTestEventHandler::Reflect(m_serializeContext);
ScriptUnitTestEventHandler::Reflect(m_behaviorContext);
m_serializeContext->DisableRemoveReflection();
m_behaviorContext->DisableRemoveReflection();
for (AZ::ComponentDescriptor* componentDescriptor : m_descriptors)
{
GetApplication()->UnregisterComponentDescriptor(componentDescriptor);
}
m_descriptors.clear();
delete m_graph;
m_graph = nullptr;
m_descriptors.clear();
}
ScriptCanvas::Graph* CreateGraph()
@@ -207,13 +228,9 @@ namespace ScriptCanvasTests
void ReportErrors(ScriptCanvas::Graph* graph, bool expectErrors = false, bool expectIrrecoverableErrors = false)
{
EXPECT_EQ(graph->IsInErrorState(), expectErrors);
EXPECT_EQ(graph->IsInIrrecoverableErrorState(), expectIrrecoverableErrors);
if (graph->IsInErrorState())
{
AZ_TracePrintf("UnitTest", "%s\n", AZStd::string(graph->GetLastErrorDescription()).c_str());
}
AZ_UNUSED(graph);
AZ_UNUSED(expectErrors);
AZ_UNUSED(expectIrrecoverableErrors);
}
void TestConnectionBetween(ScriptCanvas::Endpoint sourceEndpoint, ScriptCanvas::Endpoint targetEndpoint, bool isValid = true)
@@ -12,9 +12,12 @@
#include "ScriptCanvasTestNodes.h"
#include <ScriptCanvas/Core/Core.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/SlotConfigurationDefaults.h>
#include <ScriptCanvas/Grammar/GrammarContext.h>
#include <ScriptCanvas/Grammar/GrammarContextBus.h>
#include <gtest/gtest.h>
@@ -201,14 +204,10 @@ namespace TestNodes
return addedSlotId;
}
bool AddNodeWithRemoveSlot::RemoveSlot(const ScriptCanvas::SlotId& slotId)
bool AddNodeWithRemoveSlot::RemoveSlot(const ScriptCanvas::SlotId& slotId, bool emitWarning /*= true*/)
{
auto dynamicSlotIt = AZStd::find(m_dynamicSlotIds.begin(), m_dynamicSlotIds.end(), slotId);
if (dynamicSlotIt != m_dynamicSlotIds.end())
{
m_dynamicSlotIds.erase(dynamicSlotIt);
}
return Node::RemoveSlot(slotId);
AZStd::erase_if(m_dynamicSlotIds, [slotId](const ScriptCanvas::SlotId& sId) { return (sId == slotId); });
return Node::RemoveSlot(slotId, true, emitWarning);
}
void AddNodeWithRemoveSlot::OnInputSignal(const ScriptCanvas::SlotId& slotId)
@@ -396,7 +395,7 @@ namespace TestNodes
Node::AddSlot(ScriptCanvas::CommonSlots::GeneralOutSlot());
Node::AddSlot(ScriptCanvas::DataSlotConfiguration(ScriptCanvas::Data::Type::String(), "Result", ScriptCanvas::ConnectionType::Output));
}
/////////////////////////////
// ConfigurableUnitTestNode
/////////////////////////////
@@ -442,11 +441,12 @@ namespace TestNodes
bool ConfigurableUnitTestNode::TestHasConcreteDisplayType(const AZ::Crc32& dynamicGroup) const
{
return HasConcreteDisplayType(dynamicGroup);
return FindConcreteDisplayType(dynamicGroup).IsValid();
}
bool ConfigurableUnitTestNode::TestIsSlotConnectedToConcreteDisplayType(const ScriptCanvas::Slot& slot, ExploredDynamicGroupCache& exploredGroupCache) const
{
return IsSlotConnectedToConcreteDisplayType(slot, exploredGroupCache);
return FindConnectedConcreteDisplayType(slot, exploredGroupCache).IsValid();
}
}
@@ -103,7 +103,7 @@ namespace TestNodes
static void Reflect(AZ::ReflectContext* reflection);
ScriptCanvas::SlotId AddSlot(AZStd::string_view slotName);
bool RemoveSlot(const ScriptCanvas::SlotId& slotId);
bool RemoveSlot(const ScriptCanvas::SlotId& slotId, bool emitWarning = true);
protected:
void OnInputSignal(const ScriptCanvas::SlotId& slotId) override;
@@ -150,7 +150,7 @@ namespace TestNodes
void OnInit() override;
};
//////////////////////////////////////////////////////////////////////////////
class ConfigurableUnitTestNode
: public ScriptCanvas::Node
@@ -172,4 +172,6 @@ namespace TestNodes
protected:
};
}
@@ -10,16 +10,19 @@
*
*/
#include <Editor/Framework/ScriptCanvasTraceUtilities.h>
#include <Framework/ScriptCanvasTestUtilities.h>
#include <Framework/ScriptCanvasTestNodes.h>
#include <Editor/Framework/ScriptCanvasGraphUtilities.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <Asset/EditorAssetSystemComponent.h>
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzCore/Component/TickBus.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/IOUtils.h>
#include <AzCore/IO/FileIOEventBus.h>
#include <AzCore/UnitTest/UnitTest.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <Editor/Framework/ScriptCanvasGraphUtilities.h>
#include <Editor/Framework/ScriptCanvasTraceUtilities.h>
#include <Framework/ScriptCanvasTestNodes.h>
#include <Framework/ScriptCanvasTestUtilities.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
@@ -27,14 +30,15 @@
namespace ScriptCanvasTestUtilitiesCPP
{
const char* k_defaultExtension = "scriptcanvas";
const char* k_scriptEventExtension = "scriptevents";
const char* k_unitTestDirPathRelative = "@engroot@/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests";
} // namespace ScriptCanvasTestUtilitiesCPP
}
namespace ScriptCanvasTests
{
using namespace ScriptCanvas;
#define SC_CORE_UNIT_TEST_DIR "@exefolder@/LY_SC_UnitTest_ScriptCanvas_CoreCPP_Temporary"
#define SC_CORE_UNIT_TEST_DIR "@engroot@/LY_SC_UnitTest_ScriptCanvas_CoreCPP_Temporary"
#define SC_CORE_UNIT_TEST_NAME "serializationTest.scriptcanvas_compiled"
const char* k_tempCoreAssetDir = SC_CORE_UNIT_TEST_DIR;
const char* k_tempCoreAssetName = SC_CORE_UNIT_TEST_NAME;
@@ -42,6 +46,47 @@ namespace ScriptCanvasTests
#undef SC_CORE_UNIT_TEST_DIR
#undef SC_CORE_UNIT_TEST_NAME
void ExpectParse(AZStd::string_view graphPath)
{
ExpectParse(graphPath, ScriptCanvasTestUtilitiesCPP::k_defaultExtension);
}
void ExpectParse(AZStd::string_view graphPath, AZStd::string_view extension)
{
AZ_TEST_START_TRACE_SUPPRESSION;
const AZStd::string filePath = AZStd::string::format("%s/%s.%s", ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative, graphPath.data(), extension.data());
ScriptCanvasEditor::RunGraphSpec runGraphSpec;
runGraphSpec.graphPath = filePath;
runGraphSpec.dirPath = ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative;
runGraphSpec.runSpec.processOnly = true;
runGraphSpec.runSpec.execution = ExecutionMode::Interpreted;
auto reporters = ScriptCanvasEditor::RunGraph(runGraphSpec);
ScriptCanvasTests::VerifyReporter(reporters.front());
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT;
}
void ExpectParseError(AZStd::string_view graphPath)
{
ExpectParseError(graphPath, ScriptCanvasTestUtilitiesCPP::k_defaultExtension);
}
void ExpectParseError(AZStd::string_view graphPath, AZStd::string_view extension)
{
AZ_TEST_START_TRACE_SUPPRESSION;
const AZStd::string filePath = AZStd::string::format("%s/%s.%s", ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative, graphPath.data(), extension.data());
ScriptCanvasEditor::RunGraphSpec runGraphSpec;
runGraphSpec.runSpec.processOnly = true;
runGraphSpec.graphPath = filePath;
runGraphSpec.dirPath = ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative;
runGraphSpec.runSpec.execution = ExecutionMode::Interpreted;
auto reporters = ScriptCanvasEditor::RunGraph(runGraphSpec);
reporters.front().MarkExpectParseError();
ScriptCanvasTests::VerifyReporter(reporters.front());
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT;
}
AZStd::string_view GetGraphNameFromPath(AZStd::string_view graphPath)
{
graphPath.remove_prefix(AZStd::min(graphPath.find_last_of("\\/") + 1, graphPath.size()));
@@ -50,50 +95,83 @@ namespace ScriptCanvasTests
void VerifyReporter(const ScriptCanvasEditor::Reporter& reporter)
{
if (!reporter.GetScriptCanvasId().IsValid())
if (!reporter.IsGraphLoaded())
{
ADD_FAILURE() << "Graph is not valid";
ADD_FAILURE() << "Graph was not successfully loaded.";
}
else if (reporter.ExpectsParseError())
{
if (!reporter.IsParseAttemptMade())
{
ADD_FAILURE() << "Expected a parse error but the graph never attempted to be parsed";
}
else if (reporter.IsCompiled())
{
ADD_FAILURE() << "Expected a parse error but graph compiled successfully";
}
}
else if (!reporter.IsCompiled())
{
ADD_FAILURE() << "Graph failed to compile";
}
else if (!reporter.GetScriptCanvasId().IsValid())
{
ADD_FAILURE() << "Graph is not valid, wasn't assigned properly to an entity";
}
else if (reporter.IsReportFinished())
{
bool reportCheckpoints = false;
const auto& successes = reporter.GetSuccess();
for (const auto& success : successes)
if (!reporter.IsProcessOnly())
{
SUCCEED() << success.data();
const auto& successes = reporter.GetSuccess();
for (const auto& success : successes)
{
SUCCEED() << success.c_str();
}
if (!reporter.IsActivated())
{
ADD_FAILURE() << "Graph did not activate";
}
if (!reporter.IsDeactivated())
{
ADD_FAILURE() << "Graph did not deactivate";
reportCheckpoints = true;
}
if (!reporter.ExpectsRuntimeFailure())
{
if (!reporter.IsComplete())
{
ADD_FAILURE() << "Graph was not marked complete";
reportCheckpoints = true;
}
if (!reporter.IsErrorFree())
{
ADD_FAILURE() << "Graph execution had errors";
reportCheckpoints = true;
const auto& failures = reporter.GetFailure();
for (const auto& failure : failures)
{
ADD_FAILURE() << failure.c_str();
}
}
}
else
{
if (reporter.IsErrorFree())
{
ADD_FAILURE() << "Graph expected error, but didn't report any";
reportCheckpoints = true;
}
}
}
if (!reporter.IsActivated())
{
ADD_FAILURE() << "Graph did not activate";
}
if (!reporter.IsDeactivated())
{
ADD_FAILURE() << "Graph did not deactivate";
reportCheckpoints = true;
}
if (!reporter.IsErrorFree())
{
ADD_FAILURE() << "Graph had errors";
reportCheckpoints = true;
}
const auto& failures = reporter.GetFailure();
for (const auto& failure : failures)
{
ADD_FAILURE() << failure.data();
}
if (!reporter.IsComplete())
{
ADD_FAILURE() << "Graph was not marked complete";
reportCheckpoints = true;
}
if (reportCheckpoints)
if (reportCheckpoints && !reporter.IsProcessOnly())
{
const auto& checkpoints = reporter.GetCheckpoints();
if (checkpoints.empty())
@@ -107,12 +185,60 @@ namespace ScriptCanvasTests
for (const auto& checkpoint : checkpoints)
{
checkpointPath += AZStd::string::format("%2d: %s\n", ++i, checkpoint.data()).data();
checkpointPath += AZStd::string::format("%2d: %s\n", ++i, checkpoint.c_str()).c_str();
}
ADD_FAILURE() << checkpointPath.data();
ADD_FAILURE() << checkpointPath.c_str();
}
}
else
{
const Execution::PerformanceTrackingReport& performance = reporter.GetPerformanceReport();
if (reporter.GetExecutionMode() == ExecutionMode::Interpreted)
{
std::cerr << "[INTERPRETED] ";
}
else
{
std::cerr << "[ NATIVE] ";
}
std::cerr << AZStd::string::format
(" Parse: %4.2f ms, Translate: %4.2f ms\n"
, reporter.GetParseDuration() / 1000.0
, reporter.GetTranslateDuration() / 1000.0).c_str();
double ready = aznumeric_caster(performance.timing.initializationTime);
double instant = aznumeric_caster(performance.timing.executionTime);
double latent = aznumeric_caster(performance.timing.latentTime);
double total = aznumeric_caster(performance.timing.totalTime);
std::cerr << "[ INITIALIZE] " << AZStd::string::format("%7.3f ms \n", ready / 1000.0).c_str();
std::cerr << "[ EXECUTION] " << AZStd::string::format("%7.3f ms \n", instant / 1000.0).c_str();
std::cerr << "[ LATENT] " << AZStd::string::format("%7.3f ms \n", latent / 1000.0).c_str();
std::cerr << "[ TOTAL] " << AZStd::string::format("%7.3f ms ", total / 1000.0).c_str();
switch (reporter.GetExecutionConfiguration())
{
case ScriptCanvasEditor::ExecutionConfiguration::Debug:
std::cerr << "[ DEBUG] ";
break;
case ScriptCanvasEditor::ExecutionConfiguration::Performance:
std::cerr << "[PERFORM] ";
break;
case ScriptCanvasEditor::ExecutionConfiguration::Release:
std::cerr << "[RELEASE] ";
break;
case ScriptCanvasEditor::ExecutionConfiguration::Traced:
std::cerr << "[ TRACED] ";
break;
}
std::cerr << "\n";
}
}
else
{
@@ -120,34 +246,131 @@ namespace ScriptCanvasTests
}
}
void RunUnitTestGraph(AZStd::string_view graphPath, ExecutionMode execution, const ScriptCanvasEditor::DurationSpec& duration)
void RunUnitTestGraph(AZStd::string_view graphPath)
{
const AZStd::string filePath = AZStd::string::format("%s/%s.%s", ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative, graphPath.data(), ScriptCanvasTestUtilitiesCPP::k_defaultExtension);
const ScriptCanvasEditor::Reporter reporter = ScriptCanvasEditor::RunGraph(filePath, execution, duration);
ScriptCanvasTests::VerifyReporter(reporter);
}
void RunUnitTestGraph(AZStd::string_view graphPath, const ScriptCanvasEditor::DurationSpec& duration)
{
ScriptCanvasTests::RunUnitTestGraph(graphPath, ExecutionMode::Interpreted, duration);
ScriptCanvasTests::RunUnitTestGraph(graphPath, ScriptCanvasEditor::RunSpec());
}
void RunUnitTestGraph(AZStd::string_view graphPath, ExecutionMode execution)
{
ScriptCanvasTests::RunUnitTestGraph(graphPath, execution, ScriptCanvasEditor::DurationSpec());
ScriptCanvasEditor::RunSpec spec;
spec.execution = execution;
ScriptCanvasTests::RunUnitTestGraph(graphPath, spec);
}
void RunUnitTestGraph(AZStd::string_view graphPath)
void RunUnitTestGraph(AZStd::string_view graphPath, ExecutionMode execution, const ScriptCanvasEditor::DurationSpec& duration)
{
ScriptCanvasTests::RunUnitTestGraph(graphPath, ScriptCanvasEditor::DurationSpec());
ScriptCanvasEditor::RunSpec runSpec;
runSpec.execution = execution;
runSpec.duration = duration;
RunUnitTestGraph(graphPath, runSpec);
}
void RunUnitTestGraph(AZStd::string_view graphPath, ExecutionMode execution, AZStd::string_view dependentScriptEvent)
{
AZ::Data::AssetType assetType(azrtti_typeid<ScriptEvents::ScriptEventsAsset>());
if (auto scriptEventAssetHandler = AZ::Data::AssetManager::Instance().GetHandler(assetType))
{
const AZStd::string fullPath = AZStd::string::format("%s/%s.%s", ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative, dependentScriptEvent.data(), ScriptCanvasTestUtilitiesCPP::k_scriptEventExtension);
// Preload dependent scriptevent asset for testing
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
// Read in the data from a file to a buffer, then hand ownership of the buffer over to the assetDataStream
{
AZ::IO::FileIOStream stream(fullPath.c_str(), AZ::IO::OpenMode::ModeRead);
if (!AZ::IO::RetryOpenStream(stream))
{
ADD_FAILURE() << AZStd::string::format("CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.c_str()).data();
return;
}
AZStd::vector<AZ::u8> fileBuffer(stream.GetLength());
size_t bytesRead = stream.Read(fileBuffer.size(), fileBuffer.data());
if (bytesRead != stream.GetLength())
{
ADD_FAILURE() << AZStd::string::format("CreateJobs for \"%s\" failed because the source file could not be read.", fullPath.c_str()).data();
return;
}
assetDataStream->Open(AZStd::move(fileBuffer));
}
AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> asset;
const AZStd::string hintPath = AZStd::string::format("scriptcanvas/unittests/%s.%s", dependentScriptEvent.data(), ScriptCanvasTestUtilitiesCPP::k_scriptEventExtension);
asset.Create(AZ::Data::AssetId(AZ::Uuid::CreateName(hintPath.data())));
if (scriptEventAssetHandler->LoadAssetDataFromStream(asset, assetDataStream, nullptr) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
{
ADD_FAILURE() << AZStd::string::format("Failed to load ScriptEvent asset: %s", fullPath.data()).data();
return;
}
scriptEventAssetHandler->InitAsset(asset, true, false);
ScriptCanvasEditor::RunSpec spec;
spec.execution = execution;
ScriptCanvasTests::RunUnitTestGraph(graphPath, spec);
}
else
{
ADD_FAILURE() << "ScriptEvent asset handler is missing.";
}
}
void RunUnitTestGraph(AZStd::string_view graphPath, const ScriptCanvasEditor::DurationSpec& duration)
{
ScriptCanvasEditor::RunSpec spec;
spec.duration = duration;
ScriptCanvasTests::RunUnitTestGraph(graphPath, ExecutionMode::Interpreted, duration);
}
void RunUnitTestGraph(AZStd::string_view graphPath, const ScriptCanvasEditor::RunSpec& runSpec)
{
const AZStd::string filePath = AZStd::string::format("%s/%s.%s", ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative, graphPath.data(), ScriptCanvasTestUtilitiesCPP::k_defaultExtension);
ScriptCanvasEditor::RunGraphSpec runGraphSpec;
runGraphSpec.graphPath = filePath;
runGraphSpec.dirPath = ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative;
runGraphSpec.runSpec = runSpec;
AZ_TEST_START_TRACE_SUPPRESSION;
const ScriptCanvasEditor::Reporters reporters = ScriptCanvasEditor::RunGraph(runGraphSpec);
for (const auto& reporter : reporters)
{
ScriptCanvasTests::VerifyReporter(reporter);
}
if (reporters.size() == 2)
{
EXPECT_EQ(reporters.front(), reporters.back());
}
else if (reporters.size() > 2)
{
for (size_t lhs(0), rhs(1); rhs != reporters.size(); ++lhs, ++rhs)
{
EXPECT_EQ(reporters[lhs], reporters[rhs]);
}
}
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT;
}
void RunUnitTestGraphMixed(AZStd::string_view graphPath, const ScriptCanvasEditor::DurationSpec& duration)
{
const ScriptCanvasEditor::Reporter reporterIterpreted0 = RunGraph(graphPath, ExecutionMode::Interpreted, duration);
const ScriptCanvasEditor::Reporter reporterNative0 = RunGraph(graphPath, ExecutionMode::Native, duration);
const ScriptCanvasEditor::Reporter reporterIterpreted1 = RunGraph(graphPath, ExecutionMode::Interpreted, duration);
const ScriptCanvasEditor::Reporter reporterNative1 = RunGraph(graphPath, ExecutionMode::Native, duration);
AZ_TEST_START_TRACE_SUPPRESSION;
ScriptCanvasEditor::RunGraphSpec runGraphSpec;
runGraphSpec.graphPath = graphPath;
runGraphSpec.dirPath = ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative;
runGraphSpec.runSpec.duration = duration;
runGraphSpec.runSpec.execution = ExecutionMode::Interpreted;
const ScriptCanvasEditor::Reporter reporterIterpreted0 = RunGraph(runGraphSpec).front();
runGraphSpec.runSpec.execution = ExecutionMode::Native;
const ScriptCanvasEditor::Reporter reporterNative0 = RunGraph(runGraphSpec).front();
runGraphSpec.runSpec.execution = ExecutionMode::Interpreted;
const ScriptCanvasEditor::Reporter reporterIterpreted1 = RunGraph(runGraphSpec).front();
runGraphSpec.runSpec.execution = ExecutionMode::Native;
const ScriptCanvasEditor::Reporter reporterNative1 = RunGraph(runGraphSpec).front();
VerifyReporter(reporterIterpreted0);
VerifyReporter(reporterNative0);
@@ -163,24 +386,8 @@ namespace ScriptCanvasTests
EXPECT_EQ(reporterNative0, reporterNative1);
EXPECT_EQ(reporterIterpreted0, reporterIterpreted1);
}
ScriptCanvasEditor::LoadTestGraphResult LoadTestGraph(AZStd::string_view graphPath)
{
const AZStd::string filePath = AZStd::string::format("%s/%s.%s", ScriptCanvasTestUtilitiesCPP::k_unitTestDirPathRelative, graphPath.data(), ScriptCanvasTestUtilitiesCPP::k_defaultExtension);
AZ::Outcome< AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> assetOutcome = AZ::Failure(AZStd::string("asset creation failed"));
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(assetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateRuntimeAsset, filePath);
if (assetOutcome.IsSuccess())
{
ScriptCanvasEditor::LoadTestGraphResult result;
result.m_asset = assetOutcome.GetValue();
result.m_graphEntity = AZStd::make_unique<AZ::Entity>("Loaded Graph");
result.m_graph = result.m_graphEntity->CreateComponent<ScriptCanvas::RuntimeComponent>(result.m_asset);
return result;
}
return {};
AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT;
}
void RunUnitTestGraphMixed(AZStd::string_view graphPath)
@@ -291,16 +498,16 @@ namespace ScriptCanvasTests
{
using namespace ScriptCanvas;
ScriptCanvas::Namespaces emptyNamespaces;
ScriptCanvas::NamespacePath emptyNamespaces;
AZ::Entity* splitEntity{ aznew AZ::Entity };
splitEntity->Init();
AZ::EntityId methodNodeID{ splitEntity->GetId() };
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, methodNodeID, scriptCanvasId, Nodes::Core::Method::RTTI_Type());
Nodes::Core::Method* methodNode(nullptr);
SystemRequestBus::BroadcastResult(methodNode, &SystemRequests::GetNode<Nodes::Core::Method>, methodNodeID);
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, methodNodeID, scriptCanvasId, ScriptCanvas::Nodes::Core::Method::RTTI_Type());
ScriptCanvas::Nodes::Core::Method* methodNode(nullptr);
SystemRequestBus::BroadcastResult(methodNode, &SystemRequests::GetNode<ScriptCanvas::Nodes::Core::Method>, methodNodeID);
EXPECT_TRUE(methodNode != nullptr);
methodNode->InitializeClassOrBus(emptyNamespaces, className, methodName);
methodNode->InitializeBehaviorMethod(emptyNamespaces, className, methodName);
return methodNodeID;
}
@@ -313,83 +520,81 @@ namespace ScriptCanvasTests
switch (type.GetType())
{
case Data::eType::AABB:
node = CreateTestNode<Nodes::Math::AABB>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::AABB>(scriptCanvasId, nodeIDout);
break;
case Data::eType::BehaviorContextObject:
{
auto objectNode = CreateTestNode<Nodes::Core::BehaviorContextObjectNode>(scriptCanvasId, nodeIDout);
auto objectNode = CreateTestNode<ScriptCanvas::Nodes::Core::BehaviorContextObjectNode>(scriptCanvasId, nodeIDout);
objectNode->InitializeObject(type);
node = objectNode;
}
break;
case Data::eType::Boolean:
node = CreateTestNode<Nodes::Logic::Boolean>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Logic::Boolean>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Color:
node = CreateTestNode<Nodes::Math::Color>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Color>(scriptCanvasId, nodeIDout);
break;
case Data::eType::CRC:
node = CreateTestNode<Nodes::Math::CRC>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::CRC>(scriptCanvasId, nodeIDout);
break;
case Data::eType::EntityID:
node = CreateTestNode<Nodes::Entity::EntityRef>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Entity::EntityRef>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Matrix3x3:
node = CreateTestNode<Nodes::Math::Matrix3x3>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Matrix3x3>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Matrix4x4:
node = CreateTestNode<Nodes::Math::Matrix4x4>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Matrix4x4>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Number:
node = CreateTestNode<Nodes::Math::Number>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Number>(scriptCanvasId, nodeIDout);
break;
case Data::eType::OBB:
node = CreateTestNode<Nodes::Math::OBB>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::OBB>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Plane:
node = CreateTestNode<Nodes::Math::Plane>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Plane>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Quaternion:
node = CreateTestNode<Nodes::Math::Quaternion>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Quaternion>(scriptCanvasId, nodeIDout);
break;
case Data::eType::String:
node = CreateTestNode<Nodes::Core::String>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Core::String>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Transform:
node = CreateTestNode<Nodes::Math::Transform>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Transform>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Vector2:
node = CreateTestNode<Nodes::Math::Vector2>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Vector2>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Vector3:
node = CreateTestNode<Nodes::Math::Vector3>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Vector3>(scriptCanvasId, nodeIDout);
break;
case Data::eType::Vector4:
node = CreateTestNode<Nodes::Math::Vector4>(scriptCanvasId, nodeIDout);
node = CreateTestNode<ScriptCanvas::Nodes::Math::Vector4>(scriptCanvasId, nodeIDout);
break;
default:
AZ_Error("ScriptCanvas", false, "unsupported data type");
}
node->SetExecutionType(ExecutionType::Runtime);
return node;
}
@@ -465,22 +670,6 @@ namespace ScriptCanvasTests
return false;
}
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> CreateRuntimeAsset(ScriptCanvas::Graph* graph)
{
using namespace ScriptCanvas;
RuntimeAssetHandler runtimeAssetHandler;
AZ::Data::Asset<RuntimeAsset> runtimeAsset;
runtimeAsset.Create(AZ::Uuid::CreateRandom());
AZ::SerializeContext* serializeContext = AZ::EntityUtils::GetApplicationSerializeContext();
serializeContext->CloneObjectInplace(runtimeAsset.Get()->GetData().m_graphData, graph->GetGraphDataConst());
AZStd::unordered_map<AZ::EntityId, AZ::EntityId> graphToAssetEntityIdMap{ { graph->GetScriptCanvasId(), ScriptCanvas::UniqueId } };
AZ::IdUtils::Remapper<AZ::EntityId>::GenerateNewIdsAndFixRefs(&runtimeAsset.Get()->GetData().m_graphData, graphToAssetEntityIdMap, serializeContext);
return runtimeAsset;
}
AZ::Entity* UnitTestEntityContext::CreateEntity(const char* name)
{
auto entity = aznew AZ::Entity(name);
@@ -613,54 +802,54 @@ namespace ScriptCanvasTests
return cloneEntity;
}
AZ::Data::AssetId UnitTestEntityContext::CurrentlyInstantiatingSlice()
{
return AZ::Data::AssetId();
}
//AZ::Data::AssetId UnitTestEntityContext::CurrentlyInstantiatingSlice()
//{
// return AZ::Data::AssetId();
//}
bool UnitTestEntityContext::HandleRootEntityReloadedFromStream(AZ::Entity*, bool, AZ::SliceComponent::EntityIdToEntityIdMap*)
{
return true;
}
//bool UnitTestEntityContext::HandleRootEntityReloadedFromStream(AZ::Entity*, bool, AZ::SliceComponent::EntityIdToEntityIdMap*)
//{
// return true;
//}
AZ::SliceComponent* UnitTestEntityContext::GetRootSlice()
{
return {};
}
//AZ::SliceComponent* UnitTestEntityContext::GetRootSlice()
//{
// return {};
//}
const AZStd::unordered_map<AZ::EntityId, AZ::EntityId>& UnitTestEntityContext::GetLoadedEntityIdMap()
{
return m_unitTestEntityIdMap;
}
//const AZStd::unordered_map<AZ::EntityId, AZ::EntityId>& UnitTestEntityContext::GetLoadedEntityIdMap()
//{
// return m_unitTestEntityIdMap;
//}
AzFramework::SliceInstantiationTicket UnitTestEntityContext::InstantiateSlice(const AZ::Data::Asset<AZ::Data::AssetData>&,
const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper&, const AZ::Data::AssetFilterCB&)
{
return AzFramework::SliceInstantiationTicket();
}
//AzFramework::SliceInstantiationTicket UnitTestEntityContext::InstantiateSlice(const AZ::Data::Asset<AZ::Data::AssetData>&,
// const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper&, const AZ::Data::AssetFilterCB&)
//{
// return AzFramework::SliceInstantiationTicket();
//}
AZ::SliceComponent::SliceInstanceAddress UnitTestEntityContext::CloneSliceInstance(
AZ::SliceComponent::SliceInstanceAddress, AZ::SliceComponent::EntityIdToEntityIdMap&)
{
return AZ::SliceComponent::SliceInstanceAddress();
}
//AZ::SliceComponent::SliceInstanceAddress UnitTestEntityContext::CloneSliceInstance(
// AZ::SliceComponent::SliceInstanceAddress, AZ::SliceComponent::EntityIdToEntityIdMap&)
//{
// return AZ::SliceComponent::SliceInstanceAddress();
//}
void UnitTestEntityContext::CancelSliceInstantiation(const AzFramework::SliceInstantiationTicket&)
{
}
//void UnitTestEntityContext::CancelSliceInstantiation(const AzFramework::SliceInstantiationTicket&)
//{
//}
AzFramework::SliceInstantiationTicket UnitTestEntityContext::GenerateSliceInstantiationTicket()
{
return AzFramework::SliceInstantiationTicket();
}
//AzFramework::SliceInstantiationTicket UnitTestEntityContext::GenerateSliceInstantiationTicket()
//{
// return AzFramework::SliceInstantiationTicket();
//}
void UnitTestEntityContext::SetIsDynamic(bool)
{
}
//void UnitTestEntityContext::SetIsDynamic(bool)
//{
//}
const AzFramework::RootSliceAsset& UnitTestEntityContext::GetRootAsset() const
{
return m_unitTestRootAsset;
}
//const AzFramework::RootSliceAsset& UnitTestEntityContext::GetRootAsset() const
//{
// return m_unitTestRootAsset;
//}
} // ScriptCanvasTests
@@ -11,11 +11,15 @@
*/
#pragma once
#include <Editor/Framework/ScriptCanvasTraceUtilities.h>
#include <Editor/Framework/ScriptCanvasReporter.h>
#include <Framework/ScriptCanvasTestNodes.h>
#include <AzTest/AzTest.h>
#include <AzTest/AzTest.h>
#include <Editor/Framework/ScriptCanvasReporter.h>
#include <Editor/Framework/ScriptCanvasTraceUtilities.h>
#include <Framework/ScriptCanvasTestNodes.h>
#include <ScriptCanvas/Core/Nodeable.h>
#include <AzFramework/Entity/SliceEntityOwnershipServiceBus.h>
#include "AzFramework/Slice/SliceInstantiationTicket.h"
namespace ScriptCanvasTests
{
@@ -23,104 +27,33 @@ namespace ScriptCanvasTests
extern const char* k_tempCoreAssetName;
extern const char* k_tempCoreAssetPath;
void ExpectParse(AZStd::string_view graphPath);
void ExpectParse(AZStd::string_view graphPath, AZStd::string_view extension);
void ExpectParseError(AZStd::string_view graphPath);
void ExpectParseError(AZStd::string_view graphPath, AZStd::string_view extension);
AZStd::string_view GetGraphNameFromPath(AZStd::string_view graphPath);
void VerifyReporter(const ScriptCanvasEditor::Reporter& reporter);
void RunUnitTestGraph(AZStd::string_view graphPath, ScriptCanvas::ExecutionMode execution, const ScriptCanvasEditor::DurationSpec& duration);
void RunUnitTestGraph(AZStd::string_view graphPath, const ScriptCanvasEditor::DurationSpec& duration);
void RunUnitTestGraph(AZStd::string_view graphPath);
void RunUnitTestGraph(AZStd::string_view graphPath, ScriptCanvas::ExecutionMode execution);
void RunUnitTestGraph(AZStd::string_view graphPath);
void RunUnitTestGraph(AZStd::string_view graphPath, ScriptCanvas::ExecutionMode execution, const ScriptCanvasEditor::DurationSpec& duration);
void RunUnitTestGraph(AZStd::string_view graphPath, ScriptCanvas::ExecutionMode execution, AZStd::string_view dependentScriptEvent);
void RunUnitTestGraph(AZStd::string_view graphPath, const ScriptCanvasEditor::DurationSpec& duration);
void RunUnitTestGraph(AZStd::string_view graphPath, const ScriptCanvasEditor::RunSpec& runSpec);
void RunUnitTestGraphMixed(AZStd::string_view graphPath, const ScriptCanvasEditor::DurationSpec& duration);
void RunUnitTestGraphMixed(AZStd::string_view graphPath);
class NodeAccessor
{
public:
template<typename t_Value>
static const t_Value* GetInput_UNIT_TEST(ScriptCanvas::Node* node, AZStd::string_view slotName)
{
return GetInput_UNIT_TEST<t_Value>(node, node->GetSlotId(slotName));
}
template<typename t_Value>
static t_Value* ModInput_UNIT_TEST(ScriptCanvas::Node* node, AZStd::string_view slotName)
{
return ModInput_UNIT_TEST<t_Value>(node, node->GetSlotId(slotName));
}
template<typename t_Value>
static const t_Value* GetInput_UNIT_TEST(ScriptCanvas::Node* node, const ScriptCanvas::SlotId& slotId)
{
const ScriptCanvas::Datum* input = node->FindDatum(slotId);
return input ? input->GetAs<t_Value>() : nullptr;
}
template<typename t_Value>
static t_Value* ModInput_UNIT_TEST(ScriptCanvas::Node* node, const ScriptCanvas::SlotId& slotId)
{
auto slotIter = node->m_slotIdIteratorCache.find(slotId);
if (slotIter != node->m_slotIdIteratorCache.end())
{
ScriptCanvas::Slot* slot = &(*slotIter->second.m_slotIterator);
if (slot->IsVariableReference())
{
AZ_Assert(false, "Variable references are not supported in Unit Test methods.");
}
else
{
return slotIter->second.GetDatumIter()->ModAs<t_Value>();
}
}
return nullptr;
}
static const ScriptCanvas::Datum* GetInput_UNIT_TEST(ScriptCanvas::Node* node, AZStd::string_view slotName)
{
return GetInput_UNIT_TEST(node, node->GetSlotId(slotName));
}
static const ScriptCanvas::Datum* GetInput_UNIT_TEST(ScriptCanvas::Node* node, const ScriptCanvas::SlotId& slotId)
{
return node->FindDatum(slotId);
}
// initializes the node input to the value passed in, not a pointer to it
template<typename t_Value>
static void SetInput_UNIT_TEST(ScriptCanvas::Node* node, AZStd::string_view slotName, const t_Value& value)
{
SetInput_UNIT_TEST<t_Value>(node, node->GetSlotId(slotName), value);
}
template<typename t_Value>
static void SetInput_UNIT_TEST(ScriptCanvas::Node* node, const ScriptCanvas::SlotId& slotId, const t_Value& value)
{
node->SetInput(ScriptCanvas::Datum(value), slotId);
}
static void SetInput_UNIT_TEST(ScriptCanvas::Node* node, AZStd::string_view slotName, const ScriptCanvas::Datum& value)
{
SetInput_UNIT_TEST(node, node->GetSlotId(slotName), value);
}
static void SetInput_UNIT_TEST(ScriptCanvas::Node* node, AZStd::string_view slotName, ScriptCanvas::Datum&& value)
{
SetInput_UNIT_TEST(node, node->GetSlotId(slotName), AZStd::move(value));
}
static void SetInput_UNIT_TEST(ScriptCanvas::Node* node, const ScriptCanvas::SlotId& slotId, ScriptCanvas::Datum&& value)
{
node->SetInput(AZStd::move(value), slotId);
}
};
void VerifyReporter(const ScriptCanvasEditor::Reporter& reporter);
template<typename t_NodeType>
t_NodeType* GetTestNode([[maybe_unused]] const ScriptCanvas::ScriptCanvasId& scriptCanvasId, const AZ::EntityId& nodeID)
@@ -129,7 +62,6 @@ namespace ScriptCanvasTests
t_NodeType* node{};
SystemRequestBus::BroadcastResult(node, &SystemRequests::GetNode<t_NodeType>, nodeID);
EXPECT_TRUE(node != nullptr);
node->SetExecutionType(ExecutionType::Runtime);
return node;
}
@@ -158,7 +90,7 @@ namespace ScriptCanvasTests
EXPECT_NE(node, nullptr);
if (node)
{
NodeAccessor::SetInput_UNIT_TEST(node, "Set", value);
node->SetInput_UNIT_TEST("Set", value);
}
return node;
}
@@ -184,8 +116,6 @@ namespace ScriptCanvasTests
void DumpSlots(const ScriptCanvas::Node& node);
bool Connect(ScriptCanvas::Graph& graph, const AZ::EntityId& fromNodeID, const char* fromSlotName, const AZ::EntityId& toNodeID, const char* toSlotName, bool dumpSlotsOnFailure = true);
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> CreateRuntimeAsset(ScriptCanvas::Graph* graph);
class UnitTestEvents
: public AZ::EBusTraits
{
@@ -482,6 +412,7 @@ namespace ScriptCanvasTests
public:
virtual void Event() = 0;
virtual int Number(int number) = 0;
virtual AZStd::tuple<int, int> Numbers(int number) = 0;
virtual AZStd::string String(AZStd::string_view string) = 0;
virtual TestBehaviorContextObject Object(const TestBehaviorContextObject& vector) = 0;
};
@@ -499,6 +430,7 @@ namespace ScriptCanvasTests
, AZ::SystemAllocator
, Event
, Number
, Numbers
, String
, Object);
@@ -531,6 +463,13 @@ namespace ScriptCanvasTests
return output;
}
AZStd::tuple<int, int> Numbers(int number) override
{
AZStd::tuple<int, int> result;
CallResult(result, FN_Numbers, number);
return result;
}
AZStd::string String(AZStd::string_view input) override
{
AZStd::string output;
@@ -589,34 +528,42 @@ namespace ScriptCanvasTests
public:
AZ_CLASS_ALLOCATOR(UnitTestEntityContext, AZ::SystemAllocator, 0);
UnitTestEntityContext()
{
AzFramework::EntityContextRequestBus::Handler::BusConnect(GetOwningContextId());
AzFramework::SliceEntityOwnershipServiceRequestBus::Handler::BusConnect(GetOwningContextId());
}
UnitTestEntityContext() { AzFramework::EntityContextRequestBus::Handler::BusConnect(GetOwningContextId()); }
//// EntityIdContextQueryBus::MultiHandler
// Returns a generate Uuid which represents the UnitTest EntityContext
AzFramework::EntityContextId GetOwningContextId() override { return AzFramework::EntityContextId("{36591268-5CE9-4BC1-8277-0AB9AD528447}"); }
////
//////////////////////////////////////////////////////////////////////////
// SliceEntityOwnershipServiceRequestBus
AZ::Data::AssetId CurrentlyInstantiatingSlice() override;
bool HandleRootEntityReloadedFromStream(AZ::Entity* rootEntity, bool remapIds,
AZ::SliceComponent::EntityIdToEntityIdMap* idRemapTable) override;
AZ::SliceComponent* GetRootSlice() override;
AZ::EntityId FindLoadedEntityIdMapping(const AZ::EntityId& staticId) const;
const AZStd::unordered_map<AZ::EntityId, AZ::EntityId>& GetLoadedEntityIdMap() override;
AzFramework::SliceInstantiationTicket InstantiateSlice(const AZ::Data::Asset<AZ::Data::AssetData>& asset,
const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper& customIdMapper, const AZ::Data::AssetFilterCB& assetLoadFilter) override;
AZ::SliceComponent::SliceInstanceAddress CloneSliceInstance(AZ::SliceComponent::SliceInstanceAddress sourceInstance,
AZ::SliceComponent::EntityIdToEntityIdMap& sourceToCloneEntityIdMap) override;
void CancelSliceInstantiation(const AzFramework::SliceInstantiationTicket& ticket) override;
AzFramework::SliceInstantiationTicket GenerateSliceInstantiationTicket() override;
void SetIsDynamic(bool isDynamic) override;
const AzFramework::RootSliceAsset& GetRootAsset() const override;
//////////////////////////////////////////////////////////////////////////
//// AzFramework::SliceEntityOwnershipServiceRequests
const AzFramework::RootSliceAsset& GetRootAsset() const override {
static AzFramework::RootSliceAsset invalid;
return invalid;
}
AZ::SliceComponent* GetRootSlice() override { return {}; }
void SetIsDynamic(bool) override {}
void CancelSliceInstantiation(const AzFramework::SliceInstantiationTicket&) override {}
AzFramework::SliceInstantiationTicket GenerateSliceInstantiationTicket() override { return AzFramework::SliceInstantiationTicket(); }
bool HandleRootEntityReloadedFromStream(AZ::Entity*, bool, [[maybe_unused]] AZ::SliceComponent::EntityIdToEntityIdMap* idRemapTable = nullptr) override
{
return false;
}
const AZ::SliceComponent::EntityIdToEntityIdMap& GetLoadedEntityIdMap() override { return m_unitTestEntityIdMap; }
AZ::SliceComponent::SliceInstanceAddress CloneSliceInstance(AZ::SliceComponent::SliceInstanceAddress,
AZ::SliceComponent::EntityIdToEntityIdMap&) override
{
return{};
}
AzFramework::SliceInstantiationTicket InstantiateSlice(const AZ::Data::Asset<AZ::Data::AssetData>&,
[[maybe_unused]] const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper& customIdMapper = nullptr,
[[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilter = nullptr) override
{
return AzFramework::SliceInstantiationTicket();
}
AZ::Data::AssetId CurrentlyInstantiatingSlice() override {
return AZ::Data::AssetId();
};
AZ::Entity* CreateEntity(const char* name) override;
@@ -628,84 +575,16 @@ namespace ScriptCanvasTests
bool DestroyEntityById(AZ::EntityId entityId) override;
AZ::Entity* CloneEntity(const AZ::Entity& sourceEntity) override;
void ResetContext() override;
AZ::EntityId FindLoadedEntityIdMapping(const AZ::EntityId& staticId) const;
////
void AddEntity(AZ::EntityId entityId);
void RemoveEntity(AZ::EntityId entityId);
bool IsOwnedByThisContext(AZ::EntityId entityId) { return m_unitTestEntityIdMap.count(entityId) != 0; }
AZStd::unordered_map<AZ::EntityId, AZ::EntityId> m_unitTestEntityIdMap;
AzFramework::RootSliceAsset m_unitTestRootAsset;
AZ::SliceComponent::EntityIdToEntityIdMap m_unitTestEntityIdMap;
};
template<typename t_Operator, typename t_Operand, typename t_Value>
void BinaryOpTest(const t_Operand& lhs, const t_Operand& rhs, const t_Value& expectedResult, bool forceGraphError = false)
{
using namespace ScriptCanvas;
using namespace Nodes;
AZ::Entity graphEntity("Graph");
graphEntity.Init();
SystemRequestBus::Broadcast(&SystemRequests::CreateGraphOnEntity, &graphEntity);
auto graph = graphEntity.FindComponent<Graph>();
EXPECT_NE(nullptr, graph);
const AZ::EntityId& graphEntityId = graph->GetEntityId();
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
AZ::EntityId startID;
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
AZ::EntityId operatorID;
CreateTestNode<t_Operator>(graphUniqueId, operatorID);
AZ::EntityId lhsID;
CreateDataNode(graphUniqueId, lhs, lhsID);
AZ::EntityId rhsID;
CreateDataNode(graphUniqueId, rhs, rhsID);
AZ::EntityId printID;
auto printNode = CreateTestNode<TestNodes::TestResult>(graphUniqueId, printID);
EXPECT_TRUE(Connect(*graph, lhsID, "Get", operatorID, BinaryOperator::k_lhsName));
if (!forceGraphError)
{
EXPECT_TRUE(Connect(*graph, rhsID, "Get", operatorID, BinaryOperator::k_rhsName));
}
EXPECT_TRUE(Connect(*graph, operatorID, BinaryOperator::k_resultName, printID, "Value"));
EXPECT_TRUE(Connect(*graph, startID, "Out", operatorID, BinaryOperator::k_evaluateName));
bool isArithmetic = AZStd::is_base_of<ScriptCanvas::Nodes::ArithmeticExpression, t_Operator>::value;
if (isArithmetic)
{
EXPECT_TRUE(Connect(*graph, operatorID, BinaryOperator::k_outName, printID, "In"));
}
else
{
EXPECT_TRUE(Connect(*graph, operatorID, BinaryOperator::k_onTrue, printID, "In"));
EXPECT_TRUE(Connect(*graph, operatorID, BinaryOperator::k_onFalse, printID, "In"));
}
{
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
graph->GetEntity()->Activate();
EXPECT_EQ(graph->IsInErrorState(), forceGraphError);
}
if (!forceGraphError)
{
if (auto result = NodeAccessor::GetInput_UNIT_TEST<t_Value>(printNode, "Value"))
{
EXPECT_EQ(*result, expectedResult);
}
else
{
ADD_FAILURE();
}
}
graph->GetEntity()->Deactivate();
delete graph;
}
template<typename TBusIdType>
class TemplateEventTest
: public AZ::EBusTraits
@@ -865,5 +744,54 @@ namespace ScriptCanvasTests
AZ::u32 m_slotsAdded = 0;
AZ::u32 m_slotsRemoved = 0;
};
class TestNodeableObject
: public ScriptCanvas::Nodeable
{
public:
AZ_RTTI(TestNodeableObject, "{5FA6967F-AB4D-4077-91C9-1C2CE36733AF}", Nodeable);
AZ_CLASS_ALLOCATOR(Nodeable, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<TestNodeableObject, Nodeable>();
if (auto editContext = serializeContext->GetEditContext())
{
editContext->Class<TestNodeableObject>("TestNodeableObject", "")
;
}
}
// reflect API for the node
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
{
behaviorContext->Class<TestNodeableObject>("TestNodeableObject")
->Method("Branch", &TestNodeableObject::Branch)
;
}
}
void Branch(bool condition)
{
if (condition)
{
ExecutionOut(AZ_CRC("BranchTrue", 0xd49f121c), true, AZStd::string("called the true version!"));
}
else
{
ExecutionOut(AZ_CRC("BranchFalse", 0xaceca8bc), false, AZStd::string("called the false version!"), AZ::Vector3(1, 2, 3));
}
}
bool IsActive() const override
{
return false;
}
};
} // ScriptCanvasTests
@@ -16,52 +16,61 @@ namespace ScriptCanvasTests
{
ScriptCanvasEditor::UnitTestResult VerifyReporterEditor(const ScriptCanvasEditor::Reporter& reporter)
{
ScriptCanvasEditor::UnitTestResult result = ScriptCanvasEditor::UnitTestResult(false, true, "");
ScriptCanvasEditor::UnitTestResult result = ScriptCanvasEditor::UnitTestResult::AssumeFailure();
if (!reporter.GetScriptCanvasId().IsValid())
AZStd::string details;
if (!reporter.IsCompiled())
{
result.m_consoleOutput += "Graph is not valid\n";
details = "Graph did not compile.\n";
}
else if (reporter.IsReportFinished())
{
result.m_compiled = true;
const auto& successes = reporter.GetSuccess();
for (const auto& success : successes)
{
result.m_consoleOutput += "SUCCESS - ";
result.m_consoleOutput += success.data();
result.m_consoleOutput += "\n";
details += "SUCCESS - ";
details += success.data();
details += "\n";
}
if (!reporter.IsActivated())
{
result.m_consoleOutput += "Graph did not activate\n";
details += "Graph did not activate\n";
}
if (!reporter.IsDeactivated())
{
result.m_consoleOutput += "Graph did not deactivate\n";
// \todo track this more aggressively, graphs should deactivate
details += "Graph did not deactivate\n";
}
if (!reporter.IsErrorFree())
{
result.m_consoleOutput += "Graph had errors\n";
details += "Graph had errors\n";
}
const auto& failures = reporter.GetFailure();
for (const auto& failure : failures)
{
result.m_consoleOutput += "FAILURE - ";
result.m_consoleOutput += failure.data();
result.m_consoleOutput += "\n";
details += "FAILURE - ";
details += failure.data();
details += "\n";
}
if (!reporter.IsComplete())
{
result.m_consoleOutput += "Graph was not marked complete\n";
details += "Graph was not marked complete\n";
}
const auto& checkpoints = reporter.GetCheckpoints();
if (!checkpoints.empty())
if (checkpoints.empty())
{
details += "No checkpoints or other unit test nodes found, using them can help parse graph test failures\n";
}
else
{
AZStd::string checkpointPath = "Checkpoint Path:\n";
int i = 0;
@@ -70,28 +79,26 @@ namespace ScriptCanvasTests
{
checkpointPath += AZStd::string::format("%2d: %s\n", ++i, checkpoint.data());
}
result.m_consoleOutput += checkpointPath.data();
details += checkpointPath.data();
}
if (reporter.IsComplete() && failures.empty())
{
result.m_consoleOutput += "COMPLETE!\n";
result.m_success = true;
result.m_completed = true;
result.m_consoleOutput = "SUCCEEDED, COMPLETE!\n";
result.m_consoleOutput += details;
return result;
}
}
else
{
result.m_consoleOutput += "Graph report did not finish\n";
result.m_compiled = true;
details += "Graph report did not finish\n";
}
result.m_consoleOutput += "FAILED!\n";
result.m_success = false;
result.m_consoleOutput = "FAILED!\n";
result.m_consoleOutput += details;
return result;
}
} // namespace ScriptCanvasTests
}
@@ -0,0 +1,59 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "NodeableTestingLibrary.h"
#include "SharedDataSlotExample.h"
#include "ValuePointerReferenceExample.h"
#include <AzCore/Serialization/EditContext.h>
#include "Source/Nodes/Nodeables/SharedDataSlotExample.generated.h"
namespace ScriptCanvasTesting
{
void NodeableTestingLibrary::Reflect(AZ::ReflectContext* reflection)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
serializeContext->Class<NodeableTestingLibrary, ScriptCanvas::Library::LibraryDefinition>()
->Version(1);
AZ::EditContext* editContext = serializeContext->GetEditContext();
if (editContext)
{
editContext->Class<NodeableTestingLibrary>("Nodeable Testing", "");
}
}
}
void NodeableTestingLibrary::InitNodeRegistry(ScriptCanvas::NodeRegistry& nodeRegistry)
{
ScriptCanvas::Library::AddNodeToRegistry<NodeableTestingLibrary, ::Nodes::InputMethodSharedDataSlotExampleNode>(nodeRegistry);
ScriptCanvas::Library::AddNodeToRegistry<NodeableTestingLibrary, ::Nodes::BranchMethodSharedDataSlotExampleNode>(nodeRegistry);
ScriptCanvas::Library::AddNodeToRegistry<NodeableTestingLibrary, ::Nodes::ReturnTypeExampleNode>(nodeRegistry);
ScriptCanvas::Library::AddNodeToRegistry<NodeableTestingLibrary, ::Nodes::InputTypeExampleNode>(nodeRegistry);
ScriptCanvas::Library::AddNodeToRegistry<NodeableTestingLibrary, ::Nodes::BranchInputTypeExampleNode>(nodeRegistry);
}
AZStd::vector<AZ::ComponentDescriptor*> NodeableTestingLibrary::GetComponentDescriptors()
{
return AZStd::vector<AZ::ComponentDescriptor*>({
::Nodes::InputMethodSharedDataSlotExampleNode::CreateDescriptor(),
::Nodes::BranchMethodSharedDataSlotExampleNode::CreateDescriptor(),
::Nodes::ReturnTypeExampleNode::CreateDescriptor(),
::Nodes::InputTypeExampleNode::CreateDescriptor(),
::Nodes::BranchInputTypeExampleNode::CreateDescriptor()
});
}
}
@@ -0,0 +1,28 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <ScriptCanvas/Libraries/Libraries.h>
namespace ScriptCanvasTesting
{
struct NodeableTestingLibrary : public ScriptCanvas::Library::LibraryDefinition
{
AZ_RTTI(NodeableTestingLibrary, "{F48EF27C-EA32-455C-88AB-191A132F093B}", ScriptCanvas::Library::LibraryDefinition);
static void Reflect(AZ::ReflectContext*);
static void InitNodeRegistry(ScriptCanvas::NodeRegistry& nodeRegistry);
static AZStd::vector<AZ::ComponentDescriptor*> GetComponentDescriptors();
~NodeableTestingLibrary() override = default;
};
}
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<ScriptCanvas Include="Source/Nodes/Nodeables/SharedDataSlotExample.h" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Class Name="InputMethodSharedDataSlotExample"
QualifiedName="ScriptCanvasTesting::Nodeables::InputMethodSharedDataSlotExample"
PreferredClassName="InputMethodSharedDataSlotExample"
Base="ScriptCanvas::Nodeable"
Icon="Editor/Icons/ScriptCanvas/Placeholder.png"
Category="Tests"
GeneratePropertyFriend="True"
Namespace="None"
Description="Input Method Shared Data">
<Input Name="Append Hello" Description="" DisplayGroup="InputMethodGroup">
<Parameter Name="str" Type="const ScriptCanvas::Data::StringType&amp;"/>
<Return Name="Output" Type="ScriptCanvas::Data::StringType" Shared="true" DisplayGroup="InputMethodGroup"/>
</Input>
<Input Name="Concatenate Two" Description="" DisplayGroup="Concatenate Two">
<Parameter Name="a" Type="const ScriptCanvas::Data::StringType&amp;"/>
<Parameter Name="b" Type="const ScriptCanvas::Data::StringType&amp;"/>
<Return Name="Output" Type="ScriptCanvas::Data::StringType" Shared="true" DisplayGroup="InputMethodGroup"/>
</Input>
<Input Name="Concatenate Three" Description="" DisplayGroup="Concatenate Three">
<Parameter Name="a" Type="const ScriptCanvas::Data::StringType&amp;"/>
<Parameter Name="b" Type="const ScriptCanvas::Data::StringType&amp;"/>
<Parameter Name="c" Type="const ScriptCanvas::Data::StringType&amp;"/>
<Return Name="Output" Type="ScriptCanvas::Data::StringType" Shared="true" DisplayGroup="InputMethodGroup"/>
</Input>
</Class>
<Class Name="BranchMethodSharedDataSlotExample"
QualifiedName="ScriptCanvasTesting::Nodeables::BranchMethodSharedDataSlotExample"
PreferredClassName="BranchMethodSharedDataSlotExample"
Base="ScriptCanvas::Nodeable"
Icon="Editor/Icons/ScriptCanvas/Placeholder.png"
Category="Tests"
GeneratePropertyFriend="True"
Description="Branch Test">
<Branch Name="String Magicbox" Description="">
<Parameter Name="input" Type="ScriptCanvas::Data::NumberType" DefaultValue="0.0"/>
</Branch>
<Output Name="One String" DisplayGroup="String Magicbox">
<Parameter Name="string" Type="ScriptCanvas::Data::StringType"/>
</Output>
<Output Name="Two Strings" Type="ScriptCanvas::Data::StringType" DisplayGroup="String Magicbox">
<Parameter Name="string1" Type="ScriptCanvas::Data::StringType"/>
<Parameter Name="string2" Type="ScriptCanvas::Data::StringType"/>
</Output>
<Output Name="Three Strings" Type="Data::StringType" DisplayGroup="String Magicbox">
<Parameter Name="string1" Type="ScriptCanvas::Data::StringType"/>
<Parameter Name="string2" Type="ScriptCanvas::Data::StringType"/>
<Parameter Name="string3" Type="ScriptCanvas::Data::StringType"/>
</Output>
<Output Name="Square" Type="ScriptCanvas::Data::StringType"/>
<Output Name="Pants" Type="ScriptCanvas::Data::StringType"/>
<Output Name="Hello" Type="ScriptCanvas::Data::StringType" DisplayGroup="BranchExecutionGroup"/>
</Class>
</ScriptCanvas>
@@ -0,0 +1,50 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "SharedDataSlotExample.h"
namespace ScriptCanvasTesting
{
namespace Nodeables
{
AZStd::string InputMethodSharedDataSlotExample::AppendHello(const ScriptCanvas::Data::StringType& arg)
{
return AZStd::string::format("%sHello", arg.c_str());
}
AZStd::string InputMethodSharedDataSlotExample::ConcatenateTwo(const ScriptCanvas::Data::StringType& arg1, const ScriptCanvas::Data::StringType& arg2)
{
return AZStd::string::format("%s%s", arg1.c_str(), arg2.c_str());
}
AZStd::string InputMethodSharedDataSlotExample::ConcatenateThree(const ScriptCanvas::Data::StringType& arg1, const ScriptCanvas::Data::StringType& arg2, const ScriptCanvas::Data::StringType& arg3)
{
return AZStd::string::format("%s%s%s", arg1.c_str(), arg2.c_str(), arg3.c_str());
}
void BranchMethodSharedDataSlotExample::StringMagicbox(int arg)
{
switch (arg)
{
case 1:
CallOneString("Hello1");
break;
case 2:
CallTwoStrings("Bob", "Hello2");
break;
case 3:
CallThreeStrings("Square", "Pants", "Hello3");
break;
}
}
}
}
@@ -0,0 +1,43 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <ScriptCanvas/Core/Nodeable.h>
#include <ScriptCanvas/Core/NodeableNode.h>
#include <ScriptCanvas/CodeGen/NodeableCodegen.h>
#include <Source/Nodes/Nodeables/SharedDataSlotExample.generated.h>
namespace ScriptCanvasTesting
{
namespace Nodeables
{
class InputMethodSharedDataSlotExample
: public ScriptCanvas::Nodeable
{
SCRIPTCANVAS_NODE(InputMethodSharedDataSlotExample);
public:
};
class BranchMethodSharedDataSlotExample
: public ScriptCanvas::Nodeable
{
SCRIPTCANVAS_NODE(BranchMethodSharedDataSlotExample);
public:
void StringMagicbox(int);
};
}
}
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<ScriptCanvas Include="Source/Nodes/Nodeables/ValuePointerReferenceExample.h" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Class Name="ReturnTypeExample"
QualifiedName="ScriptCanvasTesting::Nodeables::ReturnTypeExample"
PreferredClassName="Return Type Example"
Base="ScriptCanvas::Nodeable"
Icon="Editor/Icons/ScriptCanvas/Placeholder.png"
Category="Tests"
GeneratePropertyFriend="True"
Namespace="None"
Description="Example of returning by value, pointer and reference.">
<Input Name="Return By Value" >
<Return Name="Value" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;" />
</Input>
<Input Name="Return By Pointer" >
<Return Name="Pointer" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;*" />
</Input>
<Input Name="Return By Reference" >
<Return Name="Reference" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;&amp;" />
</Input>
</Class>
<Class Name="BranchInputTypeExample"
QualifiedName="ScriptCanvasTesting::Nodeables::BranchInputTypeExample"
PreferredClassName="Branch Input Type Example"
Base="ScriptCanvas::Nodeable"
Icon="Editor/Icons/ScriptCanvas/Placeholder.png"
Category="Tests"
GeneratePropertyFriend="True"
Namespace="None"
Description="Example of branch passing as input by value, pointer and reference.">
<Input Name="Get Internal Vector" Description="">
<Return Name="Result" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;" />
</Input>
<Input Name="Branches On Input Type" Description="" DisplayGroup="Branches On Input Type">
<Parameter Name="Input Type" Type="AZStd::string" Input="True"/>
<Branch Name="By Value" Description="" DisplayGroup="Branches On Input Type">
<Return Name="Value Input" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;&amp;" DisplayGroup="Branches On Input Type"/>
</Branch>
<Branch Name="By Pointer" Description="" DisplayGroup="Branches On Input Type">
<Return Name="Pointer Input" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;*" DisplayGroup="Branches On Input Type"/>
</Branch>
</Input>
</Class>
<Class Name="InputTypeExample"
QualifiedName="ScriptCanvasTesting::Nodeables::InputTypeExample"
PreferredClassName="Input Type Example"
Base="ScriptCanvas::Nodeable"
Icon="Editor/Icons/ScriptCanvas/Placeholder.png"
Category="Tests"
GeneratePropertyFriend="True"
Namespace="None"
Description="Example of passing as input by value, pointer and reference.">
<Input Name="Clear By Value" Description="">
<Parameter Name="Value Input" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;" Input="True"/>
</Input>
<Input Name="Clear By Pointer" Description="">
<Parameter Name="Pointer Input" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;*" Input="True"/>
</Input>
<Input Name="Clear By Reference" Description="">
<Parameter Name="Reference Input" Type="AZStd::vector&lt;ScriptCanvas::Data::NumberType&gt;&amp;" Input="True"/>
</Input>
</Class>
</ScriptCanvas>
@@ -0,0 +1,70 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "ValuePointerReferenceExample.h"
namespace ScriptCanvasTesting
{
namespace Nodeables
{
AZStd::vector<ScriptCanvas::Data::NumberType> ReturnTypeExample::ReturnByValue()
{
return m_internalVector;
}
AZStd::vector<ScriptCanvas::Data::NumberType>* ReturnTypeExample::ReturnByPointer()
{
return &m_internalVector;
}
AZStd::vector<ScriptCanvas::Data::NumberType>& ReturnTypeExample::ReturnByReference()
{
return m_internalVector;
}
AZStd::vector<ScriptCanvas::Data::NumberType> BranchInputTypeExample::GetInternalVector()
{
return m_internalVector;
}
void BranchInputTypeExample::BranchesOnInputType(AZStd::string inputType)
{
if (inputType == "Value")
{
CallByValue(m_internalVector);
}
else if (inputType == "Pointer")
{
CallByPointer(&m_internalVector);
}
}
void InputTypeExample::ClearByValue(AZStd::vector<ScriptCanvas::Data::NumberType> input)
{
input.clear();
}
void InputTypeExample::ClearByPointer(AZStd::vector<ScriptCanvas::Data::NumberType>* input)
{
if (input)
{
input->clear();
}
}
void InputTypeExample::ClearByReference(AZStd::vector<ScriptCanvas::Data::NumberType>& input)
{
input.clear();
}
}
}
@@ -0,0 +1,52 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <ScriptCanvas/Core/Nodeable.h>
#include <ScriptCanvas/Core/NodeableNode.h>
#include <ScriptCanvas/CodeGen/NodeableCodegen.h>
#include <AzCore/std/containers/vector.h>
#include <Source/Nodes/Nodeables/ValuePointerReferenceExample.generated.h>
namespace ScriptCanvasTesting
{
namespace Nodeables
{
class ReturnTypeExample
: public ScriptCanvas::Nodeable
{
SCRIPTCANVAS_NODE(ReturnTypeExample);
private:
AZStd::vector<ScriptCanvas::Data::NumberType> m_internalVector{ 1.0, 2.0, 3.0 };
};
class BranchInputTypeExample
: public ScriptCanvas::Nodeable
{
SCRIPTCANVAS_NODE(BranchInputTypeExample);
private:
AZStd::vector<ScriptCanvas::Data::NumberType> m_internalVector{ 1.0, 2.0, 3.0 };
};
class InputTypeExample
: public ScriptCanvas::Nodeable
{
SCRIPTCANVAS_NODE(InputTypeExample);
};
}
}
@@ -0,0 +1,180 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "ScriptCanvasTestBus.h"
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <ScriptCanvas/Core/Attributes.h>
namespace ScriptCanvasTesting
{
class GlobalEBusHandler
: public GlobalEBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(
GlobalEBusHandler, "{CF167F12-0685-4347-A2DE-8D40186E7332}", AZ::SystemAllocator, AppendSweet, Increment, Not, Sum, Void,
GetZeroParamEvent, GetByReferenceEvent, GetByValueEvent);
AZStd::string AppendSweet(AZStd::string_view value) override
{
AZStd::string result;
CallResult(result, FN_AppendSweet, value);
return result;
}
int Increment(int value) override
{
int result;
CallResult(result, FN_Increment, value);
return result;
}
bool Not(bool value) override
{
bool result;
CallResult(result, FN_Not, value);
return result;
}
int Sum(int numberA, int numberB) override
{
int result(0);
CallResult(result, FN_Sum, numberA, numberB);
return result;
}
void Void(AZStd::string_view value) override
{
Call(FN_Void, value);
}
AZ::Event<>* GetZeroParamEvent() override
{
AZ::Event<>* azEvent = nullptr;
CallResult(azEvent, FN_GetZeroParamEvent);
return azEvent;
}
AZ::Event<AZStd::vector<AZStd::string>&>* GetByReferenceEvent() override
{
AZ::Event<AZStd::vector<AZStd::string>&>* azEvent = nullptr;
CallResult(azEvent, FN_GetByReferenceEvent);
return azEvent;
}
AZ::Event<int, bool, AZStd::string>* GetByValueEvent() override
{
AZ::Event<int, bool, AZStd::string>* azEvent = nullptr;
CallResult(azEvent, FN_GetByValueEvent);
return azEvent;
}
};
void GlobalBusTraits::Reflect(AZ::ReflectContext* context)
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
AZ::BehaviorAzEventDescription modObjectDesc, modValueDesc, modVoidDesc;
modObjectDesc.m_eventName = "OnEvent-Reference";
modObjectDesc.m_parameterNames = {"Object List"};
modValueDesc.m_eventName = "OnEvent-Value";
modValueDesc.m_parameterNames = {"A", "BB", "CCC"};
modVoidDesc.m_eventName = "OnEvent-ZeroParam";
behaviorContext->EBus<GlobalEBus>("GlobalEBus")
->Handler<GlobalEBusHandler>()
->Event("AppendSweet", &GlobalEBus::Events::AppendSweet)
->Event("Increment", &GlobalEBus::Events::Increment)
->Event("Not", &GlobalEBus::Events::Not)
->Event("Sum", &GlobalEBus::Events::Sum)
->Event("Void", &GlobalEBus::Events::Void)
->Event("GetZeroParamEvent", &GlobalEBus::Events::GetZeroParamEvent)
->Attribute(AZ::Script::Attributes::AzEventDescription, modVoidDesc)
->Event("GetByReferenceEvent", &GlobalEBus::Events::GetByReferenceEvent)
->Attribute(AZ::Script::Attributes::AzEventDescription, modObjectDesc)
->Event("GetByValueEvent", &GlobalEBus::Events::GetByValueEvent)
->Attribute(AZ::Script::Attributes::AzEventDescription, modValueDesc);
}
}
class LocalEBusHandler
: public LocalEBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(
LocalEBusHandler, "{308650EE-061D-4090-A7FB-471885C8B6A5}", AZ::SystemAllocator, AppendSweet, Increment, Not, Void);
AZStd::string AppendSweet(AZStd::string_view value) override
{
AZStd::string result;
CallResult(result, FN_AppendSweet, value);
return result;
}
int Increment(int value) override
{
int result;
CallResult(result, FN_Increment, value);
return result;
}
bool Not(bool value) override
{
bool result;
CallResult(result, FN_Not, value);
return result;
}
void Void(AZStd::string_view value)
{
Call(FN_Void, value);
}
};
void LocalBusTraits::Reflect(AZ::ReflectContext* context)
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<LocalEBus>("LocalEBus")
->Handler<LocalEBusHandler>()
->Event("AppendSweet", &LocalEBus::Events::AppendSweet)
->Event("Increment", &LocalEBus::Events::Increment)
->Event("Not", &LocalEBus::Events::Not)
->Event("Void", &LocalEBus::Events::Void);
}
}
void NativeHandlingOnlyBusTraits::Reflect(AZ::ReflectContext* context)
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<NativeHandlingOnlyEBus>("NativeHandlingOnlyEBus")
->Event("AppendSweet", &NativeHandlingOnlyEBus::Events::AppendSweet)
->Event("Increment", &NativeHandlingOnlyEBus::Events::Increment)
->Event("Not", &NativeHandlingOnlyEBus::Events::Not)
->Event("TwistTypeEntityId", &NativeHandlingOnlyEBus::Events::TwistTypeEntityId)
->Event("TwistTypeVector3", &NativeHandlingOnlyEBus::Events::TwistTypeVector3)
->Event("TwistTupleEntityId", &NativeHandlingOnlyEBus::Events::TwistTupleEntityId)
->Event("TwistTupleVector3", &NativeHandlingOnlyEBus::Events::TwistTupleVector3)
->Event("Void", &NativeHandlingOnlyEBus::Events::Void);
}
}
}
@@ -0,0 +1,107 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/string/string_view.h>
#include <ScriptCanvas/Data/Data.h>
namespace AZ
{
class ReflectContext;
}
namespace ScriptCanvasTesting
{
class GlobalBusTraits : public AZ::EBusTraits
{
public:
AZ_TYPE_INFO(GlobalBusTraits, "{DED849D7-CF17-408B-8D87-E31FC7D3CEC4}");
static void Reflect(AZ::ReflectContext* context);
virtual AZStd::string AppendSweet(AZStd::string_view) = 0;
virtual int Increment(int value) = 0;
virtual bool Not(bool value) = 0;
virtual int Sum(int numberA, int numberB) = 0;
virtual void Void(AZStd::string_view) = 0;
virtual AZ::Event<>* GetZeroParamEvent() = 0;
virtual AZ::Event<AZStd::vector<AZStd::string>&>* GetByReferenceEvent() = 0;
virtual AZ::Event<int, bool, AZStd::string>* GetByValueEvent() = 0;
};
using GlobalEBus = AZ::EBus<GlobalBusTraits>;
class LocalBusTraits : public AZ::EBusTraits
{
public:
AZ_TYPE_INFO(LocalBusTraits, "{749B6949-CBBB-44D9-A57D-9973DC88E639}");
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = double;
static void Reflect(AZ::ReflectContext* context);
virtual AZStd::string AppendSweet(AZStd::string_view) = 0;
virtual int Increment(int value) = 0;
virtual bool Not(bool value) = 0;
virtual void Void(AZStd::string_view) = 0;
};
using LocalEBus = AZ::EBus<LocalBusTraits>;
class NativeHandlingOnlyBusTraits : public AZ::EBusTraits
{
public:
AZ_TYPE_INFO(NativeHandlingOnlyBusTraits, "{5AED48A7-3E16-41F6-B1C0-4E1FBBA84F83}");
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = AZ::EntityId;
static void Reflect(AZ::ReflectContext* context);
virtual AZStd::string AppendSweet(AZStd::string_view) = 0;
virtual int Increment(int value) = 0;
virtual AZ::EntityId TwistTypeEntityId() = 0;
virtual AZ::Vector3 TwistTypeVector3() = 0;
virtual AZStd::tuple<AZ::EntityId, bool> TwistTupleEntityId() = 0;
virtual AZStd::tuple<AZ::Vector3, bool> TwistTupleVector3() = 0;
virtual bool Not(bool value) = 0;
virtual void Void(AZStd::string_view) = 0;
};
using NativeHandlingOnlyEBus = AZ::EBus<NativeHandlingOnlyBusTraits>;
class TestTupleMethods
{
public:
AZ_TYPE_INFO(TestTupleMethods, "{E794CE93-7AC6-476E-BF10-B107A2E4D807}");
static AZStd::tuple<ScriptCanvas::Data::Vector3Type, ScriptCanvas::Data::StringType, ScriptCanvas::Data::BooleanType> Three(
const ScriptCanvas::Data::Vector3Type& v, const ScriptCanvas::Data::StringType& s, const ScriptCanvas::Data::BooleanType& b)
{
return AZStd::make_tuple(v, s, b);
}
static void Reflect(AZ::ReflectContext* context)
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<TestTupleMethods>("TestTupleMethods")->Method("Three", &TestTupleMethods::Three);
}
}
};
}
@@ -15,6 +15,7 @@
#include <AzCore/Module/Module.h>
#include <ScriptCanvasTestingSystemComponent.h>
#include <Editor/Framework/ScriptCanvasTraceUtilities.h>
#include <Source/Nodes/Nodeables/NodeableTestingLibrary.h>
namespace ScriptCanvasTesting
{
@@ -33,6 +34,9 @@ namespace ScriptCanvasTesting
ScriptCanvasTestingSystemComponent::CreateDescriptor(),
TraceMessageComponent::CreateDescriptor(),
});
AZStd::vector<AZ::ComponentDescriptor*> componentDescriptors(NodeableTestingLibrary::GetComponentDescriptors());
m_descriptors.insert(m_descriptors.end(), componentDescriptors.begin(), componentDescriptors.end());
}
/**
@@ -12,11 +12,13 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <Framework/ScriptCanvasTestVerify.h>
#include "ScriptCanvasTestingSystemComponent.h"
#include "ScriptCanvasTestBus.h"
#include "Framework/ScriptCanvasTestVerify.h"
#include "Nodes/BehaviorContextObjectTestNode.h"
#include <Nodes/BehaviorContextObjectTestNode.h>
#include <Source/Nodes/Nodeables/NodeableTestingLibrary.h>
namespace ScriptCanvasTesting
{
@@ -38,7 +40,13 @@ namespace ScriptCanvasTesting
}
}
NodeableTestingLibrary::Reflect(context);
ScriptCanvasTestingNodes::BehaviorContextObjectTest::Reflect(context);
ScriptCanvasTesting::GlobalBusTraits::Reflect(context);
ScriptCanvasTesting::LocalBusTraits::Reflect(context);
ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(context);
ScriptCanvasTesting::TestTupleMethods::Reflect(context);
}
void ScriptCanvasTestingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
@@ -63,6 +71,7 @@ namespace ScriptCanvasTesting
void ScriptCanvasTestingSystemComponent::Init()
{
NodeableTestingLibrary::InitNodeRegistry(ScriptCanvas::GetNodeRegistry().Get());
}
void ScriptCanvasTestingSystemComponent::Activate()
@@ -37,7 +37,7 @@ namespace ScriptCanvasTesting
protected:
////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
// AZ::Component...
void Init() override;
void Activate() override;
void Deactivate() override;