The Great ScriptCanvas Purge, Part IV

Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com>
This commit is contained in:
chcurran
2021-07-06 13:13:16 -07:00
parent fa7accf2dc
commit 360236b89e
173 changed files with 131 additions and 6154 deletions
@@ -19,7 +19,6 @@ namespace AZ
namespace ScriptCanvas
{
class ScriptCanvasFunctionAsset;
class RuntimeAsset;
class SubgraphInterfaceAsset;
}
@@ -27,7 +26,6 @@ namespace ScriptCanvas
namespace ScriptCanvasEditor
{
class ScriptCanvasAsset;
class ScriptCanvasFunctionAsset;
class EditorAssetConversionBusTraits
: public AZ::EBusTraits
@@ -36,10 +34,8 @@ namespace ScriptCanvasEditor
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
virtual AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> LoadAsset(AZStd::string_view graphPath) = 0;
virtual AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset> LoadFunctionAsset(AZStd::string_view graphPath) = 0;
virtual AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset, AZStd::string_view graphPathForRawLuaFile) = 0;
virtual AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset) = 0;
virtual AZ::Outcome<AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>, AZStd::string> CreateFunctionRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>& editAsset) = 0;
};
using EditorAssetConversionBus = AZ::EBus<EditorAssetConversionBusTraits>;
@@ -28,8 +28,6 @@ AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
AZ_POP_DISABLE_WARNING
#include <ScriptCanvas/Asset/Functions/ScriptCanvasFunctionAsset.h>
#include <ScriptCanvas/Assets/Functions/ScriptCanvasFunctionAssetHandler.h>
#include <ScriptCanvas/Asset/Functions/RuntimeFunctionAssetHandler.h>
namespace ScriptCanvasEditor
@@ -77,7 +75,6 @@ namespace ScriptCanvasEditor
void EditorAssetSystemComponent::Activate()
{
m_editorAssetRegistry.Register<ScriptCanvasAsset, ScriptCanvasAssetHandler, ScriptCanvasAssetDescription>();
m_editorAssetRegistry.Register<ScriptCanvasEditor::ScriptCanvasFunctionAsset, ScriptCanvasFunctionAssetHandler, ScriptCanvasEditor::ScriptCanvasFunctionDescription>();
m_editorAssetRegistry.Register<ScriptCanvas::SubgraphInterfaceAsset, ScriptCanvas::SubgraphInterfaceAssetHandler, ScriptCanvas::SubgraphInterfaceAssetDescription>();
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect();
@@ -131,30 +128,11 @@ namespace ScriptCanvasEditor
}
}
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset> EditorAssetSystemComponent::LoadFunctionAsset(AZStd::string_view graphPath)
{
auto outcome = ScriptCanvasBuilder::LoadEditorFunctionAsset(graphPath);
if (outcome.IsSuccess())
{
return outcome.GetValue();
}
else
{
return {};
}
}
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> EditorAssetSystemComponent::CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset)
{
return ScriptCanvasBuilder::CreateRuntimeAsset(editAsset);
}
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>, AZStd::string> EditorAssetSystemComponent::CreateFunctionRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>& editAsset)
{
return ScriptCanvasBuilder::CreateRuntimeFunctionAsset(editAsset);
}
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> EditorAssetSystemComponent::CreateLuaAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset, AZStd::string_view graphPathForRawLuaFile)
{
return ScriptCanvasBuilder::CreateLuaAsset(editAsset->GetScriptCanvasEntity(), editAsset->GetId(), graphPathForRawLuaFile);
@@ -22,7 +22,6 @@
namespace ScriptCanvasEditor
{
class ScriptCanvasAsset;
class ScriptCanvasFunctionAsset;
class EditorAssetSystemComponent
: public AZ::Component
@@ -57,9 +56,7 @@ namespace ScriptCanvasEditor
//////////////////////////////////////////////////////////////////////////
// EditorAssetConversionBus::Handler...
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> LoadAsset(AZStd::string_view graphPath) override;
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset> LoadFunctionAsset(AZStd::string_view graphPath) override;
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset) override;
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>, AZStd::string> CreateFunctionRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>& editAsset) override;
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset, AZStd::string_view graphPathForRawLuaFile) override;
//////////////////////////////////////////////////////////////////////////
@@ -13,10 +13,8 @@
#include <Builder/ScriptCanvasBuilder.h>
#include <Builder/ScriptCanvasBuilderComponent.h>
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <ScriptCanvas/Asset/Functions/RuntimeFunctionAssetHandler.h>
#include <ScriptCanvas/Asset/Functions/ScriptCanvasFunctionAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
#include <ScriptCanvas/Assets/Functions/ScriptCanvasFunctionAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Utils/BehaviorContextUtils.h>
@@ -50,7 +48,6 @@ namespace ScriptCanvasBuilder
SharedHandlers HandleAssetTypes()
{
SharedHandlers handlers;
handlers.m_editorFunctionAssetHandler = RegisterHandler<ScriptCanvasEditor::ScriptCanvasFunctionAsset, ScriptCanvasEditor::ScriptCanvasFunctionAssetHandler>("scriptcanvas_fn", false);
handlers.m_editorAssetHandler = RegisterHandler<ScriptCanvasEditor::ScriptCanvasAsset, ScriptCanvasEditor::ScriptCanvasAssetHandler>("scriptcanvas", false);
handlers.m_subgraphInterfaceHandler = RegisterHandler<ScriptCanvas::SubgraphInterfaceAsset, ScriptCanvas::SubgraphInterfaceAssetHandler>("scriptcanvas_fn_compiled", true);
handlers.m_runtimeAssetHandler = RegisterHandler<ScriptCanvas::RuntimeAsset, JobDependencyVerificationHandler>("scriptcanvas_compiled", true);
@@ -123,7 +120,6 @@ namespace ScriptCanvasBuilder
builderDescriptor.m_productsToKeepOnFailure[s_scriptCanvasProcessJobKey] = { AZ_CRC("SubgraphInterface", 0xdfe6dc72) };
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, builderDescriptor);
ScriptCanvas::Grammar::RequestBus::Handler::BusConnect();
AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::RegisterSourceAssetType, azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>(), ScriptCanvasEditor::ScriptCanvasFunctionAsset::Description::GetFileFilter<ScriptCanvasEditor::ScriptCanvasFunctionAsset>());
}
m_sharedHandlers = HandleAssetTypes();
@@ -36,8 +36,8 @@ namespace ScriptCanvasEditor
{
class Graph;
class ScriptCanvasAsset;
class ScriptCanvasFunctionAsset;
}
namespace ScriptCanvasBuilder
{
constexpr const char* s_scriptCanvasBuilder = "ScriptCanvasBuilder";
@@ -122,8 +122,6 @@ namespace ScriptCanvasBuilder
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& asset);
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>, AZStd::string> CreateRuntimeFunctionAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>& asset);
AZ::Outcome<ScriptCanvas::GraphData, AZStd::string> CompileGraphData(AZ::Entity* scriptCanvasEntity);
AZ::Outcome<ScriptCanvas::VariableData, AZStd::string> CompileVariableData(AZ::Entity* scriptCanvasEntity);
@@ -134,8 +132,6 @@ namespace ScriptCanvasBuilder
AZ::Outcome<AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>, AZStd::string> LoadEditorAsset(AZStd::string_view graphPath, AZ::Data::AssetId assetId, AZ::Data::AssetFilterCB assetFilterCB = {});
AZ::Outcome<AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>, AZStd::string> LoadEditorFunctionAsset(AZStd::string_view graphPath);
AZ::Outcome<ScriptCanvas::Grammar::AbstractCodeModelConstPtr, AZStd::string> ParseGraph(AZ::Entity& buildEntity, AZStd::string_view graphPath);
AZ::Outcome<void, AZStd::string> ProcessTranslationJob(ProcessTranslationJobInput& input);
@@ -8,7 +8,6 @@
#include "precompiled.h"
#include <Asset/AssetDescription.h>
#include <Asset/Functions/ScriptCanvasFunctionAsset.h>
#include <AssetBuilderSDK/SerializationDependencies.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/IO/FileIO.h>
@@ -160,18 +159,6 @@ namespace ScriptCanvasBuilder
return AZ::Success(runtimeAsset);
}
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>, AZStd::string> CreateRuntimeFunctionAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>& editAsset)
{
// Flush asset manager events to ensure no asset references are held by closures queued on Ebuses.
AZ::Data::AssetManager::Instance().DispatchEvents();
auto runtimeAssetId = editAsset.GetId();
runtimeAssetId.m_subId = AZ_CRC("SubgraphInterface", 0xdfe6dc72);
AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset> runtimeAsset;
runtimeAsset.Create(runtimeAssetId);
return AZ::Success(runtimeAsset);
}
AZ::Outcome<ScriptCanvas::GraphData, AZStd::string> CompileGraphData(AZ::Entity* scriptCanvasEntity)
{
typedef AZStd::pair< ScriptCanvas::Node*, AZ::Entity* > NodeEntityPair;
@@ -452,48 +439,6 @@ namespace ScriptCanvasBuilder
return AZ::Success(asset);
}
AZ::Outcome<AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>, AZStd::string> LoadEditorFunctionAsset(AZStd::string_view filePath)
{
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
// Read the asset into a memory buffer, then hand ownership of the buffer to assetDataStream
{
AZ::IO::FileIOStream stream(filePath.data(), AZ::IO::OpenMode::ModeRead);
if (!AZ::IO::RetryOpenStream(stream))
{
return AZ::Failure(AZStd::string::format("File failed to open: %s", filePath.data()));
}
AZStd::vector<AZ::u8> fileBuffer(stream.GetLength());
size_t bytesRead = stream.Read(fileBuffer.size(), fileBuffer.data());
if (bytesRead != stream.GetLength())
{
return AZ::Failure(AZStd::string::format("File failed to open: %s", filePath.data()));
}
assetDataStream->Open(AZStd::move(fileBuffer));
}
AZ::IO::FileIOStream ioStream;
if (!ioStream.Open(filePath.data(), AZ::IO::OpenMode::ModeRead))
{
return AZ::Failure(AZStd::string::format("File failed to open: %s", filePath.data()));
}
ScriptCanvasEditor::ScriptCanvasFunctionAssetHandler editorAssetHandler;
AZ::SerializeContext* context{};
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset> asset;
asset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()));
if (editorAssetHandler.LoadAssetData(asset, assetDataStream, AZ::Data::AssetFilterCB{}) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
{
return AZ::Failure(AZStd::string::format("Failed to load ScriptCavas Function asset: %s", filePath.data()));
}
return AZ::Success(asset);
}
ScriptCanvasEditor::Graph* PrepareSourceGraph(AZ::Entity* const buildEntity)
{
auto sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvasEditor::Graph>(buildEntity);
@@ -1,338 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "precompiled.h"
#include "platform.h"
#include <Asset/AssetDescription.h>
#include <Asset/Functions/ScriptCanvasFunctionAsset.h>
#include <AssetBuilderSDK/SerializationDependencies.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/IOUtils.h>
#include <AzCore/Math/Uuid.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/string/conversions.h>
#include <AzFramework/Script/ScriptComponent.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <ScriptCanvas/Asset/Functions/RuntimeFunctionAssetHandler.h>
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
#include <ScriptCanvas/Assets/Functions/ScriptCanvasFunctionAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Core/Connection.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Grammar/AbstractCodeModel.h>
#include <ScriptCanvas/Results/ErrorText.h>
#include <ScriptCanvas/Utils/BehaviorContextUtils.h>
namespace ScriptCanvasBuilder
{
void FunctionWorker::Activate(const AssetHandlers& handlers)
{
m_editorAssetHandler = handlers.m_editorFunctionAssetHandler;
m_runtimeAssetHandler = handlers.m_runtimeAssetHandler;
m_subgraphInterfaceHandler = handlers.m_subgraphInterfaceHandler;
}
void FunctionWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) const
{
AZ_TracePrintf(s_scriptCanvasBuilder, "Start Creating Job");
AZStd::string fullPath;
AzFramework::StringFunc::Path::ConstructFull(request.m_watchFolder.data(), request.m_sourceFile.data(), fullPath, false);
AzFramework::StringFunc::Path::Normalize(fullPath);
if (!m_editorAssetHandler)
{
AZ_Error(s_scriptCanvasBuilder, false, R"(CreateJobs for %s failed because the ScriptCanvas Editor Asset handler is missing.)", fullPath.data());
}
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
// Read the asset into a memory buffer, then hand ownership of the buffer to assetDataStream
{
AZ::IO::FileIOStream stream(fullPath.c_str(), AZ::IO::OpenMode::ModeRead);
if (!AZ::IO::RetryOpenStream(stream))
{
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data());
return;
}
AZStd::vector<AZ::u8> fileBuffer(stream.GetLength());
size_t bytesRead = stream.Read(fileBuffer.size(), fileBuffer.data());
if (bytesRead != stream.GetLength())
{
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be read.", fullPath.data());
return;
}
assetDataStream->Open(AZStd::move(fileBuffer));
}
m_sourceDependencies.clear();
auto assetFilter = [&response, this](const AZ::Data::AssetFilterInfo& filterInfo)
{
if (filterInfo.m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>() ||
filterInfo.m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>() ||
filterInfo.m_assetType == azrtti_typeid<ScriptEvents::ScriptEventsAsset>() ||
filterInfo.m_assetType == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>()) // this required, since nodes reference this, rather than the editor asset
{
AssetBuilderSDK::SourceFileDependency dependency;
dependency.m_sourceFileDependencyUUID = filterInfo.m_assetId.m_guid;
response.m_sourceFileDependencyList.push_back(dependency);
}
// Asset filter always returns false to prevent parsing dependencies, but makes note of the script canvas dependencies
return false;
};
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset> asset;
asset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()));
ScriptCanvasEditor::ScriptCanvasFunctionAssetHandler* functionAssetHandler = azrtti_cast<ScriptCanvasEditor::ScriptCanvasFunctionAssetHandler*>(m_editorAssetHandler);
if (functionAssetHandler->LoadAssetData(asset, assetDataStream, assetFilter) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
{
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the asset data could not be loaded from the file", fullPath.data());
return;
}
// Flush asset database events to ensure no asset references are held by closures queued on Ebuses.
AZ::Data::AssetManager::Instance().DispatchEvents();
auto* scriptCanvasEntity = asset.Get()->GetScriptCanvasEntity();
auto* sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvasEditor::Graph>(scriptCanvasEntity);
AZ_Assert(sourceGraph, "Graph component is missing from entity.");
size_t fingerprint = 0;
const AZStd::set<AZ::Entity*> sortedEntities(sourceGraph->GetGraphData()->m_nodes.begin(), sourceGraph->GetGraphData()->m_nodes.end());
for (auto& nodeEntity : sortedEntities)
{
if (auto nodeComponent = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Node>(nodeEntity))
{
AZStd::hash_combine(fingerprint, nodeComponent->GenerateFingerprint());
}
}
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
for (const AssetBuilderSDK::PlatformInfo& info : request.m_enabledPlatforms)
{
if (info.HasTag("tools"))
{
AssetBuilderSDK::JobDescriptor copyDescriptor;
copyDescriptor.m_priority = 2;
copyDescriptor.m_critical = true;
copyDescriptor.m_jobKey = s_scriptCanvasCopyJobKey;
copyDescriptor.SetPlatformIdentifier(info.m_identifier.c_str());
copyDescriptor.m_additionalFingerprintInfo = AZStd::string(GetFingerprintString()).append("|").append(AZStd::to_string(static_cast<AZ::u64>(fingerprint)));
response.m_createJobOutputs.push_back(copyDescriptor);
}
AssetBuilderSDK::JobDescriptor jobDescriptor;
jobDescriptor.m_priority = 2;
jobDescriptor.m_critical = true;
jobDescriptor.m_jobKey = s_scriptCanvasProcessJobKey;
jobDescriptor.SetPlatformIdentifier(info.m_identifier.c_str());
jobDescriptor.m_additionalFingerprintInfo = AZStd::string(GetFingerprintString()).append("|").append(AZStd::to_string(static_cast<AZ::u64>(fingerprint)));
// Function process job needs to wait until its dependency asset job finished
for (const auto& sourceDependency : response.m_sourceFileDependencyList)
{
AssetBuilderSDK::JobDependency jobDep(s_scriptCanvasBuilder, info.m_identifier.c_str(), AssetBuilderSDK::JobDependencyType::OrderOnce, sourceDependency);
jobDescriptor.m_jobDependencyList.emplace_back(jobDep);
}
response.m_createJobOutputs.push_back(jobDescriptor);
}
#endif
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
AZ_TracePrintf(s_scriptCanvasBuilder, "Finish Creating Job");
}
const char* FunctionWorker::GetFingerprintString() const
{
if (m_fingerprintString.empty())
{
// compute it the first time
const AZStd::string runtimeAssetTypeId = azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>().ToString<AZStd::string>();
m_fingerprintString = AZStd::string::format("%i%s", GetVersionNumber(), runtimeAssetTypeId.c_str());
}
return m_fingerprintString.c_str();
}
int FunctionWorker::GetVersionNumber() const
{
return GetBuilderVersion();
}
AZ::Uuid FunctionWorker::GetUUID()
{
return AZ::Uuid::CreateString("{7227E0E1-4113-456A-877B-B2276ACB292B}");
}
void FunctionWorker::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) const
{
AZ_TracePrintf(s_scriptCanvasBuilder, "Start Processing Job");
// A runtime script canvas component is generated, which creates a .scriptcanvas_compiled file
AZStd::string fullPath;
AZStd::string fileNameOnly;
AzFramework::StringFunc::Path::GetFullFileName(request.m_sourceFile.c_str(), fileNameOnly);
fullPath = request.m_fullPath.c_str();
AzFramework::StringFunc::Path::Normalize(fullPath);
bool pathFound = false;
AZStd::string relativePath;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
( pathFound
, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath
, request.m_fullPath.c_str(), relativePath);
if (!pathFound)
{
AZ_Error(s_scriptCanvasBuilder, false, "Failed to get engine relative path from %s", request.m_fullPath.c_str());
return;
}
if (!m_editorAssetHandler)
{
AZ_Error(s_scriptCanvasBuilder, false, R"(Exporting of .scriptcanvas for "%s" file failed as no editor asset handler was registered for script canvas. The ScriptCanvas Gem might not be enabled.)", fullPath.data());
return;
}
if (!m_runtimeAssetHandler)
{
AZ_Error(s_scriptCanvasBuilder, false, R"(Exporting of .scriptcanvas for "%s" file failed as no runtime asset handler was registered for script canvas.)", fullPath.data());
return;
}
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
// Read the asset into a memory buffer, then hand ownership of the buffer to assetDataStream
{
AZ::IO::FileIOStream stream(fullPath.data(), AZ::IO::OpenMode::ModeRead);
if (!AZ::IO::RetryOpenStream(stream))
{
AZ_Warning(s_scriptCanvasBuilder, false, "Exporting of .scriptcanvas for \"%s\" failed because the source file could not be opened.", fullPath.c_str());
return;
}
AZStd::vector<AZ::u8> fileBuffer(stream.GetLength());
size_t bytesRead = stream.Read(fileBuffer.size(), fileBuffer.data());
if (bytesRead != stream.GetLength())
{
AZ_Warning(s_scriptCanvasBuilder, false, "Exporting of .scriptcanvas for \"%s\" failed because the source file could not be opened.", fullPath.c_str());
return;
}
assetDataStream->Open(AZStd::move(fileBuffer));
}
AZ::SerializeContext* context{};
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset> asset;
asset.Create(request.m_sourceFileUUID);
ScriptCanvasEditor::ScriptCanvasFunctionAssetHandler* functionAssetHandler = azrtti_cast<ScriptCanvasEditor::ScriptCanvasFunctionAssetHandler*>(m_editorAssetHandler);
if (functionAssetHandler->LoadAssetData(asset, assetDataStream, nullptr) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
{
AZ_Error(s_scriptCanvasBuilder, false, R"(Loading of ScriptCanvas asset for source file "%s" has failed)", fullPath.data());
return;
}
// Flush asset manager events to ensure no asset references are held by closures queued on Ebuses.
AZ::Data::AssetManager::Instance().DispatchEvents();
AZStd::string runtimeScriptCanvasOutputPath;
AzFramework::StringFunc::Path::Join(request.m_tempDirPath.c_str(), fileNameOnly.c_str(), runtimeScriptCanvasOutputPath, true, true);
AzFramework::StringFunc::Path::ReplaceExtension(runtimeScriptCanvasOutputPath, ScriptCanvas::SubgraphInterfaceAsset::GetFileExtension());
if (request.m_jobDescription.m_jobKey == s_scriptCanvasCopyJobKey)
{
// ScriptCanvas Editor Asset Copy job
// The SubID is zero as this represents the main asset
AssetBuilderSDK::JobProduct jobProduct;
jobProduct.m_productFileName = fullPath;
jobProduct.m_productAssetType = azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>();
jobProduct.m_productSubID = 0;
jobProduct.m_dependenciesHandled = true;
response.m_outputProducts.push_back(AZStd::move(jobProduct));
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
}
else
{
// force load all dependencies into memory
for (auto& dependency : m_sourceDependencies)
{
AZ::Data::AssetManager::Instance().GetAsset(dependency.GetId(), dependency.GetType(), AZ::Data::AssetLoadBehavior::PreLoad);
}
AZ::Entity* buildEntity = asset.Get()->GetScriptCanvasEntity();
ProcessTranslationJobInput input;
input.assetID = AZ::Data::AssetId(request.m_sourceFileUUID, AZ_CRC("RuntimeData", 0x163310ae));
input.request = &request;
input.response = &response;
input.runtimeScriptCanvasOutputPath = runtimeScriptCanvasOutputPath;
input.assetHandler = m_runtimeAssetHandler;
input.buildEntity = buildEntity;
input.fullPath = fullPath;
input.fileNameOnly = fileNameOnly;
input.namespacePath = relativePath;
input.saveRawLua = true;
auto translationOutcome = ProcessTranslationJob(input);
if (translationOutcome.IsSuccess())
{
AzFramework::StringFunc::Path::ReplaceExtension(input.runtimeScriptCanvasOutputPath, ScriptCanvas::RuntimeAsset::GetFileExtension());
auto saveRuntimAssetOutcome = SaveRuntimeAsset(input, input.runtimeDataOut);
if (saveRuntimAssetOutcome.IsSuccess())
{
// \todo this file is only required on PC editor builds, cull it in packaging, here or wherever appropriate
AzFramework::StringFunc::Path::StripExtension(fileNameOnly);
ScriptCanvas::SubgraphInterfaceData functionInterface;
functionInterface.m_name = fileNameOnly;
functionInterface.m_interface = AZStd::move(input.interfaceOut);
// save function interface
input.assetHandler = m_subgraphInterfaceHandler;
AzFramework::StringFunc::Path::ReplaceExtension(input.runtimeScriptCanvasOutputPath, ScriptCanvas::SubgraphInterfaceAsset::GetFileExtension());
auto saveInterfaceOutcome = SaveSubgraphInterface(input, functionInterface);
if (saveInterfaceOutcome.IsSuccess())
{
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
}
else
{
AZ_Error(s_scriptCanvasBuilder, false, saveInterfaceOutcome.GetError().data());
}
}
else
{
AZ_Error(s_scriptCanvasBuilder, false, saveRuntimAssetOutcome.GetError().data());
}
}
else if (AzFramework::StringFunc::Find(translationOutcome.GetError().data(), ScriptCanvas::ParseErrors::SourceUpdateRequired) != AZStd::string::npos)
{
AZ_Warning(s_scriptCanvasBuilder, false, ScriptCanvas::ParseErrors::SourceUpdateRequired);
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
}
else if (AzFramework::StringFunc::Find(fileNameOnly, s_unitTestParseErrorPrefix) != AZStd::string::npos)
{
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
}
else
{
AZ_Warning(s_scriptCanvasBuilder, false, translationOutcome.GetError().data());
}
}
AZ_TracePrintf(s_scriptCanvasBuilder, "Finish Processing Job");
}
}
@@ -1,157 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "precompiled.h"
#include <ScriptCanvas/Assets/Functions/ScriptCanvasFunctionAssetHandler.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
#include <Core/ScriptCanvasBus.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorScriptCanvasComponent.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <GraphCanvas/GraphCanvasBus.h>
#include <AzCore/IO/GenericStreams.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/Serialization/Utils.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/std/string/string_view.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <ScriptCanvas/Asset/Functions/ScriptCanvasFunctionAsset.h>
namespace ScriptCanvasEditor
{
ScriptCanvasFunctionAssetHandler::ScriptCanvasFunctionAssetHandler(AZ::SerializeContext* context)
: ScriptCanvasAssetHandler(context)
{
AZ::AssetTypeInfoBus::MultiHandler::BusConnect(azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>());
}
ScriptCanvasFunctionAssetHandler::~ScriptCanvasFunctionAssetHandler()
{
AZ::AssetTypeInfoBus::MultiHandler::BusDisconnect();
}
AZ::Data::AssetPtr ScriptCanvasFunctionAssetHandler::CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type)
{
AZ_UNUSED(type);
ScriptCanvasEditor::ScriptCanvasFunctionAsset* assetData = aznew ScriptCanvasEditor::ScriptCanvasFunctionAsset(id);
AZ::Entity* scriptCanvasEntity = aznew AZ::Entity(ScriptCanvas::AssetDescription::GetEntityName<ScriptCanvasEditor::ScriptCanvasFunctionAsset>());
SystemRequestBus::Broadcast(&SystemRequests::CreateEditorComponentsOnEntity, scriptCanvasEntity, azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>());
assetData->m_cachedComponent = scriptCanvasEntity->CreateComponent<ScriptCanvasEditor::ScriptCanvasFunctionDataComponent>();
assetData->SetScriptCanvasEntity(scriptCanvasEntity);
return assetData;
}
AZ::Data::AssetHandler::LoadResult ScriptCanvasFunctionAssetHandler::LoadAssetData(
const AZ::Data::Asset<AZ::Data::AssetData>& asset,
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
const AZ::Data::AssetFilterCB& assetLoadFilterCB)
{
ScriptCanvasEditor::ScriptCanvasFunctionAsset* scriptCanvasAsset = asset.GetAs<ScriptCanvasEditor::ScriptCanvasFunctionAsset>();
AZ_Assert(m_serializeContext, "ScriptCanvasFunctionAssetHandler needs to be initialized with a SerializeContext");
if (scriptCanvasAsset)
{
stream->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
bool loadSuccess = AZ::Utils::LoadObjectFromStreamInPlace(*stream, scriptCanvasAsset->GetScriptCanvasData(), m_serializeContext, AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES));
if (loadSuccess)
{
scriptCanvasAsset->m_cachedComponent = scriptCanvasAsset->GetScriptCanvasData().GetScriptCanvasEntity()->FindComponent<ScriptCanvasEditor::ScriptCanvasFunctionDataComponent>();
}
return loadSuccess ? AZ::Data::AssetHandler::LoadResult::LoadComplete : AZ::Data::AssetHandler::LoadResult::Error;
}
return AZ::Data::AssetHandler::LoadResult::Error;
}
bool ScriptCanvasFunctionAssetHandler::SaveAssetData(const AZ::Data::Asset<AZ::Data::AssetData>& asset, AZ::IO::GenericStream* stream)
{
return SaveAssetData(asset.GetAs<ScriptCanvasEditor::ScriptCanvasFunctionAsset>(), stream);
}
bool ScriptCanvasFunctionAssetHandler::SaveAssetData(const ScriptCanvasEditor::ScriptCanvasFunctionAsset* assetData, AZ::IO::GenericStream* stream)
{
return SaveAssetData(assetData, stream, AZ::DataStream::ST_XML);
}
bool ScriptCanvasFunctionAssetHandler::SaveAssetData(const ScriptCanvasEditor::ScriptCanvasFunctionAsset* assetData, AZ::IO::GenericStream* stream, AZ::DataStream::StreamType streamType)
{
if (assetData && m_serializeContext)
{
AZStd::vector<char> byteBuffer;
AZ::IO::ByteContainerStream<decltype(byteBuffer)> byteStream(&byteBuffer);
AZ::ObjectStream* objStream = AZ::ObjectStream::Create(&byteStream, *m_serializeContext, streamType);
const ScriptCanvas::ScriptCanvasData& functionData = assetData->GetScriptCanvasData();
bool assetSaved = objStream->WriteClass(&functionData);
objStream->Finalize();
assetSaved = stream->Write(byteBuffer.size(), byteBuffer.data()) == byteBuffer.size() && assetSaved;
return assetSaved;
}
return false;
}
AZ::Data::AssetType ScriptCanvasFunctionAssetHandler::GetAssetType() const
{
return ScriptCanvasFunctionAssetHandler::GetAssetTypeStatic();
}
const char* ScriptCanvasFunctionAssetHandler::GetAssetTypeDisplayName() const
{
return ScriptCanvas::AssetDescription::GetAssetTypeDisplayName<ScriptCanvasEditor::ScriptCanvasFunctionAsset>();
}
bool ScriptCanvasFunctionAssetHandler::CanCreateComponent([[maybe_unused]] const AZ::Data::AssetId& assetId) const
{
return false;
}
void ScriptCanvasFunctionAssetHandler::GetAssetTypeExtensions(AZStd::vector<AZStd::string>& extensions)
{
const AZ::Uuid& assetType = *AZ::AssetTypeInfoBus::GetCurrentBusId();
if (assetType == AZ::AzTypeInfo<ScriptCanvasEditor::ScriptCanvasFunctionAsset>::Uuid())
{
extensions.push_back(ScriptCanvas::AssetDescription::GetExtension<ScriptCanvasEditor::ScriptCanvasFunctionAsset>());
}
}
void ScriptCanvasFunctionAssetHandler::GetHandledAssetTypes(AZStd::vector<AZ::Data::AssetType>& assetTypes)
{
assetTypes.push_back(AZ::AzTypeInfo<ScriptCanvasEditor::ScriptCanvasFunctionAsset>::Uuid());
}
AZ::Data::AssetType ScriptCanvasFunctionAssetHandler::GetAssetTypeStatic()
{
return azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>();
}
const char* ScriptCanvasFunctionAssetHandler::GetGroup() const
{
return ScriptCanvas::AssetDescription::GetGroup<ScriptCanvasEditor::ScriptCanvasFunctionAsset>();
}
const char* ScriptCanvasFunctionAssetHandler::GetBrowserIcon() const
{
return ScriptCanvas::AssetDescription::GetIconPath<ScriptCanvasEditor::ScriptCanvasFunctionAsset>();
}
}
@@ -1,201 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "precompiled.h"
#include <LyViewPaneNames.h>
#include <Editor/Assets/Functions/ScriptCanvasFunctionAssetHolder.h>
#include <ScriptCanvas/Asset/AssetRegistry.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Serialization/IdUtils.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
namespace ScriptCanvasEditor
{
//=========================================================================
void ScriptCanvasFunctionAssetHolder::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<ScriptCanvasFunctionAssetHolder>()
->Version(1)
->Field("m_asset", &ScriptCanvasFunctionAssetHolder::m_scriptCanvasAssetId)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<ScriptCanvasFunctionAssetHolder>("Script Canvas", "Script Canvas Function Asset Holder")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->DataElement(AZ::Edit::UIHandlers::Default, &ScriptCanvasFunctionAssetHolder::m_scriptCanvasAssetId, "Script Canvas Function Asset", "Script Canvas asset associated with this component")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &ScriptCanvasFunctionAssetHolder::OnScriptChanged)
->Attribute("EditButton", "Editor/Icons/PropertyEditor/open_in.png")
->Attribute("EditDescription", "Open in Script Canvas Editor")
->Attribute("EditCallback", &ScriptCanvasFunctionAssetHolder::LaunchScriptCanvasEditor)
;
}
}
}
ScriptCanvasFunctionAssetHolder::ScriptCanvasFunctionAssetHolder(AZ::Data::AssetId assetId, const ScriptChangedCB& scriptChangedCB)
: m_scriptCanvasAssetId(assetId)
, m_scriptNotifyCallback(scriptChangedCB)
{
}
ScriptCanvasFunctionAssetHolder::~ScriptCanvasFunctionAssetHolder()
{
AZ::Data::AssetBus::Handler::BusDisconnect();
}
void ScriptCanvasFunctionAssetHolder::Init(AZ::EntityId ownerId)
{
m_ownerId = ownerId;
if (m_scriptCanvasAssetId.IsValid())
{
AZ::Data::AssetBus::Handler::BusDisconnect();
AZ::Data::AssetBus::Handler::BusConnect(m_scriptCanvasAssetId);
}
}
void ScriptCanvasFunctionAssetHolder::LaunchScriptCanvasEditor(const AZ::Data::AssetId&, const AZ::Data::AssetType&) const
{
OpenEditor();
}
void ScriptCanvasFunctionAssetHolder::OpenEditor() const
{
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
if (m_scriptCanvasAssetId.IsValid())
{
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, m_scriptCanvasAssetId, -1);
if (!openOutcome)
{
AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data());
}
}
else if (m_ownerId.IsValid())
{
AzToolsFramework::EntityIdList selectedEntityIds;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
// Going to bypass the multiple selected entities flow for right now.
if (selectedEntityIds.size() == 1)
{
GeneralRequestBus::Broadcast(&GeneralRequests::CreateScriptCanvasAssetFor, m_ownerId);
}
}
}
AZ::EntityId ScriptCanvasFunctionAssetHolder::GetGraphId() const
{
AZ::EntityId graphId;
if (m_scriptCanvasAsset.IsReady())
{
ScriptCanvas::SystemRequestBus::BroadcastResult(graphId, &ScriptCanvas::SystemRequests::FindGraphId, m_scriptCanvasAsset.Get()->GetScriptCanvasEntity());
}
return graphId;
}
void ScriptCanvasFunctionAssetHolder::SetScriptChangedCB(const ScriptChangedCB& scriptChangedCB)
{
m_scriptNotifyCallback = scriptChangedCB;
}
void ScriptCanvasFunctionAssetHolder::Load(bool loadBlocking)
{
if (!m_scriptCanvasAsset.IsReady())
{
AZ::Data::AssetInfo assetInfo;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, m_scriptCanvasAsset.GetId());
if (assetInfo.m_assetId.IsValid())
{
const AZ::Data::AssetType assetTypeId = azrtti_typeid<ScriptCanvasAsset>();
auto& assetManager = AZ::Data::AssetManager::Instance();
m_scriptCanvasAsset = assetManager.GetAsset(m_scriptCanvasAsset.GetId(), azrtti_typeid<ScriptCanvasAsset>(), true, nullptr, loadBlocking);
}
}
}
AZ::u32 ScriptCanvasFunctionAssetHolder::OnScriptChanged()
{
SetAsset(m_scriptCanvasAsset.GetId());
Load(false);
if (m_scriptNotifyCallback)
{
m_scriptNotifyCallback(m_scriptCanvasAsset);
}
return AZ::Edit::PropertyRefreshLevels::EntireTree;
}
void ScriptCanvasFunctionAssetHolder::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
SetAsset(asset.GetId());
EditorScriptCanvasAssetNotificationBus::Event(m_scriptCanvasAsset.GetId(), &EditorScriptCanvasAssetNotifications::OnScriptCanvasAssetReady, m_scriptCanvasAsset);
}
void ScriptCanvasFunctionAssetHolder::OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
SetAsset(asset.GetId());
EditorScriptCanvasAssetNotificationBus::Event(m_scriptCanvasAsset.GetId(), &EditorScriptCanvasAssetNotifications::OnScriptCanvasAssetReloaded, m_scriptCanvasAsset);
}
void ScriptCanvasFunctionAssetHolder::OnAssetUnloaded(const AZ::Data::AssetId assetId, const AZ::Data::AssetType)
{
EditorScriptCanvasAssetNotificationBus::Event(assetId, &EditorScriptCanvasAssetNotifications::OnScriptCanvasAssetUnloaded, assetId);
}
void ScriptCanvasFunctionAssetHolder::OnAssetSaved(AZ::Data::Asset<AZ::Data::AssetData> asset, bool isSuccessful)
{
SetAsset(asset.GetId());
auto currentBusId = AZ::Data::AssetBus::GetCurrentBusId();
if (currentBusId)
{
EditorScriptCanvasAssetNotificationBus::Event(*currentBusId, &EditorScriptCanvasAssetNotifications::OnScriptCanvasAssetSaved, asset.GetId());
}
}
void ScriptCanvasFunctionAssetHolder::SetAsset(AZ::Data::AssetId assetId)
{
m_scriptCanvasAssetId = assetId;
if (!AZ::Data::AssetBus::Handler::BusIsConnectedId(m_scriptCanvasAssetId))
{
AZ::Data::AssetBus::Handler::BusDisconnect();
if (m_scriptCanvasAssetId.IsValid())
{
AZ::Data::AssetBus::Handler::BusConnect(m_scriptCanvasAssetId);
}
}
}
//AZ::Data::Asset<ScriptCanvasAsset> ScriptCanvasFunctionAssetHolder::GetAsset() const
//{
// return m_scriptCanvasAsset;
//}
AZ::Data::AssetId ScriptCanvasFunctionAssetHolder::GetAssetId() const
{
return m_scriptCanvasAssetId;
}
}
@@ -1,75 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/EntityId.h>
#include <AzCore/Asset/AssetCommon.h>
namespace ScriptCanvas
{
class ScriptCanvasFunctionAsset;
}
namespace ScriptCanvasEditor
{
class ScriptCanvasFunctionAsset;
/*! ScriptCanvasAssetHolder
Wraps a ScriptCanvasAsset reference and registers for the individual AssetBus events
for saving, loading and unloading the asset.
The ScriptCanvasAsset Holder contains functionality for activating the ScriptCanvasEntity stored on the reference asset
as well as attempting to open the ScriptCanvasAsset within the ScriptCanvas Editor.
It also provides the EditContext reflection for opening the asset in the ScriptCanvas Editor via a button
*/
class ScriptCanvasFunctionAssetHolder
: private AZ::Data::AssetBus::Handler
{
public:
AZ_RTTI(ScriptCanvasFunctionAssetHolder, "{21693AFA-5664-4AAE-9213-8B944A398BA1}");
AZ_CLASS_ALLOCATOR(ScriptCanvasFunctionAssetHolder, AZ::SystemAllocator, 0);
using ScriptChangedCB = AZStd::function<void(const AZ::Data::Asset<ScriptCanvasAsset>&)>;
ScriptCanvasFunctionAssetHolder() = default;
ScriptCanvasFunctionAssetHolder(AZ::Data::AssetId assetId, const ScriptChangedCB& = {});
~ScriptCanvasFunctionAssetHolder() override;
static void Reflect(AZ::ReflectContext* context);
void Init(AZ::EntityId ownerId = AZ::EntityId());
void SetAsset(AZ::Data::AssetId assetId);
AZ::Data::AssetId GetAssetId() const;
AZ::EntityId GetGraphId() const;
void LaunchScriptCanvasEditor(const AZ::Data::AssetId&, const AZ::Data::AssetType&) const;
void OpenEditor() const;
void SetScriptChangedCB(const ScriptChangedCB&);
void Load(bool loadBlocking = false);
protected:
//=====================================================================
// AZ::Data::AssetBus
void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetUnloaded(const AZ::Data::AssetId assetId, const AZ::Data::AssetType assetType) override;
void OnAssetSaved(AZ::Data::Asset<AZ::Data::AssetData> asset, bool isSuccessful) override;
//=====================================================================
//! Reloads the Script From the AssetData if it has changed
AZ::u32 OnScriptChanged();
AZ::Data::AssetId m_scriptCanvasAssetId;
AZ::Data::Asset<ScriptCanvas::ScriptCanvasFunctionAsset> m_scriptCanvasAsset;
AZ::EntityId m_ownerId; // Id of Entity which stores this AssetHolder object
ScriptChangedCB m_scriptNotifyCallback;
};
}
@@ -8,7 +8,6 @@
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Asset/Functions/ScriptCanvasFunctionAsset.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
namespace ScriptCanvasEditor
@@ -80,11 +80,6 @@ namespace ScriptCanvasEditor
AZ::Data::Asset<ScriptCanvasAsset> newAsset = Clone<ScriptCanvasAsset>();
memoryAsset.m_inMemoryAsset = newAsset;
}
else if (m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>())
{
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset> newAsset = Clone<ScriptCanvasEditor::ScriptCanvasFunctionAsset>();
memoryAsset.m_inMemoryAsset = newAsset;
}
else
{
AZ_Assert(false, "Unsupported Script Canvas Asset Type");
@@ -107,10 +102,6 @@ namespace ScriptCanvasEditor
{
asset = assetHandler->CreateAsset(assetId, azrtti_typeid<ScriptCanvasAsset>());
}
else if (assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>())
{
asset = assetHandler->CreateAsset(assetId, azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>());
}
m_inMemoryAsset = AZ::Data::Asset<AssetType>(asset, AZ::Data::AssetLoadBehavior::PreLoad);
@@ -155,8 +146,6 @@ namespace ScriptCanvasEditor
streamInfo.m_streamFlags = AZ::IO::OpenMode::ModeWrite;
streamInfo.m_streamName = m_saveAsPath;
ScriptCanvasEditor::ScriptCanvasDataRequestBus::Event(GetScriptCanvasId(), &ScriptCanvasEditor::ScriptCanvasDataRequests::SetPrettyName, GetTabName().c_str());
if (!streamInfo.IsValid())
{
return;
@@ -223,10 +212,6 @@ namespace ScriptCanvasEditor
{
m_inMemoryAsset = AZ::Data::AssetManager::Instance().GetAsset<ScriptCanvasAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
}
else if (assetInfo.m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>())
{
m_inMemoryAsset = AZ::Data::AssetManager::Instance().GetAsset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
}
if (m_inMemoryAsset)
{
@@ -290,15 +275,8 @@ namespace ScriptCanvasEditor
return;
}
if (m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>())
{
editorGraph->MarkFunctionGraph();
}
m_scriptCanvasId = editorGraph->GetScriptCanvasId();
ScriptCanvasEditor::ScriptCanvasDataRequestBus::Event(m_scriptCanvasId, &ScriptCanvasEditor::ScriptCanvasDataRequests::SetPrettyName, GetTabName().c_str());
EditorGraphNotificationBus::Handler::BusDisconnect();
EditorGraphNotificationBus::Handler::BusConnect(m_scriptCanvasId);
@@ -538,10 +516,6 @@ namespace ScriptCanvasEditor
{
return CloneAssetData<ScriptCanvasAsset>(newAssetId);
}
else if (m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>())
{
return CloneAssetData<ScriptCanvasEditor::ScriptCanvasFunctionAsset>(newAssetId);
}
AZ_Assert(false, "The provides asset type is not supported as a valid Script Canvas memory asset");
return AZ::Data::Asset<AZ::Data::AssetData>();
@@ -21,7 +21,6 @@
#include <Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h>
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
#include <ScriptCanvas/Asset/Functions/ScriptCanvasFunctionAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
@@ -61,11 +61,6 @@ namespace ScriptCanvasEditor
{
}
void ScriptCanvasAssetNode::OnInputSignal(const ScriptCanvas::SlotId&)
{
}
void ScriptCanvasAssetNode::OnInit()
{
if (GetAsset().GetId().IsValid())
@@ -74,7 +74,6 @@ namespace ScriptCanvasEditor
////
protected:
void OnInputSignal(const ScriptCanvas::SlotId&) override;
// AssetBus::Handler
void OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetUnloaded(const AZ::Data::AssetId assetId, const AZ::Data::AssetType) override;
@@ -223,7 +223,7 @@ namespace ScriptCanvasEditor
void ScriptCanvasRootPaletteTreeItem::SetActiveScriptCanvasId(const ScriptCanvas::ScriptCanvasId& scriptCanvasId)
{
ScriptCanvas::RuntimeRequestBus::EventResult(m_previousAssetId, scriptCanvasId, &ScriptCanvas::RuntimeRequests::GetAssetId);
ScriptCanvas::RuntimeRequestBus::EventResult(m_previousAssetId, scriptCanvasId, &ScriptCanvas::GraphRequests::GetAssetId);
for (auto functionTreePair : m_globalFunctionTreeItems)
{
@@ -31,7 +31,6 @@
#include <Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.h>
#include <Editor/View/Widgets/NodePalette/VariableNodePaletteTreeItemTypes.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
@@ -722,7 +721,7 @@ namespace ScriptCanvasEditor
ScriptCanvas::GraphVariableManagerNotificationBus::Handler::BusDisconnect();
m_assetType = AZ::Data::AssetType::CreateNull();
ScriptCanvas::RuntimeRequestBus::EventResult(m_assetType, scriptCanvasId, &ScriptCanvas::RuntimeRequests::GetAssetType);
ScriptCanvas::GraphRequestBus::EventResult(m_assetType, scriptCanvasId, &ScriptCanvas::GraphRequests::GetAssetType);
m_scriptCanvasId = scriptCanvasId;
@@ -50,7 +50,6 @@
#include <ScriptCanvas/Core/NodeBus.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
@@ -50,7 +50,6 @@
#include <ScriptCanvas/Core/NodeBus.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
@@ -757,7 +756,7 @@ namespace ScriptCanvasEditor
AZStd::vector<AZ::EntityId> selection;
ScriptCanvas::RuntimeRequests* runtimeRequests = ScriptCanvas::RuntimeRequestBus::FindFirstHandler(m_scriptCanvasId);
auto owningGraph = ScriptCanvas::GraphRequestBus::FindFirstHandler(m_scriptCanvasId);
if (runtimeRequests == nullptr)
{
@@ -1,145 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Asset/AssetCommon.h>
#include <ScriptCanvas/Asset/AssetDescription.h>
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
#include <AzCore/std/containers/vector.h>
namespace AZ
{
class Entity;
}
namespace ScriptCanvasEditor
{
class ScriptCanvasFunctionAsset;
class Graph;
class ScriptCanvasFunctionDescription : public ScriptCanvas::AssetDescription
{
public:
AZ_TYPE_INFO(ScriptCanvasFunctionDescription, "{B53569F6-8408-40FC-9A72-ED873BEF162E}");
ScriptCanvasFunctionDescription()
: AssetDescription(
azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>(),
"Script Canvas Function",
"Script Canvas Function Graph Asset",
"@devassets@/scriptcanvas/functions",
".scriptcanvas_fn",
"Script Canvas Function",
"Untitled-Function-%i",
"Script Canvas Function Files (*.scriptcanvas_fn)",
"Script Canvas Function",
"Script Canvas Function",
"Icons/ScriptCanvas/Viewport/ScriptCanvas_Function.png",
AZ::Color(0.192f, 0.149f, 0.392f, 1.0f),
true
)
{}
};
// TODO-LS: move these to their own file
class ScriptCanvasDataRequests : public AZ::ComponentBus
{
public:
virtual void SetPrettyName(const char* name) = 0;
virtual AZStd::string GetPrettyName() = 0;
};
using ScriptCanvasDataRequestBus = AZ::EBus<ScriptCanvasDataRequests>;
class ScriptCanvasFunctionDataComponent
: public AZ::Component
, ScriptCanvasDataRequestBus::MultiHandler
{
public:
AZ_COMPONENT(ScriptCanvasFunctionDataComponent, "{440BB6DC-4E70-4304-A926-252925F77433}");
void Activate() override
{
AZ::EntityId entityId = GetEntityId();
ScriptCanvasDataRequestBus::MultiHandler::BusConnect(entityId);
}
void Deactivate() override
{
ScriptCanvasDataRequestBus::MultiHandler::BusDisconnect();
AZ::EntityId entityId = GetEntityId();
}
void SetPrettyName(const char* name) override
{
m_assetPrettyName = name;
}
AZStd::string GetPrettyName() override
{
return m_assetPrettyName;
}
static void Reflect(AZ::ReflectContext* reflectContext)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<ScriptCanvasFunctionDataComponent, AZ::Component>()
->Version(2)
->Field("m_assetPrettyName", &ScriptCanvasFunctionDataComponent::m_assetPrettyName)
->Field("m_version", &ScriptCanvasFunctionDataComponent::m_functionDataComponentVersion)
;
}
}
size_t m_functionDataComponentVersion = 0;
AZStd::string m_assetPrettyName;
};
class ScriptCanvasFunctionAsset
: public ScriptCanvas::ScriptCanvasAssetBase
{
public:
AZ_RTTI(ScriptCanvasFunctionAsset, "{ED078D3C-938D-41F8-A5F6-CC04311ECF4F}", ScriptCanvasAssetBase);
AZ_CLASS_ALLOCATOR(ScriptCanvasFunctionAsset, AZ::SystemAllocator, 0);
ScriptCanvasFunctionAsset(const AZ::Data::AssetId& assetId = AZ::Data::AssetId(AZ::Uuid::CreateRandom()), AZ::Data::AssetData::AssetStatus status = AZ::Data::AssetData::AssetStatus::NotLoaded)
: ScriptCanvasAssetBase(assetId, status)
{
m_data = aznew ScriptCanvas::ScriptCanvasData();
}
~ScriptCanvasFunctionAsset() override
{}
ScriptCanvas::AssetDescription GetAssetDescription() const override
{
return ScriptCanvasFunctionDescription();
}
using Description = ScriptCanvasFunctionDescription;
ScriptCanvasFunctionDataComponent* m_cachedComponent = nullptr;
ScriptCanvasFunctionDataComponent* GetFunctionData()
{
if (m_cachedComponent == nullptr)
{
m_cachedComponent = GetScriptCanvasEntity()->FindComponent<ScriptCanvasFunctionDataComponent>();
}
return m_cachedComponent;
}
};
}
@@ -122,8 +122,6 @@ namespace ScriptCanvas
{
const auto& scriptCanvasId = GetScriptCanvasId();
GraphRequestBus::Handler::BusConnect(scriptCanvasId);
RuntimeRequestBus::Handler::BusConnect(scriptCanvasId);
ValidationRequestBus::Handler::BusConnect(scriptCanvasId);
for (auto& nodeEntity : m_graphData.m_nodes)
@@ -142,6 +140,7 @@ namespace ScriptCanvas
}
m_graphData.BuildEndpointMap();
for (auto& connectionEntity : m_graphData.m_connections)
{
if (connectionEntity)
@@ -19,7 +19,6 @@
#include <ScriptCanvas/Debugger/Bus.h>
#include <ScriptCanvas/Execution/ErrorBus.h>
#include <ScriptCanvas/Execution/ExecutionContext.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Debugger/StatusBus.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ValidationEvent.h>
@@ -35,7 +34,6 @@ namespace ScriptCanvas
class Graph
: public AZ::Component
, protected GraphRequestBus::Handler
, protected RuntimeRequestBus::Handler
, protected StatusRequestBus::Handler
, private AZ::EntityBus::Handler
, private ValidationRequestBus::Handler
@@ -174,14 +172,12 @@ namespace ScriptCanvas
void RefreshConnectionValidity(bool warnOnRemoval = false);
//// RuntimeRequestBus::Handler
AZ::Data::AssetId GetAssetId() const override { return AZ::Data::AssetId(); }
GraphIdentifier GetGraphIdentifier() const override { return GraphIdentifier(GetAssetId(), 0); }
AZStd::string GetAssetName() const override { return ""; }
AZ::EntityId GetRuntimeEntityId() const override { return GetEntity() ? GetEntityId() : AZ::EntityId(); }
VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeId) const override { return runtimeId; }
VariableId FindRuntimeVariableIdByAssetVariableId(VariableId assetId) const override { return assetId; }
AZ::EntityId FindAssetNodeIdByRuntimeNodeId(AZ::EntityId editorNode) const override { return editorNode; }
AZ::EntityId FindRuntimeNodeIdByAssetNodeId(AZ::EntityId runtimeNode) const override { return runtimeNode; }
@@ -190,8 +186,8 @@ namespace ScriptCanvas
const GraphVariableMapping* GetVariables() const override;
GraphVariable* FindVariable(AZStd::string_view propName) override;
GraphVariable* FindVariableById(const VariableId& variableId) override;
Data::Type GetVariableType(const VariableId& variableId) const override;
AZStd::string_view GetVariableName(const VariableId& variableId) const override;
Data::Type GetVariableType(const VariableId& variableId) const;
AZStd::string_view GetVariableName(const VariableId& variableId) const;
bool IsGraphObserved() const override;
void SetIsGraphObserved(bool isObserved) override;
@@ -11,6 +11,7 @@
#include "Endpoint.h"
#include <ScriptCanvas/Variable/VariableCore.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/vector.h>
@@ -23,6 +24,8 @@ namespace ScriptCanvas
class Graph;
class Slot;
using EndpointMapConstIterator = AZStd::unordered_multimap<Endpoint, Endpoint>::const_iterator;
//! These are public graph requests
class GraphRequests : public AZ::EBusTraits
{
@@ -104,8 +107,49 @@ namespace ScriptCanvas
virtual void SetIsGraphObserved(bool observed) = 0;
virtual bool IsGraphObserved() const = 0;
};
virtual VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeId) const = 0;
virtual AZ::EntityId FindAssetNodeIdByRuntimeNodeId(AZ::EntityId editorNode) const = 0;
virtual AZ::Data::AssetId GetAssetId() const = 0;
virtual GraphIdentifier GetGraphIdentifier() const = 0;
virtual AZStd::string GetAssetName() const = 0;
//! Looks up the nodeId within the bus handler
virtual Node* FindNode(AZ::EntityId nodeId) const = 0;
virtual AZ::EntityId FindRuntimeNodeIdByAssetNodeId(AZ::EntityId runtimeNode) const = 0;
//! Returns the entity id of the execution component
virtual AZ::EntityId GetRuntimeEntityId() const = 0;
virtual AZStd::pair< EndpointMapConstIterator, EndpointMapConstIterator > GetConnectedEndpointIterators(const Endpoint& endpoint) const = 0;
//! Returns whether the given endpoint has any connections
virtual bool IsEndpointConnected(const Endpoint& endpoint) const = 0;
//! Retrieves VariableData structure which manages variable data for the execution component
virtual VariableData* GetVariableData() = 0;
virtual const VariableData* GetVariableDataConst() const = 0;
//! Retrieves a map of variable id to variable name and variable datums pair
virtual const GraphVariableMapping* GetVariables() const = 0;
//! Searches for a variable with the specified name
//! returns pointer to the first variable with the specified name or nullptr
virtual GraphVariable* FindVariable(AZStd::string_view varName) = 0;
//! Searches for a variable by VariableId
//! returns a pair of <variable datum pointer, variable name> with the supplied id
//! The variable datum pointer is non-null if the variable has been found
virtual GraphVariable* FindVariableById(const VariableId& variableId) = 0;
virtual AZ::Data::AssetType GetAssetType() const = 0;
};
using GraphRequestBus = AZ::EBus<GraphRequests>;
class GraphNotifications : public AZ::EBusTraits
@@ -487,23 +487,16 @@ namespace ScriptCanvas
void Node::Activate()
{
SignalBus::Handler::BusConnect(GetEntityId());
SetRuntimeBus(RuntimeRequestBus::FindFirstHandler(m_scriptCanvasId));
AZ_Assert(m_runtimeBus, "Invalid m_executionUniqueId given for RuntimeRequestBus");
m_graphRequestBus = GraphRequestBus::FindFirstHandler(m_scriptCanvasId);
AZ_Assert(m_graphRequestBus, "Invalid m_executionUniqueId given for RuntimeRequestBus");
OnActivate();
MarkDefaultableInput();
}
void Node::Deactivate()
{
OnDeactivate();
SignalBus::Handler::BusDisconnect();
SetRuntimeBus(RuntimeRequestBus::FindFirstHandler(m_scriptCanvasId));
m_graphRequestBus = GraphRequestBus::FindFirstHandler(m_scriptCanvasId);
}
void Node::PostActivate()
@@ -737,7 +730,7 @@ namespace ScriptCanvas
bool Node::IsInEventHandlingScope(const ID& possibleEventHandler) const
{
Node* node = m_runtimeBus->FindNode(possibleEventHandler);
Node* node = m_graphRequestBus->FindNode(possibleEventHandler);
if (auto eventHandler = azrtti_cast<ScriptCanvas::Nodes::Core::EBusEventHandler*>(node))
{
@@ -844,7 +837,7 @@ namespace ScriptCanvas
GraphVariable* Node::FindGraphVariable(const VariableId& variableId) const
{
return m_runtimeBus->FindVariableById(variableId);
return m_graphRequestBus->FindVariableById(variableId);
}
void Node::OnSlotConvertedToValue(const SlotId& slotId)
@@ -1598,24 +1591,6 @@ namespace ScriptCanvas
NodeNotificationsBus::Event(GetEntityId(), &NodeNotifications::OnSlotDisplayTypeChanged, slotId, dataType);
}
void Node::SignalInput(const SlotId& slotId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas);
SC_EXECUTION_TRACE_SIGNAL_INPUT((*this), (InputSignal(CreateNodeInputSignal(slotId))));
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::%s::SignalInput", GetNodeName().c_str());
OnInputSignal(slotId);
}
}
void Node::SignalOutput(const SlotId& slotId, ExecuteMode mode)
{
AZ_UNUSED(slotId);
AZ_UNUSED(mode);
}
AZ::Outcome<void, AZStd::string> Node::SlotAcceptsType(const SlotId& slotID, const Data::Type& type) const
{
if (auto slot = GetSlot(slotID))
@@ -1914,7 +1889,7 @@ namespace ScriptCanvas
if (slot.GetDescriptor() == slotDescriptor
&& (allowLatentSlots || !slot.IsLatent()))
{
AZStd::vector<Endpoint> connectedEndpoints = m_runtimeBus->GetConnectedEndpoints(Endpoint{ GetEntityId(), slot.GetId() });
AZStd::vector<Endpoint> connectedEndpoints = m_graphRequestBus->GetConnectedEndpoints(Endpoint{ GetEntityId(), slot.GetId() });
endpoints.insert(endpoints.end(), connectedEndpoints.begin(), connectedEndpoints.end());
}
}
@@ -2339,9 +2314,7 @@ namespace ScriptCanvas
void Node::SetOwningScriptCanvasId(ScriptCanvasId scriptCanvasId)
{
m_scriptCanvasId = scriptCanvasId;
SetRuntimeBus(RuntimeRequestBus::FindFirstHandler(m_scriptCanvasId));
m_graphRequestBus = GraphRequestBus::FindFirstHandler(m_scriptCanvasId);
OnGraphSet();
}
@@ -2426,7 +2399,7 @@ namespace ScriptCanvas
AZ::EntityId Node::GetGraphEntityId() const
{
return m_runtimeBus->GetRuntimeEntityId();
return m_graphRequestBus->GetRuntimeEntityId();
}
NodePtrConstList Node::FindConnectedNodesByDescriptor(const SlotDescriptor& slotDescriptor, bool followLatentConnections) const
@@ -2437,7 +2410,7 @@ namespace ScriptCanvas
for (const auto& endpoint : GetAllEndpointsByDescriptor(slotDescriptor, followLatentConnections))
{
Node* connectedNode = m_runtimeBus->FindNode(endpoint.GetNodeId());
Node* connectedNode = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (connectedNode)
{
@@ -2456,7 +2429,7 @@ namespace ScriptCanvas
for (const auto& endpoint : GetAllEndpointsByDescriptor(slotDescriptor, followLatentConnections))
{
Node* connectedNode = m_runtimeBus->FindNode(endpoint.GetNodeId());
Node* connectedNode = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (connectedNode)
{
@@ -2469,7 +2442,7 @@ namespace ScriptCanvas
AZ::Data::AssetId Node::GetGraphAssetId() const
{
return m_runtimeBus->GetAssetId();
return m_graphRequestBus->GetAssetId();
}
AZStd::string Node::GetGraphAssetName() const
@@ -2482,7 +2455,7 @@ namespace ScriptCanvas
GraphIdentifier Node::GetGraphIdentifier() const
{
return m_runtimeBus->GetGraphIdentifier();
return m_graphRequestBus->GetGraphIdentifier();
}
bool Node::IsSanityCheckRequired() const
@@ -2652,7 +2625,7 @@ namespace ScriptCanvas
return;
}
auto node = m_runtimeBus->FindNode(endpoint.GetNodeId());
auto node = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (node)
{
@@ -2840,7 +2813,7 @@ namespace ScriptCanvas
bool Node::IsConnected(const Slot& slot) const
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Node::IsConnected");
return slot.IsVariableReference() || m_runtimeBus->IsEndpointConnected(slot.GetEndpoint());
return slot.IsVariableReference() || m_graphRequestBus->IsEndpointConnected(slot.GetEndpoint());
}
bool Node::IsConnected(const SlotId& slotId) const
@@ -2880,7 +2853,7 @@ namespace ScriptCanvas
bool Node::IsActivated() const
{
return m_runtimeBus;
return m_graphRequestBus;
}
EndpointsResolved Node::GetConnectedNodes(const Slot& slot) const
@@ -2889,17 +2862,17 @@ namespace ScriptCanvas
EndpointsResolved connectedNodes;
auto endpointIters = m_runtimeBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
auto endpointIters = m_graphRequestBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
for (auto endpointIter = endpointIters.first; endpointIter != endpointIters.second; ++endpointIter)
{
const Endpoint& endpoint = endpointIter->second;
auto node = m_runtimeBus->FindNode(endpoint.GetNodeId());
auto node = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (node == nullptr)
{
AZStd::string assetName = m_runtimeBus->GetAssetName();
AZ::EntityId assetNodeId = m_runtimeBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZStd::string assetName = m_graphRequestBus->GetAssetName();
AZ::EntityId assetNodeId = m_graphRequestBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZ_Warning("Script Canvas", false, "Unable to find node with id (id: %s) in the graph '%s'. Most likely the node was serialized with a type that is no longer reflected",
assetNodeId.ToString().data(), assetName.data());
@@ -2913,8 +2886,8 @@ namespace ScriptCanvas
auto endpointSlot = node->GetSlot(endpoint.GetSlotId());
if (!endpointSlot)
{
AZStd::string assetName = m_runtimeBus->GetAssetName();
AZ::EntityId assetNodeId = m_runtimeBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZStd::string assetName = m_graphRequestBus->GetAssetName();
AZ::EntityId assetNodeId = m_graphRequestBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZ_Warning("Script Canvas", false, "Endpoint was missing slot. id (id: %s) in the graph '%s'.",
assetNodeId.ToString().data(), assetName.data());
@@ -2937,18 +2910,18 @@ namespace ScriptCanvas
void Node::ModConnectedNodes(const Slot& slot, AZStd::vector<AZStd::pair<Node*, const SlotId>>& connectedNodes) const
{
auto endpointIters = m_runtimeBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
auto endpointIters = m_graphRequestBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
for (auto endpointIter = endpointIters.first; endpointIter != endpointIters.second; ++endpointIter)
{
const Endpoint& endpoint = endpointIter->second;
auto node = m_runtimeBus->FindNode(endpoint.GetNodeId());
auto node = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (node == nullptr)
{
AZStd::string assetName = m_runtimeBus->GetAssetName();
AZ::EntityId assetNodeId = m_runtimeBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZStd::string assetName = m_graphRequestBus->GetAssetName();
AZ::EntityId assetNodeId = m_graphRequestBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZ_Error("Script Canvas", false, "Unable to find node with id (id: %s) in the graph '%s'. Most likely the node was serialized with a type that is no longer reflected",
assetNodeId.ToString().data(), assetName.data());
@@ -2961,41 +2934,7 @@ namespace ScriptCanvas
bool Node::HasConnectedNodes(const Slot& slot) const
{
return m_runtimeBus->IsEndpointConnected(Endpoint{ GetEntityId(), slot.GetId() });
}
void Node::OnInputChanged(Node& node, const Datum& input, const SlotId& slotID)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas);
node.OnInputChanged(input, slotID);
}
void Node::PushOutput(const Datum& output, const Slot& slot) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas);
if (slot.IsVariableReference())
{
GraphVariable* variable = slot.GetVariable();
if (variable)
{
ModifiableDatumView datumView;
variable->ConfigureDatumView(datumView);
datumView.AssignToDatum(output);
}
}
else
{
auto endpointIters = m_runtimeBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
for (auto endpointIter = endpointIters.first; endpointIter != endpointIters.second; ++endpointIter)
{
Node* node = m_runtimeBus->FindNode(endpointIter->second.GetNodeId());
node->SetInput(output, endpointIter->second.GetSlotId());
}
}
return m_graphRequestBus->IsEndpointConnected(Endpoint{ GetEntityId(), slot.GetId() });
}
void Node::ForEachConnectedNode(const Slot& slot, AZStd::function<void(Node&, const SlotId&)> callable) const
@@ -3018,9 +2957,8 @@ namespace ScriptCanvas
FindModifiableDatumView(slotId, datumView);
if (datumView.IsValid())
{
{
datumView.AssignToDatum(newInput);
OnInputChanged((*datumView.GetDatum()), slotId);
}
}
@@ -3034,7 +2972,6 @@ namespace ScriptCanvas
if (datumView.IsValid())
{
datumView.AssignToDatum(newInput);
OnInputChanged((*datumView.GetDatum()), slotId);
}
}
@@ -22,12 +22,10 @@
#include <ScriptCanvas/Core/ExecutionNotificationsBus.h>
#include <ScriptCanvas/Core/GraphBus.h>
#include <ScriptCanvas/Core/NodeBus.h>
#include <ScriptCanvas/Core/SignalBus.h>
#include <ScriptCanvas/Core/Slot.h>
#include <ScriptCanvas/Debugger/StatusBus.h>
#include <ScriptCanvas/Execution/ErrorBus.h>
#include <ScriptCanvas/Execution/ExecutionBus.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
#include <ScriptCanvas/Grammar/Primitives.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ValidationEvent.h>
@@ -400,7 +398,6 @@ namespace ScriptCanvas
class Node
: public AZ::Component
, public DatumNotificationBus::Handler
, private SignalBus::Handler
, public NodeRequestBus::Handler
, public EndpointNotificationBus::MultiHandler
{
@@ -542,7 +539,6 @@ namespace ScriptCanvas
AZStd::vector<AZStd::pair<const Node*, SlotId>> FindConnectedNodesAndSlotsByDescriptor(const SlotDescriptor& slotType, bool followLatentConnections = false) const;
AZStd::vector<const Slot*> GetSlotsByType(CombinedSlotType slotType) const;
AZStd::vector<Endpoint> GetConnectedEndpoints(SlotId outSlot) const;
bool IsConnected(const Slot& slot) const;
bool IsConnected(const SlotId& slotId) const;
@@ -845,7 +841,6 @@ namespace ScriptCanvas
void SignalSlotsReordered();
static void OnInputChanged(Node& node, const Datum& input, const SlotId& slotID);
static void SetInput(Node& node, const SlotId& id, const Datum& input);
static void SetInput(Node& node, const SlotId& id, Datum&& input);
@@ -892,7 +887,6 @@ protected:
void Configure();
protected:
TransientSlotIdentifier ConstructTransientIdentifier(const Slot& slot) const;
DatumVector GatherDatumsForDescriptor(SlotDescriptor descriptor) const;
@@ -900,7 +894,6 @@ protected:
SlotDataMap CreateInputMap() const;
SlotDataMap CreateOutputMap() const;
Signal CreateNodeInputSignal(const SlotId& slotId) const;
Signal CreateNodeOutputSignal(const SlotId& slotId) const;
@@ -954,6 +947,7 @@ protected:
//! This is a used by CodeGen to configure slots just prior to OnInit.
virtual void ConfigureSlots() {}
//! Entity level initialization, perform any resource allocation here that should be available throughout the node's existence.
virtual void OnInit() {}
@@ -968,13 +962,11 @@ protected:
//! Entity level activation, perform entity lifetime setup here, i.e. connect to EBuses
virtual void OnActivate() {}
//! Entity level deactivation, perform any entity lifetime release here, i.e disconnect from EBuses
virtual void OnDeactivate() {}
virtual void OnPostActivate() {}
//! Any node that is not pure data will perform its operation assuming that all input has been pushed and is reasonably valid
// perform your derived nodes work in OnInputSignal(const SlotId&)
virtual void OnInputSignal(const SlotId& /*slot*/) {}
//! Signal sent once the OwningScriptCanvasId is set.
virtual void OnGraphSet() {}
@@ -1000,25 +992,12 @@ protected:
void ModConnectedNodes(const Slot& slot, AZStd::vector<AZStd::pair<Node*, const SlotId>>&) const;
bool HasConnectedNodes(const Slot& slot) const;
virtual void OnInputChanged(const Datum& /*input*/, const SlotId& /*slotID*/) {}
//////////////////////////////////////////////////////////////////////////
//! The body of the node's execution, implement the node's work here.
void PushOutput(const Datum& output, const Slot& slot) const;
void SetOwningScriptCanvasId(ScriptCanvasId scriptCanvasId);
void SetGraphEntityId(AZ::EntityId graphEntityId);
// on activate, simple expressions need to push this data
virtual void SetInput(const Datum& input, const SlotId& id);
virtual void SetInput(Datum&& input, const SlotId& id);
//! Any node that is not pure data will perform its operation assuming that all input has been pushed and is reasonably valid
// perform your derived nodes work in OnInputSignal(const SlotId&)
void SignalInput(const SlotId& slot) override final;
//! This must be called manually to send execution out of a specific slot
void SignalOutput(const SlotId& slot, ExecuteMode mode = ExecuteMode::Normal) override final;
bool SlotExists(AZStd::string_view name, const SlotDescriptor& slotDescriptor) const;
bool IsTargetInDataFlowPath(const ID& targetNodeId, AZStd::unordered_set<ID>& path) const;
@@ -1027,10 +1006,6 @@ protected:
void PopulateNodeType();
void SetRuntimeBus(RuntimeRequests* runtimeBus) { m_runtimeBus = runtimeBus; }
RuntimeRequests* GetRuntimeBus() const { return m_runtimeBus; }
GraphScopedNodeId GetScopedNodeId() const { return GraphScopedNodeId(GetOwningScriptCanvasId(), GetEntityId()); }
private:
@@ -1070,102 +1045,17 @@ protected:
AZStd::vector< VisualExtensionSlotConfiguration > m_visualExtensions;
// Cache pointer to the owning Graph
RuntimeRequests* m_runtimeBus = nullptr;
GraphRequests* m_graphRequestBus = nullptr;
ScriptCanvas::SlotId m_removingSlot;
public:
template<typename t_Value>
const t_Value* GetInput_UNIT_TEST(AZStd::string_view slotName)
{
return GetInput_UNIT_TEST<t_Value>(GetSlotId(slotName));
}
template<typename t_Value>
t_Value* ModInput_UNIT_TEST(AZStd::string_view slotName)
{
return ModInput_UNIT_TEST<t_Value>(GetSlotId(slotName));
}
template<typename t_Value>
const t_Value* GetInput_UNIT_TEST(const SlotId& slotId)
{
const Datum* input = FindDatum(slotId);
return input ? input->GetAs<t_Value>() : nullptr;
}
template<typename t_Value>
t_Value* ModInput_UNIT_TEST(const SlotId& slotId)
{
auto slotIter = m_slotIdIteratorCache.find(slotId);
if (slotIter != m_slotIdIteratorCache.end())
{
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;
}
const Datum* GetInput_UNIT_TEST(AZStd::string_view slotName)
{
return GetInput_UNIT_TEST(GetSlotId(slotName));
}
const Datum* GetInput_UNIT_TEST(const SlotId& slotId)
{
return FindDatum(slotId);
}
// initializes the node input to the value passed in, not a pointer to it
template<typename t_Value>
void SetInput_UNIT_TEST(AZStd::string_view slotName, const t_Value& value)
{
SetInput_UNIT_TEST<t_Value>(GetSlotId(slotName), value);
}
template<typename t_Value>
void SetInput_UNIT_TEST(const SlotId& slotId, const t_Value& value)
{
SetInput(Datum(value), slotId);
}
void SetInput_UNIT_TEST(AZStd::string_view slotName, const Datum& value)
{
SetInput_UNIT_TEST(GetSlotId(slotName), value);
}
void SetInput_UNIT_TEST(AZStd::string_view slotName, Datum&& value)
{
SetInput_UNIT_TEST(GetSlotId(slotName), AZStd::move(value));
}
void SetInput_UNIT_TEST(const SlotId& slotId, Datum&& value)
{
SetInput(AZStd::move(value), slotId);
}
template<typename t_Func, t_Func, typename, size_t>
friend struct Internal::MultipleOutputHelper;
template<typename ResultType, typename t_Traits, typename>
friend struct Internal::OutputSlotHelper;
template<typename ResultType, typename t_Traits, typename>
friend struct Internal::PushOutputHelper;
template<typename ResultType, typename ResultIndexSequence, typename t_Func, t_Func function, typename t_Traits>
friend struct Internal::CallHelper;
template<size_t... inputDatumIndices>
friend struct SetDefaultValuesByIndex;
};
@@ -1238,104 +1128,6 @@ protected:
}
};
template<typename ResultType, typename t_Traits, typename = AZStd::void_t<>>
struct PushOutputHelper
{
template<size_t... Is>
static void PushOutput(Node& node, ResultType&& result, AZStd::index_sequence<Is...>)
{
// protect against changes to the function that generated the node
if (auto slot = node.GetSlotByIndex(t_Traits::s_resultsSlotIndicesStart))
{
node.PushOutput(Datum(AZStd::forward<ResultType>(result)), *slot);
}
}
};
template<typename t_Traits>
struct PushOutputHelper<void, t_Traits, void>
{
template<size_t... Is> static void PushOutput(Node& node, AZStd::ignore_t result, AZStd::index_sequence<Is...>) {}
};
template<typename ResultType, typename t_Traits>
struct PushOutputHelper<ResultType, t_Traits, AZStd::enable_if_t<IsTupleLike<ResultType>::value>>
{
template<size_t t_Index>
static void PushOutputFold(Node& node, ResultType&& tupleResult)
{
// protect against changes to the function that generated the node
if (auto slot = node.GetSlotByIndex(t_Traits::s_resultsSlotIndicesStart + t_Index))
{
node.PushOutput(Datum(AZStd::get<t_Index>(AZStd::forward<ResultType>(tupleResult))), *slot);
}
}
template<size_t... Is>
static void PushOutput(Node& node, ResultType&& tupleResult, AZStd::index_sequence<Is...>)
{
(PushOutputFold<Is>(node, AZStd::forward<ResultType>(tupleResult)), ...);
}
};
template<typename ResultType, typename ResultIndexSequence, typename t_Func, t_Func function, typename t_Traits>
struct CallHelper
{
// protect against changes to the function that generated the node
template<typename... t_Args, size_t... Indices>
static bool IsIndexSafe(Node& node, const AZStd::index_sequence<Indices...>&)
{
return (true && ... && (node.FindDatumByIndex(Indices) != nullptr && node.FindDatumByIndex(Indices)->GetAs<AZStd::decay_t<t_Args>>() != nullptr));
}
template<typename... t_Args, size_t... ArgIndices>
static void Call(Node& node, AZStd::Internal::pack_traits_arg_sequence<t_Args...>, [[maybe_unused]] AZStd::index_sequence<ArgIndices...> sequence)
{
#if !defined(_RELEASE)
if (IsIndexSafe<t_Args...>(node, sequence))
{
PushOutputHelper<ResultType, t_Traits>::PushOutput(node, AZStd::invoke(function, *node.FindDatumByIndex(ArgIndices)->GetAs<AZStd::decay_t<t_Args>>()...), ResultIndexSequence());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((node), "Generic function Node (%s) could not be executed, due to missing slot for source definition."
"this is likely due to changing the function signature. See serialization log for potential errors & warnings.", node.GetNodeName().c_str());
}
#else
PushOutputHelper<ResultType, t_Traits>::PushOutput(node, AZStd::invoke(function, *node.FindDatumByIndex(ArgIndices)->GetAs<AZStd::decay_t<t_Args>>()...), ResultIndexSequence());
#endif//!defined(_RELEASE)
}
};
template<typename ResultIndexSequence, typename t_Func, t_Func function, typename t_Traits>
struct CallHelper<void, ResultIndexSequence, t_Func, function, t_Traits>
{
// protect against changes to the function that generated the node
template<typename... t_Args, size_t... Indices>
static bool IsIndexSafe(Node& node, const AZStd::index_sequence<Indices...>&)
{
return true && (... && (node.FindDatumByIndex(Indices) != nullptr && node.FindDatumByIndex(Indices)->GetAs<AZStd::decay_t<t_Args>>() != nullptr));
}
template<typename... t_Args, size_t... ArgIndices>
static void Call(Node& node, AZStd::Internal::pack_traits_arg_sequence<t_Args...>, [[maybe_unused]] AZStd::index_sequence<ArgIndices...> sequence)
{
#if !defined(_RELEASE)
if (IsIndexSafe<t_Args...>(node, sequence))
{
AZStd::invoke(function, *node.FindDatumByIndex(ArgIndices)->GetAs<AZStd::decay_t<t_Args>>()...);
}
else
{
SCRIPTCANVAS_REPORT_ERROR((node), "Generic function Node (%s) could not be executed, due to missing slot for source definition."
"this is likely due to changing the function signature. See serialization log for potential errors & warnings.", node.GetNodeName().c_str());
}
#else
AZStd::invoke(function, *node.FindDatumByIndex(ArgIndices)->GetAs<AZStd::decay_t<t_Args>>()...);
#endif//!defined(_RELEASE)
}
};
template<typename t_Func, t_Func function, typename t_Traits, size_t NumOutputs>
struct MultipleOutputHelper
{
@@ -1346,11 +1138,6 @@ protected:
{
OutputSlotHelper<ResultType, t_Traits>::AddOutputSlot(node, ResultIndexSequence());
}
static void Call(Node& node)
{
CallHelper<ResultType, ResultIndexSequence, t_Func, function, t_Traits>::Call(node, typename AZStd::function_traits<t_Func>::arg_sequence{}, AZStd::make_index_sequence<AZStd::function_traits<t_Func>::arity>{});
}
};
template<typename t_Func, t_Func function, typename t_Traits, typename t_Result, typename = AZStd::void_t<>>
@@ -248,8 +248,6 @@ namespace ScriptCanvas
return AZ::Success(scope);
}
protected:
template<typename ArgType, size_t Index>
@@ -298,13 +296,6 @@ namespace ScriptCanvas
MultipleOutputInvoker<t_Func, function, t_Traits>::Add(*this);
}
void OnInputSignal(const SlotId&) override
{
MultipleOutputInvoker<t_Func, function, t_Traits>::Call(*this);
SignalOutput(GetSlotId("Out"));
}
static bool VersionConverter(AZ::SerializeContext& serializeContext, AZ::SerializeContext::DataElementNode& rootElement);
static bool ConvertOldNodeGeneric(AZ::SerializeContext& serializeContext, AZ::SerializeContext::DataElementNode& rootElement);
@@ -1,36 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include "Core.h"
#include <AzCore/EBus/EBus.h>
namespace ScriptCanvas
{
enum class ExecuteMode
{
Normal,
UntilNodeIsFoundInStack
};
class SignalInterface : public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
typedef ID BusIdType;
//////////////////////////////////////////////////////////////////////////
virtual void SignalInput(const SlotId& slot) = 0;
virtual void SignalOutput(const SlotId& slot, ExecuteMode mode = ExecuteMode::Normal) = 0;
};
using SignalBus = AZ::EBus<SignalInterface>;
}
@@ -384,15 +384,10 @@ namespace ScriptCanvas
if (m_variable)
{
VariableNotificationBus::Handler::BusConnect(m_variable->GetGraphScopedId());
if (IsInput())
{
m_node->OnInputChanged((*m_variable->GetDatum()), GetId());
}
}
else
else if (m_node)
{
SCRIPTCANVAS_REPORT_ERROR((*m_node), "Node (%s) is attempting to execute using an invalid Variable Reference", m_node->GetNodeName().c_str());
AZ_Warning("ScriptCanvas", false, "Node (%s) is attempting to initialize an invalid Variable Reference", m_node->GetNodeName().c_str());
}
}
}
@@ -584,11 +579,6 @@ namespace ScriptCanvas
return m_isLatentSlot;
}
void Slot::OnVariableValueChanged()
{
m_node->OnInputChanged((*m_variable->GetDatum()), GetId());
}
void Slot::SetDynamicDataType(DynamicDataType dynamicDataType)
{
AZ_Assert(m_dynamicDataType == DynamicDataType::None, "Set Dynamic Data Type is meant to be used for a node wise version conversion step. Not as a run time reconfiguration of a dynamic type.");
@@ -167,10 +167,6 @@ namespace ScriptCanvas
bool IsLatent() const;
// VariableNotificationBus
void OnVariableValueChanged() override;
////
// Here to allow conversion of the previously untyped any slots into the dynamic type any.
void SetDynamicDataType(DynamicDataType dynamicDataType);
@@ -266,16 +266,6 @@ namespace ScriptCanvas
const In* FindIn(const AZStd::string& inSlotId) const;
const Out* FindLatentOut(const AZStd::string& latent) const;
LexicalScope GetLexicalScope(bool isSourcePure) const;
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
public:
bool IsAllInputOutputShared() const;
// all input/output are used in every in/out/latent slot?
bool m_isAllInputOutputShared = false;
void MarkAllInputOutputShared();
#endif
};
AZStd::string ToString(const In& in, size_t tabs = 0);
@@ -1,103 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <ScriptCanvas/Core/Endpoint.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/string/string_view.h>
#include <ScriptCanvas/Core/ExecutionNotificationsBus.h>
#include <ScriptCanvas/Data/Data.h>
#include <ScriptCanvas/Variable/VariableCore.h>
namespace ScriptCanvas
{
struct GraphData;
class GraphVariable;
class VariableData;
using EndpointMapConstIterator = AZStd::unordered_multimap<Endpoint, Endpoint>::const_iterator;
//! Runtime Request Bus for interfacing with the runtime execution component
class RuntimeRequests : public AZ::EBusTraits
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
//! BusIdType represents a unique id for the execution component
//! Because multiple Script Canvas graphs can execute on the same entity
//! this is not an "EntityId" in the sense that it uniquely identifies an entity.
using BusIdType = ScriptCanvasId;
virtual VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeId) const = 0;
virtual VariableId FindRuntimeVariableIdByAssetVariableId(VariableId assetId) const = 0;
virtual AZ::EntityId FindAssetNodeIdByRuntimeNodeId(AZ::EntityId editorNode) const = 0;
virtual AZ::Data::AssetId GetAssetId() const = 0;
virtual GraphIdentifier GetGraphIdentifier() const = 0;
virtual AZStd::string GetAssetName() const = 0;
//! Looks up the nodeId within the bus handler
virtual Node* FindNode(AZ::EntityId nodeId) const = 0;
virtual AZ::EntityId FindRuntimeNodeIdByAssetNodeId(AZ::EntityId runtimeNode) const = 0;
//! Returns the entity id of the execution component
virtual AZ::EntityId GetRuntimeEntityId() const = 0;
//! Returns a container of nodes
virtual AZStd::vector<AZ::EntityId> GetNodes() const = 0;
//! Returns a container of connections
virtual AZStd::vector<AZ::EntityId> GetConnections() const = 0;
//! Returns a container of all endpoints to which the supplied endpoint is connected point
virtual AZStd::vector<Endpoint> GetConnectedEndpoints(const Endpoint& endpoint) const = 0;
virtual AZStd::pair< EndpointMapConstIterator, EndpointMapConstIterator > GetConnectedEndpointIterators(const Endpoint& endpoint) const = 0;
//! Returns whether the given endpoint has any connections
virtual bool IsEndpointConnected(const Endpoint& endpoint) const = 0;
//! Retrieves GraphData structure which manages the nodes and connections of an executing graph
virtual GraphData* GetGraphData() = 0;
virtual const GraphData* GetGraphDataConst() const = 0;
//! Retrieves VariableData structure which manages variable data for the execution component
virtual VariableData* GetVariableData() = 0;
virtual const VariableData* GetVariableDataConst() const = 0;
//! Retrieves a map of variable id to variable name and variable datums pair
virtual const GraphVariableMapping* GetVariables() const = 0;
//! Searches for a variable with the specified name
//! returns pointer to the first variable with the specified name or nullptr
virtual GraphVariable* FindVariable(AZStd::string_view varName) = 0;
//! Searches for a variable by VariableId
//! returns a pair of <variable datum pointer, variable name> with the supplied id
//! The variable datum pointer is non-null if the variable has been found
virtual GraphVariable* FindVariableById(const VariableId& variableId) = 0;
//! Returns the type associated with the specified variable.
virtual Data::Type GetVariableType(const VariableId& variableId) const = 0;
//! Looks up the variable name that the variable data is associated with in the handler of the bus
virtual AZStd::string_view GetVariableName(const VariableId& variableId) const = 0;
virtual bool IsGraphObserved() const = 0;
virtual void SetIsGraphObserved(bool isObserved) = 0;
virtual AZ::Data::AssetType GetAssetType() const = 0;
};
using RuntimeRequestBus = AZ::EBus<RuntimeRequests>;
}
@@ -2248,17 +2248,6 @@ namespace ScriptCanvas
m_subgraphInterface.SetNamespacePath(m_source.m_namespacePath);
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
if (m_source.m_graph->IsFunctionGraph())
{
m_variableScopeMeaning = VariableScopeMeaning_LegacyFunctions::FunctionPrototype;
m_subgraphInterface.MarkAllInputOutputShared();
}
else
{
m_variableScopeMeaning = VariableScopeMeaning_LegacyFunctions::ValueInitialization;
}
#endif
// The Order Matters: begin
// add all data to the ACM for easy look up in input/output processing for ACM nodes
@@ -594,24 +594,6 @@ namespace ScriptCanvas
void ParseExecutionIfStatementBooleanExpression(ExecutionTreePtr booleanExpressionExecution, AZStd::string executionName, LexicalScope lexicalScope);
void ParseExecutionIfStatementInternalFunction(ExecutionTreePtr internalFunctionExecution);
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
public:
AZStd::vector<VariablePtr> FindAllVariablesInVariableFlagScope(VariableFlags::Scope scope) const;
// scrape variables for scope, every Scope::In and InOut
AZStd::vector<VariablePtr> FindSubGraphInputValues() const;
// scrape variables for scope, every Scope::Out and InOut
AZStd::vector<VariablePtr> FindSubGraphOutputValues() const;
AZStd::vector<VariableConstPtr> GetLocalVariablesUser() const;
VariableScopeMeaning_LegacyFunctions GetVariableScopeMeaning() const;
private:
VariableScopeMeaning_LegacyFunctions m_variableScopeMeaning = VariableScopeMeaning_LegacyFunctions::ValueInitialization;
#endif
}; // class AbstractCodeModel
template<typename T>
@@ -1,283 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "PrimitivesDeclarations.h"
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/Datum.h>
#include <ScriptCanvas/Core/EBusHandler.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/GraphData.h>
#include <ScriptCanvas/Core/ModifiableDatumView.h>
#include <ScriptCanvas/Core/Nodeable.h>
#include <ScriptCanvas/Core/NodeableNode.h>
#include <ScriptCanvas/Core/NodeableNodeOverloaded.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <ScriptCanvas/Core/SlotNames.h>
#include <ScriptCanvas/Core/SubgraphInterfaceUtility.h>
#include <ScriptCanvas/Debugger/ValidationEvents/DataValidation/ScopedDataConnectionEvent.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ParsingValidation/ParsingValidations.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
#include <ScriptCanvas/Grammar/ParsingMetaData.h>
#include <ScriptCanvas/Libraries/Core/AzEventHandler.h>
#include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
#include <ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h>
#include <ScriptCanvas/Libraries/Core/ExtractProperty.h>
#include <ScriptCanvas/Libraries/Core/ForEach.h>
#include <ScriptCanvas/Libraries/Core/FunctionCallNode.h>
#include <ScriptCanvas/Libraries/Core/Method.h>
#include <ScriptCanvas/Libraries/Core/MethodUtility.h>
#include <ScriptCanvas/Libraries/Core/Start.h>
#include <ScriptCanvas/Translation/TranslationUtilities.h>
#include <ScriptCanvas/Utils/VersionConverters.h>
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
#include <ScriptCanvas/Variable/VariableBus.h>
#include <ScriptCanvas/Variable/VariableData.h>
#include <ScriptEvents/ScriptEventsAsset.h>
#include <ScriptEvents/ScriptEventsBus.h>
#include "AbstractCodeModel.h"
#include "FunctionsLegacySupport.h"
#include "GrammarContextBus.h"
#include "ParsingUtilities.h"
#include "Primitives.h"
namespace ScriptCanvas
{
namespace Grammar
{
void AbstractCodeModel::AddAllVariablesPreParse_LegacyFunctions()
{
// all variables assumed to be NOT persistent - in the live code they are reset when activated
// variables with no scope In/Out is assumed to be persistent, this is a mess with tick handlers
// warn on any variable attempted to be read before written
AZ_Assert(m_variableScopeMeaning == VariableScopeMeaning_LegacyFunctions::FunctionPrototype, "new graph type added without full support");
auto& sourceVariables = m_source.m_variableData->GetVariables();
AZStd::set<const GraphVariable*, GraphVariable::Comparator> sortedVariables;
for (const auto& variablePair : sourceVariables)
{
sortedVariables.insert(&variablePair.second);
}
for (auto& sourceVariable : sortedVariables)
{
auto datum = sourceVariable->GetDatum();
AZ_Assert(datum != nullptr, "the datum must be valid");
AddVariable(*datum, sourceVariable->GetVariableName(), sourceVariable->GetVariableId());
}
}
AZStd::vector<VariablePtr> AbstractCodeModel::FindSubGraphInputValues() const
{
return FindAllVariablesInVariableFlagScope(VariableFlags::Scope::Input);
}
AZStd::vector<VariablePtr> AbstractCodeModel::FindSubGraphOutputValues() const
{
return FindAllVariablesInVariableFlagScope(VariableFlags::Scope::Output);
}
AZStd::vector<VariablePtr> AbstractCodeModel::FindAllVariablesInVariableFlagScope(VariableFlags::Scope scope) const
{
AZStd::vector<VariablePtr> variables;
auto& sourceVariables = m_source.m_variableData->GetVariables();
for (auto& variable : m_variables)
{
if (IsSourceInScope(variable, scope))
{
variables.push_back(variable);
}
}
// sort by variable id
AZStd::sort(variables.begin(), variables.end(), [](const auto& lhs, const auto& rhs) { return lhs->m_sourceVariableId < rhs->m_sourceVariableId; });
return variables;
}
AZStd::vector<VariableConstPtr> AbstractCodeModel::GetLocalVariablesUser() const
{
AZStd::vector<VariableConstPtr> userLocalVariables;
if (m_variableScopeMeaning == VariableScopeMeaning_LegacyFunctions::FunctionPrototype)
{
for (auto variable : m_variables)
{
if (!variable->m_isMember
&& variable->m_sourceVariableId.IsValid()
&& !IsSourceInScope(variable, VariableFlags::Scope::Input)
&& !IsSourceInScope(variable, VariableFlags::Scope::Output))
{
userLocalVariables.push_back(variable);
}
}
}
return userLocalVariables;
}
VariableScopeMeaning_LegacyFunctions AbstractCodeModel::GetVariableScopeMeaning() const
{
return m_variableScopeMeaning;
}
bool SubgraphInterface::IsAllInputOutputShared() const
{
return m_isAllInputOutputShared;
}
void SubgraphInterface::MarkAllInputOutputShared()
{
m_isAllInputOutputShared = true;
}
} // namespace Grammar
namespace Nodes
{
namespace Core
{
void FunctionCallNode::BuildNodeFromSubgraphInterface
(const AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>& runtimeAsset
, const SlotExecution::Map& previousMap)
{
// build the node here, from the asset topology, take the node/variable ordering from the function runtime data as a suggestion
// deal with updates and conversions after
const Grammar::SubgraphInterface& subgraphInterface = runtimeAsset.Get()->m_runtimeData.m_interface;
m_prettyName = runtimeAsset.Get()->m_runtimeData.m_name;
if (!subgraphInterface.IsAllInputOutputShared())
{
AZ_Error("ScriptCanvas", false, "the current assumption is that there is no way to distinguish between the input/output of different nodelings");
return;
}
// for now, all outputs are shared
Grammar::Outputs outputs;
bool sharedOutputInitialized = false;
SlotExecution::Ins slotMapIns;
SlotExecution::Outs slotMapLatents;
int slotOffset = 0;
// add all ins->outs, in their display groups
for (size_t indexIn = 0; indexIn < subgraphInterface.GetInCount(); ++indexIn)
{
const Grammar::In& interfaceIn = subgraphInterface.GetIn(indexIn);
SlotExecution::In slotMapIn = AddExecutionInSlotFromInterface(interfaceIn, slotOffset++, previousMap.FindInSlotIdBySource(interfaceIn.sourceID));
if (!slotMapIn.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Execution In slot from sub graph interface");
return;
}
slotMapIn.inputs = AddDataInputSlotFromInterface(interfaceIn.inputs, interfaceIn.sourceID, interfaceIn.displayName, previousMap, slotOffset);
for (auto& input : slotMapIn.inputs)
{
if (!input.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Input slot from sub graph interface");
return;
}
}
for (auto& interfaceOut : interfaceIn.outs)
{
SlotExecution::Out slotMapOut = AddExecutionOutSlotFromInterface(interfaceIn, interfaceOut, slotOffset++, previousMap.FindOutSlotIdBySource(interfaceIn.sourceID, interfaceOut.sourceID));
if (!slotMapOut.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Execution Out slot from sub graph interface");
return;
}
if (!sharedOutputInitialized)
{
outputs = interfaceOut.outputs;
sharedOutputInitialized = true;
}
slotMapIn.outs.push_back(slotMapOut);
}
slotMapIns.push_back(slotMapIn);
}
// add all latents in their display groups
for (size_t indexLatent = 0; indexLatent < subgraphInterface.GetLatentOutCount(); ++indexLatent)
{
const Grammar::Out& interfaceLatent = subgraphInterface.GetLatentOut(indexLatent);
SlotExecution::Out slotMapLatentOut = AddExecutionLatentOutSlotFromInterface(interfaceLatent, slotOffset++, previousMap.FindLatentSlotIdBySource(interfaceLatent.sourceID));
if (!slotMapLatentOut.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Latent Out slot from sub graph interface");
return;
}
slotMapLatentOut.returnValues.values = AddDataInputSlotFromInterface(interfaceLatent.returnValues, interfaceLatent.sourceID, interfaceLatent.displayName, previousMap, slotOffset);
for (auto& input : slotMapLatentOut.returnValues.values)
{
if (!input.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Input slot from sub graph interface");
return;
}
}
if (!sharedOutputInitialized)
{
outputs = interfaceLatent.outputs;
sharedOutputInitialized = true;
}
slotMapLatents.push_back(slotMapLatentOut);
}
// add all outputs one time, since they are currently all required to be part of all the signatures [\todo must fix] , in a variable display group
SlotExecution::Outputs slotMapOutputs = AddDataOutputSlotFromInterface(outputs, "", previousMap, slotOffset);
for (auto& output : slotMapOutputs)
{
if (!output.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Output slot from sub graph interface");
return;
}
}
if (!subgraphInterface.IsLatent())
{
for (auto& slotMapIn : slotMapIns)
{
for (auto& slotMapOut : slotMapIn.outs)
{
slotMapOut.outputs = slotMapOutputs;
}
}
}
else
{
for (auto& slotMapLatent : slotMapLatents)
{
slotMapLatent.outputs = slotMapOutputs;
}
}
// when returning variables: sort variables by source slot id, they are sorted in the slot map, so just take them from the slot map
m_slotExecutionMap = AZStd::move(SlotExecution::Map(AZStd::move(slotMapIns), AZStd::move(slotMapLatents)));
m_slotExecutionMapSourceInterface = subgraphInterface;
m_asset = runtimeAsset;
SignalSlotsReordered();
}
} // namespace Core
} // namespace Nodes
}
#endif
@@ -1,20 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
namespace ScriptCanvas
{
namespace Grammar
{
enum class VariableScopeMeaning_LegacyFunctions : AZ::u32
{
ValueInitialization,
FunctionPrototype,
};
}
}
@@ -19,10 +19,6 @@
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/string/string.h>
#if defined (FUNCTION_LEGACY_SUPPORT_ENABLED)
#include "FunctionsLegacySupport.h"
#endif
namespace AZ
{
class ReflectContext;
@@ -23,15 +23,6 @@ namespace ScriptCanvas
}
}
//////////////////
// BaseTimerNode
//////////////////
BaseTimerNode::~BaseTimerNode()
{
StopTimer();
}
void BaseTimerNode::OnInit()
{
AZStd::string slotName = GetTimeSlotName();
@@ -74,11 +65,6 @@ namespace ScriptCanvas
AddTimeDataSlot();
}
void BaseTimerNode::OnDeactivate()
{
StopTimer();
}
void BaseTimerNode::ConfigureVisualExtensions()
{
{
@@ -103,54 +89,7 @@ namespace ScriptCanvas
return nullptr;
}
void BaseTimerNode::OnSystemTick()
{
AZ::SystemTickBus::Handler::BusDisconnect();
if (!AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusConnect();
}
}
void BaseTimerNode::OnTick(float delta, AZ::ScriptTimePoint)
{
if (m_timeUnits == TimeUnits::Ticks)
{
m_timerCounter += 1;
}
switch (m_timeUnits)
{
case TimeUnits::Ticks:
m_timerCounter += 1;
break;
case TimeUnits::Milliseconds:
case TimeUnits::Seconds:
m_timerCounter += delta;
break;
default:
break;
}
while (m_timerCounter > m_timerDuration)
{
if (!m_isActive)
{
break;
}
m_timerCounter -= m_timerDuration;
OnTimeElapsed();
}
}
int BaseTimerNode::GetTickOrder()
{
return m_tickOrder;
}
void BaseTimerNode::AddTimeDataSlot()
{
if (!m_timeSlotId.IsValid())
@@ -174,70 +113,6 @@ namespace ScriptCanvas
}
}
void BaseTimerNode::StartTimer()
{
StopTimer();
m_isActive = true;
const Datum* datum = FindDatum(m_timeSlotId);
if (datum)
{
const Data::NumberType* timeAmount = datum->GetAs<Data::NumberType>();
if (timeAmount)
{
m_timerDuration = (*timeAmount);
m_timerCounter = 0;
// Manage the different unit types
if (m_timeUnits == TimeUnits::Ticks)
{
// Remove all of the floating points
m_timerDuration = aznumeric_cast<float>(aznumeric_cast<int>(m_timerDuration));
}
else if (m_timeUnits == TimeUnits::Milliseconds)
{
m_timerDuration /= 1000.0;
}
}
}
if (AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusDisconnect();
}
if (AZ::SystemTickBus::Handler::BusIsConnected())
{
AZ::SystemTickBus::Handler::BusDisconnect();
}
if (!AZ::IsClose(m_timerDuration, 0.0, DBL_EPSILON))
{
AZ::SystemTickBus::Handler::BusConnect();
}
else if (AllowInstantResponse())
{
while (m_isActive)
{
OnTimeElapsed();
}
}
}
void BaseTimerNode::StopTimer()
{
m_isActive = false;
m_timerCounter = 0.0;
m_timerDuration = 0.0;
AZ::SystemTickBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
}
AZStd::string BaseTimerNode::GetTimeSlotName() const
{
return GetBaseTimeSlotName();
@@ -283,11 +158,7 @@ namespace ScriptCanvas
{
return false;
}
void BaseTimerNode::OnTimeElapsed()
{
}
void BaseTimerNode::ConfigureTimeSlot(DataSlotConfiguration& configuration)
{
AZ_UNUSED(configuration);
@@ -7,10 +7,7 @@
#pragma once
#include <AzCore/Component/TickBus.h>
#include <ScriptCanvas/Core/Node.h>
#include <Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.generated.h>
namespace ScriptCanvas
@@ -23,8 +20,6 @@ namespace ScriptCanvas
class BaseTimerNode
: public Node
, public NodePropertyInterfaceListener
, public AZ::TickBus::Handler
, public AZ::SystemTickBus::Handler
{
public:
@@ -44,32 +39,16 @@ namespace ScriptCanvas
"Seconds"
};
virtual ~BaseTimerNode();
// Node...
void OnInit() override;
void OnConfigured() override;
void OnDeactivate() override;
void ConfigureVisualExtensions() override;
NodePropertyInterface* GetPropertyInterface(AZ::Crc32 propertyId) override;
////
// SystemTickBus...
void OnSystemTick() override;
////
// TickBus...
void OnTick(float delta, AZ::ScriptTimePoint timePoint) override;
int GetTickOrder() override;
////
// Method that will handle displaying and viewing of the time slot
void AddTimeDataSlot();
void StartTimer();
void StopTimer();
AZStd::string GetTimeSlotName() const;
protected:
@@ -83,7 +62,6 @@ namespace ScriptCanvas
bool IsActive() const;
virtual bool AllowInstantResponse() const;
virtual void OnTimeElapsed();
// Store until versioning is complete
virtual const char* GetTimeSlotFormat() const { return "Time (%s)"; }
@@ -112,37 +112,6 @@ namespace ScriptCanvas
}
}
void ExpressionNodeBase::OnInputSignal(const SlotId& slotId)
{
if (slotId == ExpressionNodeBaseProperty::GetInSlotId(this))
{
for (const SlotId& dirtySlotId : m_dirtyInputs)
{
auto variableIter = m_slotToVariableMap.find(dirtySlotId);
if (variableIter != m_slotToVariableMap.end())
{
PushVariable(variableIter->second, (*FindDatum(dirtySlotId)));
}
}
m_dirtyInputs.clear();
if (m_parseError.IsValidExpression() && m_expressionTree.GetTreeSize() != 0)
{
ExpressionEvaluation::ExpressionResult expressionResult;
ExpressionEvaluation::ExpressionEvaluationRequestBus::BroadcastResult(expressionResult, &ExpressionEvaluation::ExpressionEvaluationRequests::Evaluate, m_expressionTree);
OnResult(expressionResult);
}
}
}
void ExpressionNodeBase::OnInputChanged([[maybe_unused]] const Datum& input, const SlotId& slotId)
{
m_dirtyInputs.insert(slotId);
}
bool ExpressionNodeBase::CanDeleteSlot([[maybe_unused]] const SlotId& slotId) const
{
return m_handlingExtension;
@@ -53,10 +53,6 @@ namespace ScriptCanvas
void OnInit() override;
void OnPostActivate() override;
void ConfigureVisualExtensions() override;
void OnInputSignal(const SlotId& slotId) override;
void OnInputChanged(const Datum& input, const SlotId& slotId) override;
bool CanDeleteSlot(const SlotId& slotId) const override;
SlotId HandleExtension(AZ::Crc32 extensionId) override;
@@ -110,7 +106,6 @@ namespace ScriptCanvas
bool m_isInError = false;
AZStd::unordered_map<SlotId, AZStd::string> m_slotToVariableMap;
AZStd::unordered_set<SlotId> m_dirtyInputs;
AZStd::unordered_map<AZStd::string, SlotId> m_slotsByVariables;
ExpressionEvaluation::ParsingError m_parseError;
@@ -41,22 +41,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs == rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -40,21 +40,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs > rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -41,21 +41,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs >= rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -40,22 +40,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs < rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -40,22 +40,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs <= rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -40,22 +40,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs != rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -75,20 +75,6 @@ namespace ScriptCanvas
}
}
void ArithmeticExpression::OnInputSignal(const SlotId& slotId)
{
if (slotId == GetSlotId(k_evaluateName))
{
const Datum output = Evaluate(*FindDatumByIndex(k_datumIndexLHS), *FindDatumByIndex(k_datumIndexRHS));
if (auto slot = GetSlot(GetOutputSlotId()))
{
PushOutput(output, *slot);
}
SignalOutput(GetSlotId(k_outName));
}
}
void ArithmeticExpression::Reflect(AZ::ReflectContext* reflection)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
@@ -107,17 +93,6 @@ namespace ScriptCanvas
}
}
Datum BinaryOperator::Evaluate([[maybe_unused]] const Datum& lhs, [[maybe_unused]] const Datum& rhs)
{
AZ_Assert(false, "Evaluate must be overridden");
return Datum();
};
void BinaryOperator::OnInputSignal([[maybe_unused]] const SlotId& slot)
{
AZ_Assert(false, "OnInputSignal must be overridden");
}
void BinaryOperator::OnInit()
{
{
@@ -159,28 +134,6 @@ namespace ScriptCanvas
AZ_Assert(false, "InitializeBooleanExpression must be overridden");
}
void BooleanExpression::OnInputSignal(const SlotId& slotId)
{
if (slotId == GetSlotId(k_evaluateName))
{
const Datum output = Evaluate(*FindDatumByIndex(k_datumIndexLHS), *FindDatumByIndex(k_datumIndexRHS));
if (auto slot = GetSlot(GetOutputSlotId()))
{
PushOutput(output, *slot);
}
const bool* result = output.GetAs<bool>();
if (result && *result)
{
SignalOutput(GetSlotId(k_onTrue));
}
else
{
SignalOutput(GetSlotId(k_onFalse));
}
}
}
void BooleanExpression::OnInit()
{
{
@@ -31,9 +31,7 @@ namespace ScriptCanvas
static const char* k_evaluateName;
static const char* k_outName;
static const char* k_onTrue;
static const char* k_onFalse;
static const char* k_onFalse;
protected:
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& /*executionSlot*/, CombinedSlotType targetSlotType, const Slot* /*executionChildSlot*/) const override
@@ -47,12 +45,6 @@ namespace ScriptCanvas
void OnInit() override;
// must be overridden with the binary operations
virtual Datum Evaluate(const Datum& lhs, const Datum& rhs);
// Triggered by the execution signal
void OnInputSignal(const SlotId& slot) override;
SlotId GetOutputSlotId() const;
};
@@ -71,10 +63,6 @@ namespace ScriptCanvas
protected:
// adds Number inputs, adds Number output type
void OnInit() override;
void OnInputSignal(const SlotId& slot) override;
};
class BooleanExpression
@@ -107,9 +95,7 @@ namespace ScriptCanvas
protected:
// initialize boolean expression, adds boolean output type calls
void OnInit() override;
virtual void InitializeBooleanExpression();
void OnInputSignal(const SlotId& slot) override;
virtual void InitializeBooleanExpression();
};
// accepts any type, checks for type equality, and then value equality or pointer equality
@@ -126,10 +112,8 @@ namespace ScriptCanvas
void InitializeBooleanExpression() override;
private:
SlotId m_firstSlotId;
SlotId m_secondSlotId;
ScriptCanvas::Data::Type m_displayType;
};
@@ -144,8 +128,7 @@ namespace ScriptCanvas
protected:
// adds number types
void InitializeBooleanExpression() override;
void InitializeBooleanExpression() override;
};
}
}
@@ -9,7 +9,6 @@
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/Utils.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Grammar/Primitives.h>
#include <ScriptCanvas/Grammar/ParsingUtilities.h>
#include <ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.h>
@@ -59,16 +58,6 @@ namespace ScriptCanvas
SetAutoConnectToGraphOwner(m_autoConnectToGraphOwner);
}
void EBusEventHandler::OnPostActivate()
{
}
void EBusEventHandler::OnDeactivate()
{
Disconnect();
}
void EBusEventHandler::OnGraphSet()
{
GraphScopedNodeId scopedNodeId(GetOwningScriptCanvasId(), GetEntityId());
@@ -127,14 +116,6 @@ namespace ScriptCanvas
}
}
void EBusEventHandler::Connect()
{
}
void EBusEventHandler::Disconnect()
{
}
AZ::Outcome<DependencyReport, void> EBusEventHandler::GetDependencies() const
{
return AZ::Success(DependencyReport{});
@@ -515,7 +496,6 @@ namespace ScriptCanvas
const AZ::BehaviorEBusHandler::BusForwarderEvent& event = events[eventIndex];
AZ_Assert(!event.m_parameters.empty(), "No parameters in event!");
m_handler->InstallGenericHook(events[eventIndex].m_name, &OnEventGenericHook, this);
if (m_eventMap.find(AZ::Crc32(event.m_name)) != m_eventMap.end())
{
@@ -621,137 +601,6 @@ namespace ScriptCanvas
}
}
void EBusEventHandler::OnEvent(const char* eventName, const int /*eventIndex*/, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "EBusEventHandler::OnEvent %s", eventName);
SCRIPTCANVAS_RETURN_IF_ERROR_STATE((*this));
auto iter = m_eventMap.find(AZ::Crc32(eventName));
if (iter == m_eventMap.end())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Invalid event index in Ebus handler");
return;
}
EBusEventEntry& ebusEventEntry = iter->second;
if (!ebusEventEntry.m_shouldHandleEvent || ebusEventEntry.m_isHandlingEvent)
{
AZ_Warning("ScriptCanvas", !ebusEventEntry.m_isHandlingEvent, "Found situation where in handling event(%s::%s) triggered the same event. Possible infinite loop, not handling second call.", GetEBusName().c_str(), eventName);
return;
}
ebusEventEntry.m_isHandlingEvent = true;
ebusEventEntry.m_resultEvaluated = !ebusEventEntry.IsExpectingResult();
AZ_Assert(ebusEventEntry.m_eventName.compare(eventName) == 0, "Wrong event handled by this EBusEventHandler! received %s, expected %s", eventName, ebusEventEntry.m_eventName.c_str());
AZ_Assert(numParameters == ebusEventEntry.m_numExpectedArguments, "Wrong number of events passed into EBusEventHandler %s", eventName);
// route my parameters to the connect nodes input
AZ_Assert(ebusEventEntry.m_parameterSlotIds.size() == numParameters, "Node %s-%s Num parameters = %d, but num output slots = %d", m_ebusName.c_str(), ebusEventEntry.m_eventName.c_str(), numParameters, ebusEventEntry.m_parameterSlotIds.size());
for (int parameterIndex(0); parameterIndex < numParameters; ++parameterIndex)
{
const Slot* slot = GetSlot(ebusEventEntry.m_parameterSlotIds[parameterIndex]);
const auto& value = *(parameters + parameterIndex);
const Datum input(value);
PushOutput(input, (*slot));
}
// now, this should pass execution off to the nodes that will push their output into this result input
SignalOutput(ebusEventEntry.m_eventSlotId, ExecuteMode::UntilNodeIsFoundInStack);
// route executed nodes output to my input, and my input to the result
if (ebusEventEntry.IsExpectingResult())
{
if (result)
{
if (const Datum* resultInput = FindDatum(ebusEventEntry.m_resultSlotId))
{
ebusEventEntry.m_resultEvaluated = resultInput->ToBehaviorContext(*result);
AZ_Warning("Script Canvas", ebusEventEntry.m_resultEvaluated, "Script Canvas failed to write a value back to the caller!");
}
else
{
AZ_Warning("Script Canvas", false, "Script Canvas handler expecting a result, but had no ability to return it");
}
}
else
{
AZ_Warning("Script Canvas", false, "Script Canvas handler is expecting a result, but was called without expecting one!");
}
}
else
{
AZ_Warning("Script Canvas", !result, "Script Canvas handler is not expecting a result, but was called expecting one!");
}
// route executed nodes output to my input, and my input to the result
AZ_Warning("Script Canvas", (result != nullptr) == ebusEventEntry.IsExpectingResult(), "Node %s-%s mismatch between expecting a result and getting one!", m_ebusName.c_str(), ebusEventEntry.m_eventName.c_str());
AZ_Warning("Script Canvas", ebusEventEntry.m_resultEvaluated, "Node %s-%s result not evaluated properly!", m_ebusName.c_str(), ebusEventEntry.m_eventName.c_str());
ebusEventEntry.m_isHandlingEvent = false;
}
void EBusEventHandler::OnInputSignal(const SlotId& slotId)
{
SlotId connectSlot = EBusEventHandlerProperty::GetConnectSlotId(this);
SlotId disconnectSlot = EBusEventHandlerProperty::GetDisconnectSlotId(this);
if (connectSlot == slotId)
{
if (IsIDRequired())
{
const Datum* busIdDatum = FindDatum(GetSlotId(c_busIdName));
if (!busIdDatum || busIdDatum->Empty())
{
SlotId failureSlot = EBusEventHandlerProperty::GetOnFailureSlotId(this);
SignalOutput(failureSlot);
SCRIPTCANVAS_REPORT_ERROR((*this), "In order to connect this node, a valid BusId must be provided.");
return;
}
}
Disconnect();
Connect();
SlotId onConnectSlotId = EBusEventHandlerProperty::GetOnConnectedSlotId(this);
SignalOutput(onConnectSlotId);
return;
}
else if (disconnectSlot == slotId)
{
Disconnect();
SlotId onDisconnectSlotId = EBusEventHandlerProperty::GetOnDisconnectedSlotId(this);
SignalOutput(onDisconnectSlotId);
return;
}
}
void EBusEventHandler::OnInputChanged(const Datum& /*input*/, const SlotId& /*slotId*/)
{
/*
if (GetExecutionType() == ExecutionType::Runtime
&& m_autoConnectToGraphOwner
&& slotId == FindSlotIdForDescriptor(c_busIdName, SlotDescriptors::DataIn()))
{
Disconnect();
Connect();
}
*/
}
void EBusEventHandler::OnEventGenericHook(void* userData, const char* eventName, int eventIndex, AZ::BehaviorValueParameter* result, int numParameters, AZ::BehaviorValueParameter* parameters)
{
EBusEventHandler* handler(reinterpret_cast<EBusEventHandler*>(userData));
handler->OnEvent(eventName, eventIndex, result, numParameters, parameters);
}
void EBusEventHandler::OnWriteEnd()
{
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
@@ -78,9 +78,6 @@ namespace ScriptCanvas
void OnInit() override;
void OnActivate() override;
void OnPostActivate() override;
void OnDeactivate() override;
void OnGraphSet() override;
void CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const override;
@@ -96,16 +93,10 @@ namespace ScriptCanvas
void InitializeEvent(int eventIndex);
bool IsOutOfDate(const VersionData& graphVersion) const override;
bool IsOutOfDate(const VersionData& graphVersion) const override;
bool CreateHandler(AZStd::string_view ebusName);
void Connect();
void Disconnect();
const EBusEventEntry* FindEventWithSlot(const Slot& slot) const;
AZ::Outcome<AZStd::string, void> GetFunctionCallName(const Slot* /*slot*/) const override;
@@ -166,16 +157,10 @@ namespace ScriptCanvas
inline bool IsConfigured() const { return !m_eventMap.empty(); }
void OnEvent(const char* eventName, const int eventIndex, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters);
void OnInputSignal(const SlotId&) override;
void OnInputChanged(const Datum& input, const SlotId& slotID) override;
private:
EBusEventHandler(const EBusEventHandler&) = delete;
static void OnEventGenericHook(void* userData, const char* eventName, int eventIndex, AZ::BehaviorValueParameter* result, int numParameters, AZ::BehaviorValueParameter* parameters);
EventMap m_eventMap;
AZStd::string m_ebusName;
ScriptCanvas::EBusBusId m_busId;
@@ -63,43 +63,6 @@ namespace ScriptCanvas
}
}
void GetVariableNode::OnInputSignal(const SlotId& slotID)
{
if (slotID == GetSlotId("In"))
{
SC_EXECUTION_TRACE_ANNOTATE_NODE((*this), CreateAnnotationData());
if (m_variableView.IsValid())
{
Slot* resultSlot = GetSlot(m_variableDataOutSlotId);
if (resultSlot)
{
const Datum* inputDatum = m_variableView.GetDatum();
PushOutput(*inputDatum, *resultSlot);
// Push the data for each property slot out as well
for (auto&& propertyAccount : m_propertyAccounts)
{
Slot* propertySlot = GetSlot(propertyAccount.m_propertySlotId);
if (propertySlot && propertyAccount.m_getterFunction)
{
auto outputOutcome = propertyAccount.m_getterFunction(*inputDatum);
if (!outputOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), outputOutcome.TakeError().data());
return;
}
PushOutput(outputOutcome.TakeValue(), *propertySlot);
}
}
}
}
SignalOutput(GetSlotId("Out"));
}
}
void GetVariableNode::CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const
{
if (m_variableId.IsValid())
@@ -324,8 +287,9 @@ namespace ScriptCanvas
ScriptCanvas::Data::Type baseType = ScriptCanvas::Data::Type::Invalid();
VariableRequestBus::EventResult(baseType, GetScopedVariableId(), &VariableRequests::GetType);
const GraphVariableMapping* variableMap = GetRuntimeBus()->GetVariables();
const GraphVariableMapping* variableMap = nullptr;
GraphRequestBus::EventResult(variableMap, *GraphNotificationBus::GetCurrentBusId(), &GraphRequests::GetVariables);
if (variableMap && baseType.IsValid())
{
for (const auto& variablePair : *variableMap)
@@ -360,12 +324,6 @@ namespace ScriptCanvas
VariableNodeNotificationBus::Event(GetEntityId(), &VariableNodeNotifications::OnVariableRemovedFromNode, removedVariableId);
}
AnnotateNodeSignal GetVariableNode::CreateAnnotationData()
{
AZ::EntityId assetNodeId = GetRuntimeBus()->FindAssetNodeIdByRuntimeNodeId(GetEntityId());
return AnnotateNodeSignal(CreateGraphInfo(GetOwningScriptCanvasId(), GetGraphIdentifier()), AnnotateNodeSignal::AnnotationLevel::Info, m_variableName, AZ::NamedEntityId(assetNodeId, GetNodeName()));
}
VariableId GetVariableNode::GetVariableIdRead(const Slot*) const
{
return m_variableId;
@@ -64,7 +64,6 @@ namespace ScriptCanvas
void OnInit() override;
void OnPostActivate() override;
void OnInputSignal(const SlotId&) override;
void AddOutputSlot();
void RemoveOutputSlot();
@@ -78,8 +77,6 @@ namespace ScriptCanvas
void OnVariableRemoved() override;
////
AnnotateNodeSignal CreateAnnotationData();
// Adds/Remove Property Slots from the GetVariable node
void AddPropertySlots(const Data::Type& type);
void ClearPropertySlots();
@@ -11,105 +11,6 @@
namespace ScriptCanvas
{
int CountMatchingInputTypes(const Grammar::FunctionPrototype& a, const Grammar::FunctionPrototype& b, const AZStd::vector<size_t>& checkedIndices)
{
AZ_Warning("ScriptCanvas", a.m_inputs.size() == b.m_inputs.size(), "Function inputs are not the same size");
int matching = 0;
if (a.m_inputs.size() == b.m_inputs.size())
{
if (checkedIndices.empty())
{
for (size_t index = 0; index < a.m_inputs.size(); ++index)
{
if (!a.m_inputs[index]->m_datum.GetType().IsValid()
|| a.m_inputs[index]->m_datum.GetType() == b.m_inputs[index]->m_datum.GetType())
{
++matching;
}
}
}
else
{
for (const auto checkedIndex : checkedIndices)
{
const auto index = checkedIndices[checkedIndex];
if (index < a.m_inputs.size())
{
if (!a.m_inputs[index]->m_datum.GetType().IsValid()
|| a.m_inputs[index]->m_datum.GetType() == b.m_inputs[index]->m_datum.GetType())
{
++matching;
}
}
else
{
AZ_Error("ScriptCanvas", false, "Overload checked index is no longer valid");
}
}
}
}
return matching;
}
BehaviorContextMethodHelper::CallResult BehaviorContextMethodHelper::Call(Node& node, bool isExpectingMultipleResults, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, AZStd::vector<SlotId>& resultSlotIds)
{
if (isExpectingMultipleResults)
{
return BehaviorContextMethodHelper::Call(node, method, paramBegin, paramEnd, resultSlotIds);
}
else
{
return BehaviorContextMethodHelper::Call(node, method, paramBegin, paramEnd, resultSlotIds[0]);
}
}
BehaviorContextMethodHelper::CallResult BehaviorContextMethodHelper::Call(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, SlotId resultSlotId)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Method::OnInputSignal::Call %s", method->m_name.c_str());
return CallGeneric(node, method, paramBegin, paramEnd, &AttemptCallWithResults, resultSlotId);
}
BehaviorContextMethodHelper::CallResult BehaviorContextMethodHelper::Call(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, AZStd::vector<SlotId>& resultSlotIds)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Method::OnInputSignal::Call %s", method->m_name.c_str());
return CallGeneric(node, method, paramBegin, paramEnd, &AttemptCallWithTupleResults, resultSlotIds);
}
AZ::Outcome<BehaviorContextMethodHelper::CallResult, AZStd::string> BehaviorContextMethodHelper::AttemptCallWithResults(Node&, const AZ::BehaviorMethod*, AZ::BehaviorValueParameter*, unsigned int, SlotId)
{
return AZ::Failure(AZStd::string("This method is slated for deletion"));
}
AZ::Outcome<BehaviorContextMethodHelper::CallResult, AZStd::string> BehaviorContextMethodHelper::AttemptCallWithTupleResults(Node&, const AZ::BehaviorMethod*, AZ::BehaviorValueParameter*, unsigned int, AZStd::vector<SlotId>)
{
return AZ::Failure(AZStd::string("This method is slated for deletion"));
}
AZ::Outcome<Datum, AZStd::string> BehaviorContextMethodHelper::CallTupleGetMethod(const AZ::BehaviorMethod*, Datum&)
{
return AZ::Failure(AZStd::string("This method is slated for deletion"));
}
AZ::Outcome<BehaviorContextMethodHelper::CallResult, AZStd::string> BehaviorContextMethodHelper::CallOutcomeTupleMethod(Node&, const SlotId&, Datum&, size_t, AZStd::string)
{
return AZ::Failure(AZStd::string("to be deleted"));
}
AZ::BehaviorValueParameter BehaviorContextMethodHelper::ToBehaviorValueParameter(const AZ::BehaviorMethod* method, size_t index, const Datum& datum)
{
const AZ::BehaviorParameter* datumParam = method->GetArgument(index);
auto toParamOutcome = datumParam ? datum.ToBehaviorValueParameter(*datumParam) : AZ::Failure(AZStd::string::format("BehaviorMethod contains nullptr BehaviorParameter at index %zu", index));
if (toParamOutcome)
{
return AZ::BehaviorValueParameter(toParamOutcome.TakeValue());
}
return AZ::BehaviorValueParameter();
}
AZStd::unordered_map<size_t, const AZ::BehaviorMethod*> GetTupleGetMethodsFromResult(const AZ::BehaviorMethod& method)
{
if (method.HasResult())
@@ -19,202 +19,9 @@ namespace ScriptCanvas::Grammar
namespace ScriptCanvas
{
int CountMatchingInputTypes(const Grammar::FunctionPrototype& a, const Grammar::FunctionPrototype& b, const AZStd::vector<size_t>& checkedIndices);
struct BehaviorContextMethodHelper
{
enum BehaviorContextInputOutput : size_t
{
MaxCount = 40,
};
enum class MethodCallStatus
{
NotAttempted = 0,
Attempted,
Failed,
Succeeded,
};
struct CallResult
{
const MethodCallStatus m_status = MethodCallStatus::NotAttempted;
const AZStd::string m_executionOutOverride = "Out";
AZ_INLINE CallResult(const MethodCallStatus status, AZStd::string executionOutOverride = "Out")
: m_status(status)
, m_executionOutOverride(executionOutOverride)
{}
};
template<typename t_Call, typename t_Slots>
static CallResult CallGeneric(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, t_Call attempt, t_Slots& slots);
static CallResult Call(Node& node, bool isExpectingMultipleResults, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, AZStd::vector<SlotId>& resultSlotIds);
static CallResult Call(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, SlotId resultSlotId);
static CallResult Call(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, AZStd::vector<SlotId>& resultSlotIds);
static AZ::Outcome<CallResult, AZStd::string> AttemptCallWithResults(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* params, unsigned int numExpectedArgs, SlotId resultSlotId);
static AZ::Outcome<CallResult, AZStd::string> AttemptCallWithTupleResults(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* params, unsigned int numExpectedArgs, AZStd::vector<SlotId> resultSlotIds);
template<typename ... Args>
static AZ::Outcome<Datum, AZStd::string> CallMethodOnDatum(const Datum& input, AZStd::string_view methodName, Args&& ... args);
template<typename ... Args>
static AZ::Outcome<Datum, AZStd::string> CallMethodOnDatumUnpackOutcomeSuccess(const Datum& input, AZStd::string_view methodName, Args&& ... args);
template<typename ... Args>
static AZStd::vector<AZ::BehaviorValueParameter> CreateParameterList(const AZ::BehaviorMethod* method, Args&&... args);
static AZ::Outcome<Datum, AZStd::string> CallTupleGetMethod(const AZ::BehaviorMethod* method, Datum& thisPointer);
private:
static AZ::Outcome<CallResult, AZStd::string> CallOutcomeTupleMethod(Node& node, const SlotId& resultSlotId, Datum& outcomeDatum, size_t index, AZStd::string outSlotName);
static AZ::BehaviorValueParameter ToBehaviorValueParameter(const AZ::BehaviorMethod* method, size_t index, const Datum& datum);
template <typename T>
static AZ::BehaviorValueParameter ToBehaviorValueParameter(const AZ::BehaviorMethod*, size_t, const T& arg);
template<typename ... Args, size_t ... Indices>
static AZStd::vector<AZ::BehaviorValueParameter> CreateParameterListInternal(const AZ::BehaviorMethod* method, AZStd::index_sequence<Indices...>, Args&&... args);
};
AZStd::unordered_map<size_t, const AZ::BehaviorMethod*> GetTupleGetMethodsFromResult(const AZ::BehaviorMethod& method);
AZStd::unordered_map<size_t, const AZ::BehaviorMethod*> GetTupleGetMethods(const AZ::TypeId& typeId);
AZ::Outcome<const AZ::BehaviorMethod*, void> GetTupleGetMethod(const AZ::TypeId& typeID, size_t index);
template<typename t_Call, typename t_Slots>
BehaviorContextMethodHelper::CallResult BehaviorContextMethodHelper::CallGeneric(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, t_Call attempt, t_Slots& slots)
{
const auto numExpectedArgs(static_cast<unsigned int>(method->GetNumArguments()));
if ((paramEnd - paramBegin) == numExpectedArgs)
{
AZ::Outcome<CallResult, AZStd::string> withResultsOutcome = attempt(node, method, paramBegin, numExpectedArgs, slots);
if (!withResultsOutcome.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((node), "Script Canvas attempt to call %s with a result failed: %s", method->m_name.data(), withResultsOutcome.GetError().data());
return CallResult(MethodCallStatus::Failed);
}
else if (withResultsOutcome.GetValue().m_status == MethodCallStatus::Attempted)
{
return CallResult(MethodCallStatus::Succeeded, withResultsOutcome.GetValue().m_executionOutOverride);
}
else if (method->Call(paramBegin, numExpectedArgs))
{
return CallResult(MethodCallStatus::Succeeded);
}
else
{
SCRIPTCANVAS_REPORT_ERROR((node), "Script Canvas attempt to call %s failed", method->m_name.data());
return CallResult(MethodCallStatus::Failed);
}
}
else
{
SCRIPTCANVAS_REPORT_ERROR((node), "Script Canvas attempt to call %s failed, it expects %d args but called with %d", method->m_name.c_str(), numExpectedArgs, paramEnd - paramBegin);
return CallResult(MethodCallStatus::NotAttempted);
}
}
template<typename ... Args>
AZ::Outcome<Datum, AZStd::string> BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(const Datum& input, AZStd::string_view methodName, Args&& ... args)
{
AZ::Outcome<Datum, AZStd::string> methodCallResult = CallMethodOnDatum(input, methodName, args...);
if (methodCallResult.IsSuccess())
{
// Even when successfully called, the method will return an outcome as the result, we need to test that
// outcome in case any errors were returned from the invoked function call.
const Datum& methodCallResultDatum = methodCallResult.GetValue();
const auto* actualOutcome = methodCallResultDatum.GetAs<AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string>>();
if (actualOutcome && !actualOutcome->IsSuccess())
{
return AZ::Failure(AZStd::string::format("%s returned an error: %s", methodName.data(), actualOutcome->GetError().c_str()));
}
AZ::Outcome<Datum, AZStd::string> isSuccessCallResult = CallMethodOnDatum(methodCallResult.GetValue(), "IsSuccess");
if (isSuccessCallResult.IsSuccess())
{
if (*isSuccessCallResult.GetValue().GetAs<bool>())
{
return CallMethodOnDatum(methodCallResult.GetValue(), "GetValue");
}
else
{
return AZ::Failure(AZStd::string::format("%s returned an error", methodName.data()));
}
}
else
{
return AZ::Failure(AZStd::string::format("Script Canvas attempt to call %s failed, Failed to query result Outcome success", methodName.data()));
}
}
else
{
return AZ::Failure(methodCallResult.GetError());
}
return methodCallResult;
}
template<typename ... Args>
AZ::Outcome<Datum, AZStd::string> BehaviorContextMethodHelper::CallMethodOnDatum(const Datum& input, AZStd::string_view methodName, Args&& ... args)
{
const AZ::BehaviorClass* behaviorClass = AZ::BehaviorContextHelper::GetClass(input.GetType().GetAZType());
if (behaviorClass)
{
auto methodIt = behaviorClass->m_methods.find(methodName);
if (methodIt != behaviorClass->m_methods.end())
{
AZ::BehaviorMethod* method = methodIt->second;
const AZ::BehaviorParameter* resultType = method->HasResult() ? method->GetResult() : nullptr;
if (resultType)
{
// Populate parameters
AZStd::vector<AZ::BehaviorValueParameter> parameters = CreateParameterList(method, input, AZStd::forward<Args>(args)...);
return Datum::CallBehaviorContextMethodResult(method, resultType, parameters.begin(), (unsigned int)AZStd::GetMin(parameters.size(), method->GetNumArguments()), behaviorClass->m_name);
}
else
{
AZStd::vector<AZ::BehaviorValueParameter> parameters = CreateParameterList(method, input, AZStd::forward<Args>(args)...);
if (Datum::CallBehaviorContextMethod(method, parameters.begin(), (unsigned int)AZStd::GetMin(parameters.size(), method->GetNumArguments())).IsSuccess())
{
return AZ::Success(Datum());
}
}
}
else
{
return AZ::Failure(AZStd::string::format("ScriptCanvas Behavior Context method call failed; method named \"%s\" not found.", methodName.data()));
}
}
return AZ::Failure(AZStd::string::format("ScriptCanvas Behavior Context method call failed; unable to retrieve Behavior Class."));
}
template<typename ... Args>
AZStd::vector<AZ::BehaviorValueParameter> BehaviorContextMethodHelper::CreateParameterList(const AZ::BehaviorMethod* method, Args&&... args)
{
// Create an index sequence for the parameters and forward the arguments
return CreateParameterListInternal(method, AZStd::make_index_sequence<sizeof...(Args)>{}, AZStd::forward<Args>(args)...);
}
template <typename T>
AZ::BehaviorValueParameter BehaviorContextMethodHelper::ToBehaviorValueParameter(const AZ::BehaviorMethod*, size_t, const T& arg)
{
return AZ::BehaviorValueParameter(&arg);
}
template<typename ... Args, size_t ... Indices>
AZStd::vector<AZ::BehaviorValueParameter> BehaviorContextMethodHelper::CreateParameterListInternal(const AZ::BehaviorMethod* method, AZStd::index_sequence<Indices...>, Args&&... args)
{
// Unpack the arguments and the index sequence to populate the parameter list
return { ToBehaviorValueParameter(method, Indices, args)... };
}
}
@@ -12,8 +12,8 @@
#include <AzCore/Component/TickBus.h>
#include <AzCore/Asset/AssetManager.h>
#include <ScriptCanvas/Core/GraphBus.h>
#include <ScriptCanvas/Execution/ErrorBus.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.h>
#include <ScriptCanvas/Utils/VersionConverters.h>
@@ -75,7 +75,7 @@ namespace ScriptCanvas
AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, asset.GetId());
AZStd::string graphAssetName;
RuntimeRequestBus::EventResult(graphAssetName, GetOwningScriptCanvasId(), &RuntimeRequests::GetAssetName);
GraphRequestBus::EventResult(graphAssetName, GetOwningScriptCanvasId(), &GraphRequests::GetAssetName);
AZ_Error("Script Event", false, "The Script Event asset (%s) has been modified. Open the graph (%s) and re-save it.", assetInfo.m_relativePath.c_str(), graphAssetName.c_str());
return;
@@ -325,197 +325,16 @@ namespace ScriptCanvas
}
}
void ReceiveScriptEvent::OnEvent(const char* eventName, const int, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ReceiveScriptEvent::OnEvent %s", eventName);
SCRIPTCANVAS_RETURN_IF_ERROR_STATE((*this));
ScriptEvents::Method method;
if (!GetScriptEvent().FindMethod(eventName, method))
{
AZ_Warning("Script Events", false, "Failed to find method: %s when trying to handle it.", eventName);
return;
}
auto iter = m_eventMap.find(AZ::Crc32(method.GetNameProperty().GetId().ToString<AZStd::string>().c_str()));
if (iter == m_eventMap.end())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Invalid event index in Ebus handler");
return;
}
Internal::ScriptEventEntry& scriptEventEntry = iter->second;
if (!scriptEventEntry.m_shouldHandleEvent || scriptEventEntry.m_isHandlingEvent)
{
AZ_Warning("ScriptCanvas", !scriptEventEntry.m_isHandlingEvent, "Found situation where in handling event(%s::%s) triggered the same event. Possible infinite loop, not handling second call.", GetScriptEvent().GetName().c_str(), eventName);
return;
}
scriptEventEntry.m_isHandlingEvent = true;
scriptEventEntry.m_resultEvaluated = !scriptEventEntry.IsExpectingResult();
// route the parameters to the connect nodes input
if (scriptEventEntry.m_parameterSlotIds.size() != numParameters)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "The Script Event, %s, has %d parameters. While the ScriptCanvas Node (%s) has (%zu) slots. Make sure the node is updated in the Script Canvas graph.", eventName, numParameters, GetNodeName().c_str(), scriptEventEntry.m_parameterSlotIds.size());
}
else
{
for (int parameterIndex(0); parameterIndex < numParameters; ++parameterIndex)
{
const Slot* slot = GetSlot(scriptEventEntry.m_parameterSlotIds[parameterIndex]);
const auto& value = *(parameters + parameterIndex);
const Datum input(value);
if (slot->IsTypeMatchFor(input.GetType()))
{
PushOutput(input, *slot);
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Type mismatch in Script Event %s on ScriptCanvas Node (%s). Make sure the nodes is updated in the Script Canvas graph", eventName, GetNodeName().c_str());
}
}
}
{
// now, this should pass execution off to the nodes that will push their output into this result input
SignalOutput(scriptEventEntry.m_eventSlotId, ExecuteMode::UntilNodeIsFoundInStack);
}
// route executed nodes output to my input, and my input to the result
if (scriptEventEntry.IsExpectingResult())
{
if (result)
{
if (const Datum* resultInput = FindDatum(scriptEventEntry.m_resultSlotId))
{
scriptEventEntry.m_resultEvaluated = resultInput->ToBehaviorContext(*result);
AZ_Warning("Script Canvas", scriptEventEntry.m_resultEvaluated, "%s expects a result value of type %s to be provided, got %s", scriptEventEntry.m_eventName.c_str(), Data::GetName(resultInput->GetType()).c_str(), result->m_name);
}
else
{
AZ_Warning("Script Canvas", false, "Script Canvas handler expecting a result, but had no ability to return it");
}
}
else
{
AZ_Warning("Script Canvas", false, "Script Canvas handler is expecting a result, but was called without receiving one!");
}
}
else
{
AZ_Warning("Script Canvas", !result, "Script Canvas handler is not expecting a result, but was called receiving one!");
}
// route executed nodes output to my input, and my input to the result
AZ_Warning("Script Canvas", (result != nullptr) == scriptEventEntry.IsExpectingResult(), "Node %s-%s mismatch between expecting a result and getting one!", m_ebus->m_name.c_str(), scriptEventEntry.m_eventName.c_str());
AZ_Warning("Script Canvas", scriptEventEntry.m_resultEvaluated, "Node %s-%s result not evaluated properly!", m_ebus->m_name.c_str(), scriptEventEntry.m_eventName.c_str());
scriptEventEntry.m_isHandlingEvent = false;
}
void ReceiveScriptEvent::OnActivate()
{
SetAutoConnectToGraphOwner(m_autoConnectToGraphOwner);
ScriptEventBase::OnActivate();
}
void ReceiveScriptEvent::OnPostActivate()
{
}
void ReceiveScriptEvent::OnDeactivate()
{
Disconnect(false);
ScriptEventBase::OnDeactivate();
}
void ReceiveScriptEvent::Connect()
{
AZ::EntityId connectToEntityId;
AZ::BehaviorValueParameter busIdParameter;
busIdParameter.Set(m_ebus->m_idParam);
const AZ::Uuid busIdType = m_ebus->m_idParam.m_typeId;
const Datum* busIdDatum = IsIDRequired() ? FindDatum(GetSlotId(c_busIdName)) : nullptr;
if (busIdDatum && !busIdDatum->Empty())
{
if (busIdDatum->IS_A(Data::FromAZType(busIdType)) || busIdDatum->IsConvertibleTo(Data::FromAZType(busIdType)))
{
auto busIdOutcome = busIdDatum->ToBehaviorValueParameter(m_ebus->m_idParam);
if (busIdOutcome.IsSuccess())
{
busIdParameter = busIdOutcome.TakeValue();
}
}
if (busIdType == azrtti_typeid<AZ::EntityId>())
{
if (auto busEntityId = busIdDatum->GetAs<AZ::EntityId>())
{
if (!busEntityId->IsValid() || *busEntityId == ScriptCanvas::GraphOwnerId)
{
RuntimeRequestBus::EventResult(connectToEntityId, GetOwningScriptCanvasId(), &RuntimeRequests::GetRuntimeEntityId);
busIdParameter.m_value = &connectToEntityId;
}
}
}
}
if (!IsIDRequired() || busIdParameter.GetValueAddress())
{
if (m_connected)
{
// Ensure we disconnect if this bus is already connected, this could happen if a different bus Id is provided
// and this node is connected through the Connect slot.
m_handler->Disconnect();
}
AZ_VerifyError("Script Canvas", m_handler->Connect(&busIdParameter),
"Unable to connect to EBus with BusIdType %s. The BusIdType of the Script Event (%s) does not match the BusIdType provided.",
busIdType.ToString<AZStd::string>().data(), m_definition.GetName().c_str());
m_connected = true;
}
}
void ReceiveScriptEvent::CompleteDisconnection()
{
m_handler->Disconnect();
m_connected = false;
if (IsActivated())
{
SlotId onDisconnectSlotId = ReceiveScriptEventProperty::GetOnDisconnectedSlotId(this);
SignalOutput(onDisconnectSlotId);
}
}
void ReceiveScriptEvent::Disconnect(bool queueDisconnect)
{
if (m_connected && m_handler)
{
if (queueDisconnect)
{
AZ::SystemTickBus::QueueFunction(
[this]()
{
CompleteDisconnection();
}
);
}
else
{
CompleteDisconnection();
}
}
}
}
const Internal::ScriptEventEntry* ReceiveScriptEvent::FindEventWithSlot(const Slot& slot) const
{
@@ -771,51 +590,6 @@ namespace ScriptCanvas
return true;
}
void ReceiveScriptEvent::OnInputSignal(const SlotId& slotId)
{
SlotId connectSlot = ReceiveScriptEventProperty::GetConnectSlotId(this);
if (connectSlot == slotId)
{
const Datum* busIdDatum = FindDatum(GetSlotId(c_busIdName));
if (IsIDRequired() && (!busIdDatum || busIdDatum->Empty()))
{
SlotId failureSlot = ReceiveScriptEventProperty::GetOnFailureSlotId(this);
SignalOutput(failureSlot);
SCRIPTCANVAS_REPORT_ERROR((*this), "In order to connect this node, a valid BusId must be provided.");
return;
}
else
{
Connect();
SlotId onConnectSlotId = ReceiveScriptEventProperty::GetOnConnectedSlotId(this);
SignalOutput(onConnectSlotId);
return;
}
}
SlotId disconnectSlot = ReceiveScriptEventProperty::GetDisconnectSlotId(this);
if (disconnectSlot == slotId)
{
Disconnect();
return;
}
}
void ReceiveScriptEvent::OnInputChanged(const Datum&, const SlotId&)
{
/*
if (GetExecutionType() == ExecutionType::Runtime
&& m_autoConnectToGraphOwner
&& slotId == FindSlotIdForDescriptor(c_busIdName, SlotDescriptors::DataIn()))
{
Disconnect(false);
Connect();
}
*/
}
bool ReceiveScriptEvent::IsOutOfDate(const VersionData& graphVersion) const
{
AZ_UNUSED(graphVersion);
@@ -87,16 +87,9 @@ namespace ScriptCanvas
private:
void Connect();
void Disconnect(bool queueDisconnect = true);
void CompleteDisconnection();
bool CreateEbus();
bool SetupHandler();
void OnInputSignal(const SlotId& slotId) override;
void OnInputChanged(const Datum& input, const SlotId& slotId) override;
AZ::BehaviorEBusHandler* m_handler = nullptr;
AZ::BehaviorEBus* m_ebus = nullptr;
AZStd::recursive_mutex m_mutex; // post-serialization
@@ -105,9 +98,6 @@ namespace ScriptCanvas
void InitializeEvent(AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> asset, int eventIndex, SlotIdMapping& populationMapping);
static void OnEventGenericHook(void* userData, const char* eventName, int eventIndex, AZ::BehaviorValueParameter* result, int numParameters, AZ::BehaviorValueParameter* parameters);
void OnEvent(const char* eventName, const int eventIndex, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters);
bool IsEventConnected(const Internal::ScriptEventEntry& entry) const;
Internal::ScriptEventEntry ConfigureEbusEntry(const ScriptEvents::Method& methodDefinition, const AZ::BehaviorEBusHandler::BusForwarderEvent& event, SlotIdMapping& populationMapping);
@@ -74,28 +74,6 @@ namespace ScriptCanvas
}
}
}
void Repeater::OnInputSignal(const SlotId&)
{
m_repetionCount = aznumeric_cast<int>(RepeaterProperty::GetRepetitions(this));
if (m_repetionCount > 0)
{
StartTimer();
}
}
void Repeater::OnTimeElapsed()
{
m_repetionCount--;
SignalOutput(RepeaterProperty::GetActionSlotId(this), ScriptCanvas::ExecuteMode::UntilNodeIsFoundInStack);
if (m_repetionCount == 0)
{
StopTimer();
SignalOutput(RepeaterProperty::GetCompleteSlotId(this));
}
}
}
}
}
@@ -17,6 +17,7 @@ namespace ScriptCanvas
namespace Core
{
//! A node that repeats an execution signal over the specified time
//! Deprecated for nodeable version
class Repeater
: public ScriptCanvas::Nodes::Internal::BaseTimerNode
{
@@ -27,18 +28,11 @@ namespace ScriptCanvas
void OnInit() override;
void OnInputSignal(const SlotId& slotId) override;
void OnTimeElapsed();
const char* GetTimeSlotFormat() const override { return "Delay (%s)"; }
const char* GetBaseTimeSlotName() const override { return "Interval"; }
const char* GetBaseTimeSlotToolTip() const override { return "The Interval between repetitions"; }
protected:
bool AllowInstantResponse() const override { return true; }
int m_repetionCount;
};
}
@@ -10,8 +10,6 @@
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/Utils.h>
#include <AzCore/Component/TickBus.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <AzCore/Asset/AssetManager.h>
#include <ScriptEvents/ScriptEventsAsset.h>
@@ -106,9 +106,7 @@ namespace ScriptCanvas
AZStd::pair<AZ::Data::Asset<ScriptEvents::ScriptEventsAsset>, bool> IsAssetOutOfDate() const;
virtual void Initialize(const AZ::Data::AssetId assetId);
virtual void Initialize(const AZ::Data::AssetId assetId);
protected:
@@ -28,64 +28,6 @@ namespace ScriptCanvas
ScriptEvents::ScriptEventNotificationBus::Handler::BusDisconnect();
}
void SendScriptEvent::OnInputSignal(const SlotId&)
{
if (!m_method)
{
if (!m_asset.IsReady())
{
m_asset = AZ::Data::AssetManager::Instance().GetAsset<ScriptEvents::ScriptEventsAsset>(m_scriptEventAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
}
CreateSender(m_asset);
}
if (!m_method)
{
AZStd::string error = AZStd::string::format("Script Event sender node called with no initialized method (%s::%s)!", m_busName.c_str(), m_eventName.c_str());
SCRIPTCANVAS_REPORT_ERROR((*this), error.c_str());
}
if (m_method)
{
Node::DatumVector inputDatums = GatherDatumsForDescriptor(SlotDescriptors::DataIn());
if (m_method->GetNumArguments() != inputDatums.size())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "The Script Event %s number of parameters %d do not correspond to the number of slots %zu in the Script Canvas node (%s). Make sure the node is updated in the Script Canvas graph.", m_method->m_name.c_str(), m_method->GetNumArguments(), inputDatums.size(), GetNodeName().c_str());
return;
}
AZStd::array<AZ::BehaviorValueParameter, BehaviorContextMethodHelper::MaxCount> params;
AZ::BehaviorValueParameter* paramFirst(params.begin());
AZ::BehaviorValueParameter* paramIter = paramFirst;
{
// all input should have been pushed into this node already
int argIndex(0);
for (const Datum* datum : inputDatums)
{
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> inputParameter = datum->ToBehaviorValueParameter(*m_method->GetArgument(argIndex));
if (!inputParameter.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "BehaviorContext method input problem at parameter index %d: %s", argIndex, inputParameter.GetError().data());
return;
}
paramIter->Set(inputParameter.GetValue());
++paramIter;
++argIndex;
}
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::ScriptEvents::OnInputSignal::Call %s::%s", m_busName.c_str(), m_eventName.c_str());
{
BehaviorContextMethodHelper::Call(*this, m_method, paramFirst, paramIter, m_resultSlotID);
}
}
}
SignalOutput(GetSlotId("Out"));
}
ScriptCanvas::EBusBusId SendScriptEvent::GetBusId() const
{
return m_busId;
@@ -155,11 +97,6 @@ namespace ScriptCanvas
AZ::Outcome<void, AZStd::string> IsExposable(const AZ::BehaviorMethod& method)
{
if (method.GetNumArguments() > BehaviorContextMethodHelper::MaxCount)
{
return AZ::Failure(AZStd::string("Too many arguments for a Script Canvas method"));
}
for (size_t argIndex(0), sentinel(method.GetNumArguments()); argIndex != sentinel; ++argIndex)
{
if (const AZ::BehaviorParameter* argument = method.GetArgument(argIndex))
@@ -79,11 +79,7 @@ namespace ScriptCanvas
bool IsConfigured() const { return m_method != nullptr; }
void ConfigureMethod(AZ::BehaviorMethod& method);
bool RegisterScriptEvent(AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> asset);
void OnInputSignal(const SlotId&) override;
void AddInputSlot(size_t slotIndex, size_t argIndex, const AZStd::string_view argName, const AZStd::string_view tooltip, AZ::BehaviorMethod* method, const AZ::BehaviorParameter* argument, AZ::Uuid slotKey, SlotIdMapping& populationMapping);
void OnRegistered(const ScriptEvents::ScriptEvent&) override;
SlotId m_resultSlotID;
@@ -59,47 +59,6 @@ namespace ScriptCanvas
}
}
void SetVariableNode::OnInputSignal(const SlotId& slotID)
{
if (slotID == GetSlotId(GetInputSlotName()))
{
const Datum* sourceDatum = FindDatum(m_variableDataInSlotId);
if (sourceDatum && m_variableView.IsValid())
{
m_variableView.AssignToDatum((*sourceDatum));
SC_EXECUTION_TRACE_VARIABLE_CHANGE((m_variableId), (CreateVariableChange((*m_variableView.GetDatum()), m_variableId)));
}
Slot* resultSlot = GetSlot(m_variableDataOutSlotId);
if (resultSlot && m_variableView.IsValid())
{
const Datum* variableDatum = m_variableView.GetDatum();
PushOutput((*variableDatum), *resultSlot);
// Push the data for each property slot out as well
for (auto&& propertyAccount : m_propertyAccounts)
{
Slot* propertySlot = GetSlot(propertyAccount.m_propertySlotId);
if (propertySlot && propertyAccount.m_getterFunction)
{
auto outputOutcome = propertyAccount.m_getterFunction((*variableDatum));
if (!outputOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), outputOutcome.TakeError().data());
return;
}
PushOutput(outputOutcome.TakeValue(), *propertySlot);
}
}
}
SignalOutput(GetSlotId(GetOutputSlotName()));
}
}
VariableId SetVariableNode::GetVariableIdRead(const Slot*) const
{
return m_variableId;
@@ -283,7 +242,8 @@ namespace ScriptCanvas
ScriptCanvas::Data::Type baseType = ScriptCanvas::Data::Type::Invalid();
VariableRequestBus::EventResult(baseType, GetScopedVariableId(), &VariableRequests::GetType);
const AZStd::unordered_map<VariableId, GraphVariable>* variableMap = GetRuntimeBus()->GetVariables();
const GraphVariableMapping* variableMap = nullptr;
GraphRequestBus::EventResult(variableMap, *GraphNotificationBus::GetCurrentBusId(), &GraphRequests::GetVariables);
if (variableMap && baseType.IsValid())
{
@@ -319,12 +279,6 @@ namespace ScriptCanvas
VariableNodeNotificationBus::Event(GetEntityId(), &VariableNodeNotifications::OnVariableRemovedFromNode, removedVariableId);
}
AnnotateNodeSignal SetVariableNode::CreateAnnotationData()
{
AZ::EntityId assetNodeId = GetRuntimeBus()->FindAssetNodeIdByRuntimeNodeId(GetEntityId());
return AnnotateNodeSignal(CreateGraphInfo(GetOwningScriptCanvasId(), GetGraphIdentifier()), AnnotateNodeSignal::AnnotationLevel::Info, m_variableName, AZ::NamedEntityId(assetNodeId, GetNodeName()));
}
void SetVariableNode::AddPropertySlots(const Data::Type& type)
{
Data::GetterContainer getterFunctions = Data::ExplodeToGetters(type);
@@ -67,8 +67,7 @@ namespace ScriptCanvas
void OnInit() override;
void OnPostActivate() override;
void OnInputSignal(const SlotId&) override;
void AddSlots();
void RemoveSlots();
void AddPropertySlots(const Data::Type& type);
@@ -86,8 +85,6 @@ namespace ScriptCanvas
void OnVariableRemoved() override;
////
AnnotateNodeSignal CreateAnnotationData();
VariableId m_variableId;
SlotId m_variableDataInSlotId;
@@ -1,25 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Start.h"
#include <ScriptCanvas/Core/GraphBus.h>
#include <ScriptCanvas/Grammar/Primitives.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
void Start::OnInputSignal(const SlotId&)
{
SignalOutput(StartProperty::GetOutSlotId(this));
}
}
}
}
@@ -25,11 +25,6 @@ namespace ScriptCanvas
public:
SCRIPTCANVAS_NODE(Start);
void OnInputSignal(const SlotId&) override;
};
}
}
@@ -52,11 +52,6 @@ namespace ScriptCanvas
//////////////////////////////////////////////////////////////////////////
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<bool>() && *rhs.GetAs<bool>());
}
void InitializeBooleanExpression() override
{
{
@@ -60,12 +60,6 @@ namespace ScriptCanvas
RegisterExtension(visualExtensions);
}
}
void Any::OnInputSignal([[maybe_unused]] const SlotId& slotId)
{
const SlotId outSlotId = AnyProperty::GetOutSlotId(this);
SignalOutput(outSlotId);
}
SlotId Any::HandleExtension(AZ::Crc32 extensionId)
{
@@ -44,8 +44,6 @@ namespace ScriptCanvas
void OnInit() override;
void ConfigureVisualExtensions() override;
void OnInputSignal(const SlotId& slot) override;
SlotId HandleExtension(AZ::Crc32 extensionId) override;
bool CanDeleteSlot(const SlotId& slotId) const override;
@@ -54,9 +52,7 @@ namespace ScriptCanvas
////
/// Translation
bool IsNoOp() const override;
bool IsNoOp() const override;
AZ::Outcome<DependencyReport, void> GetDependencies() const override;
@@ -69,9 +65,7 @@ namespace ScriptCanvas
AZ::Crc32 GetInputExtensionId() const { return AZ_CRC("Output", 0xccde149e); }
private:
AZStd::string GenerateInputName(int counter);
SlotId AddInputSlot();
void FixupStateNames();
};
@@ -98,26 +98,6 @@ namespace ScriptCanvas
return AddSlot(executionConfiguration);
}
void Cycle::OnInputSignal(const SlotId& slot)
{
if (slot != CycleProperty::GetInSlotId(this))
{
return;
}
if (!m_orderedOutputSlots.empty())
{
const SlotId& slotId = m_orderedOutputSlots[m_executionSlot];
SignalOutput(slotId);
if (++m_executionSlot >= m_orderedOutputSlots.size())
{
m_executionSlot = 0;
}
}
}
void Cycle::OnSlotRemoved([[maybe_unused]] const SlotId& slotId)
{
FixupStateNames();
@@ -43,13 +43,9 @@ namespace ScriptCanvas
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& executionSlot, CombinedSlotType targetSlotType, const Slot* /*executionChildSlot*/) const override;
protected:
AZStd::string GetDisplayGroup() const { return "OutputGroup"; }
void OnInputSignal(const SlotId& slot) override;
void OnSlotRemoved(const SlotId& slotId) override;
private:
@@ -1,37 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Indexer.h"
namespace ScriptCanvas
{
namespace Nodes
{
namespace Logic
{
void Indexer::OnInputSignal(const SlotId& slotId)
{
auto slotIndex = FindSlotIndex(slotId);
if (slotIndex < 0)
{
AZ_Warning("Script Canvas", false, "Could not find slot with id %s", slotId.ToString().c_str());
return;
}
const Datum output(slotIndex);
const SlotId outSlotId = IndexerProperty::GetOutSlotId(this);
if (auto outSlot = GetSlot(outSlotId))
{
PushOutput(output, *outSlot);
}
SignalOutput(outSlotId);
}
}
}
}
@@ -21,16 +21,8 @@ namespace ScriptCanvas
class Indexer
: public Node
{
public:
SCRIPTCANVAS_NODE(Indexer);
Indexer() = default;
protected:
void OnInputSignal(const SlotId& slot) override;
};
}
}
@@ -61,13 +61,6 @@ namespace ScriptCanvas
AddSlot(slotConfiguration);
}
}
void IsNull::OnInputSignal(const SlotId&)
{
const bool isNull = FindDatum(GetSlotId("Reference"))->Empty();
PushOutput(Datum(isNull), *GetSlot(GetSlotId("Is Null")));
SignalOutput(isNull ? IsNullProperty::GetTrueSlotId(this) : IsNullProperty::GetFalseSlotId(this));
}
}
}
}
@@ -34,8 +34,6 @@ namespace ScriptCanvas
bool IsIfBranchPrefacedWithBooleanExpression() const override;
protected:
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot&, CombinedSlotType targetSlotType, const Slot*) const override
{
@@ -43,9 +41,6 @@ namespace ScriptCanvas
}
void OnInit() override;
void OnInputSignal(const SlotId&) override;
};
}
}
@@ -1,42 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Multiplexer.h"
namespace ScriptCanvas
{
namespace Nodes
{
namespace Logic
{
Multiplexer::Multiplexer()
{}
void Multiplexer::OnInputSignal(const SlotId& slotId)
{
auto slotIndex = FindSlotIndex(slotId);
if (!slotIndex)
{
AZ_Warning("Script Canvas", false, "Could not find slot with Id %s", slotId.ToString().c_str());
return;
}
// These are generated from CodeGen, they essentially
// check if there's anything connected on the slot and
// they assign the local member with the value, otherwise
// they use the default property value.
const AZ::s64 selectedIndex = MultiplexerProperty::GetIndex(this);
if (selectedIndex == slotIndex)
{
const SlotId outSlotId = MultiplexerProperty::GetOutSlotId(this);
SignalOutput(outSlotId);
}
}
}
}
}
@@ -26,12 +26,6 @@ namespace ScriptCanvas
SCRIPTCANVAS_NODE(Multiplexer);
Multiplexer();
protected:
void OnInputSignal(const SlotId& slot) override;
};
}
}
@@ -50,11 +50,6 @@ namespace ScriptCanvas
//////////////////////////////////////////////////////////////////////////
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<bool>() || *rhs.GetAs<bool>());
}
void InitializeBooleanExpression() override
{
{
@@ -107,50 +107,6 @@ namespace ScriptCanvas
}
}
void Sequencer::OnInputSignal(const SlotId& slot)
{
m_selectedIndex = SequencerProperty::GetIndex(this);
m_order = SequencerProperty::GetOrder(this);
const SlotId inSlot = SequencerProperty::GetInSlotId(this);
const SlotId nextSlot = SequencerProperty::GetNextSlotId(this);
if (slot == inSlot)
{
m_currentIndex = m_selectedIndex;
}
else if (slot == nextSlot)
{
int step = m_order == Order::Forward ? 1 : -1;
m_outputIsValid = false;
int startIndex = m_currentIndex;
while (!m_outputIsValid)
{
m_currentIndex = (m_currentIndex + step + NUMBER_OF_OUTPUTS) % NUMBER_OF_OUTPUTS;
SlotId outSlotId = GetCurrentSlotId();
Slot* outSlot = GetSlot(outSlotId);
if (outSlot)
{
m_outputIsValid = !GetConnectedNodes(*outSlot).empty();
}
//Avoid infinite loop when none of the outputs or only the current output connects to other nodes.
if (m_currentIndex == startIndex)
{
m_outputIsValid = false;
break;
}
}
}
if (m_outputIsValid)
{
SlotId outSlotId = GetCurrentSlotId();
SignalOutput(outSlotId);
}
}
SlotId Sequencer::GetCurrentSlotId() const
{
AZStd::string slotName = "Out" + AZStd::to_string(m_currentIndex);
@@ -43,10 +43,6 @@ namespace ScriptCanvas
int m_order;
int m_selectedIndex;
protected:
void OnInputSignal(const SlotId& slot) override;
private:
int m_currentIndex;
bool m_outputIsValid;
@@ -71,31 +71,6 @@ namespace ScriptCanvas
return AddSlot(executionConfiguration);
}
void TargetedSequencer::OnInputSignal(const SlotId& slot)
{
if (slot != TargetedSequencerProperty::GetInSlotId(this))
{
return;
}
int targetIndex = TargetedSequencerProperty::GetIndex(this);
if (targetIndex < 0
|| targetIndex >= m_numOutputs)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Switch node was given an out of bound index.");
return;
}
AZStd::string slotName = GenerateOutputName(targetIndex);
SlotId outSlotId = GetSlotId(slotName.c_str());
if (outSlotId.IsValid())
{
SignalOutput(outSlotId);
}
}
void TargetedSequencer::OnSlotRemoved([[maybe_unused]] const SlotId& slotId)
{
FixupStateNames();
@@ -54,7 +54,6 @@ namespace ScriptCanvas
AZStd::string GetDisplayGroup() const { return "OutputGroup"; }
void OnInputSignal(const SlotId& slot) override;
void OnSlotRemoved(const SlotId& slotId) override;
private:
@@ -131,63 +131,6 @@ namespace ScriptCanvas
return isValid;
}
void WeightedRandomSequencer::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = WeightedRandomSequencerProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
int runningTotal = 0;
AZStd::vector< WeightedStruct > weightedStructs;
weightedStructs.reserve(m_weightedPairings.size());
for (const WeightedPairing& weightedPairing : m_weightedPairings)
{
const Datum* datum = FindDatum(weightedPairing.m_weightSlotId);
if (datum)
{
WeightedStruct weightedStruct;
weightedStruct.m_executionSlotId = weightedPairing.m_executionSlotId;
if (datum->GetType().IS_A(ScriptCanvas::Data::Type::Number()))
{
int weight = aznumeric_cast<int>((*datum->GetAs<Data::NumberType>()));
runningTotal += weight;
weightedStruct.m_totalWeight = runningTotal;
}
weightedStructs.emplace_back(weightedStruct);
}
}
// We have no weights. So just trigger the first execution output
// Weighted pairings is controlled to never be empty.
if (runningTotal == 0)
{
if (!m_weightedPairings.empty())
{
SignalOutput(m_weightedPairings.front().m_executionSlotId);
}
return;
}
int weightedResult = MathNodeUtilities::GetRandomIntegral<int>(1, runningTotal);
for (const WeightedStruct& weightedStruct : weightedStructs)
{
if (weightedResult <= weightedStruct.m_totalWeight)
{
SignalOutput(weightedStruct.m_executionSlotId);
break;
}
}
}
}
SlotId WeightedRandomSequencer::HandleExtension(AZ::Crc32 extensionId)
{
auto weightedPairing = AddWeightedPair();
@@ -22,9 +22,7 @@ namespace ScriptCanvas
class WeightedRandomSequencer
: public Node
{
public:
SCRIPTCANVAS_NODE(WeightedRandomSequencer);
static void ReflectDataTypes(AZ::ReflectContext* reflectContext);
@@ -42,11 +40,7 @@ namespace ScriptCanvas
bool OnValidateNode(ValidationResults& validationResults);
void OnInputSignal(const SlotId& slot);
SlotId HandleExtension(AZ::Crc32 extensionId) override;
SlotId HandleExtension(AZ::Crc32 extensionId) override;
bool CanDeleteSlot(const SlotId& slotId) const override;
@@ -51,21 +51,6 @@ namespace ScriptCanvas
nodeConfig.m_type = AZ::Uuid("DC17E19F-3829-410D-9A0B-AD60C6066DAA");
return nodeConfig;
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
const Data::NumberType lhsValue = *lhs.GetAs<Data::NumberType>();
const Data::NumberType rhsValue = *rhs.GetAs<Data::NumberType>();
if (AZ::IsClose(rhsValue, 0.0, 0.0001))
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Divide by zero");
return Datum();
}
return Datum(lhsValue / rhsValue);
}
};
}
@@ -50,12 +50,6 @@ namespace ScriptCanvas
nodeConfig.m_type = AZ::Uuid("E9BB45A1-AE96-47B0-B2BF-2927D420A28C");
return nodeConfig;
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<Data::NumberType>() * *rhs.GetAs<Data::NumberType>());
}
};
}
@@ -50,12 +50,6 @@ namespace ScriptCanvas
nodeConfig.m_type = AZ::Uuid("D0615D0A-027F-47F6-A02B-E35DAF22F431");
return nodeConfig;
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<Data::NumberType>() - *rhs.GetAs<Data::NumberType>());
}
};
}
@@ -52,12 +52,6 @@ namespace ScriptCanvas
nodeConfig.m_type = AZ::Uuid("C1B42FEC-0545-4511-9FAC-11E0387FEDF0");
return nodeConfig;
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<Data::NumberType>() + *rhs.GetAs<Data::NumberType>());
}
};
}
}
@@ -91,70 +91,6 @@ namespace ScriptCanvas
}
}
}
void OperatorAt::KeyNotFound(const Datum* containerDatum)
{
Datum defaultDatum;
AZStd::vector<AZ::Uuid> types = ScriptCanvas::Data::GetContainedTypes(GetSourceAZType());
int index = Data::IsMapContainerType(containerDatum->GetType()) ? 1 : 0;
Data::Type type = Data::FromAZType(types[index]);
defaultDatum.SetType(type);
PushOutput(defaultDatum, *GetSlot(*m_outputSlots.begin()));
SignalOutput(GetSlotId("Key Not Found"));
}
void OperatorAt::InvokeOperator()
{
Slot* inputSlot = GetFirstInputSourceSlot();
if (inputSlot)
{
SlotId sourceSlotId = inputSlot->GetId();
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
const Datum* inputKeyDatum = FindDatum(*m_inputSlots.begin());
AZ::Outcome<Datum, AZStd::string> valueOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(*containerDatum, "At", *inputKeyDatum);
if (!valueOutcome.IsSuccess())
{
KeyNotFound(containerDatum);
return;
}
if (Data::IsVectorContainerType(containerDatum->GetType()))
{
PushOutput(valueOutcome.TakeValue(), *GetSlot(*m_outputSlots.begin()));
SignalOutput(GetSlotId("Out"));
}
else if (Data::IsSetContainerType(containerDatum->GetType()) || Data::IsMapContainerType(containerDatum->GetType()))
{
Datum keyDatum = valueOutcome.TakeValue();
if (keyDatum.Empty())
{
KeyNotFound(containerDatum);
}
else
{
PushOutput(keyDatum, *GetSlot(*m_outputSlots.begin()));
SignalOutput(GetSlotId("Out"));
}
}
}
}
}
void OperatorAt::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -36,9 +36,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
void KeyNotFound(const Datum* containerDatum);
};
}
@@ -48,43 +48,6 @@ namespace ScriptCanvas
}
}
void OperatorBack::InvokeOperator()
{
const SlotSet& slotSets = GetSourceSlots();
if (!slotSets.empty())
{
SlotId sourceSlotId = (*slotSets.begin());
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
const Datum* inputKeyDatum = FindDatum(*m_inputSlots.begin());
AZ::Outcome<Datum, AZStd::string> valueOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(*containerDatum, "Back", *inputKeyDatum);
if (!valueOutcome.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to call Back on container: %s", valueOutcome.GetError().c_str());
return;
}
if (Data::IsVectorContainerType(containerDatum->GetType()))
{
PushOutput(valueOutcome.TakeValue(), *GetSlot(*m_outputSlots.begin()));
}
}
}
SignalOutput(GetSlotId("Out"));
}
void OperatorBack::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -35,7 +35,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
};
@@ -67,36 +67,6 @@ namespace ScriptCanvas
}
////
}
void OperatorClear::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId != inSlotId)
{
return;
}
SlotId sourceSlotId = OperatorClearProperty::GetSourceSlotId(this);
if (const Datum* containerDatum = FindDatum(sourceSlotId))
{
if (Datum::IsValidDatum(containerDatum))
{
AZ::Outcome<Datum, AZStd::string> clearOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(*containerDatum, "Clear");
if (!clearOutcome.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to call Clear on container: %s", clearOutcome.GetError().c_str());
return;
}
// Push the source container as an output to support chaining
PushOutput(*containerDatum, *OperatorClearProperty::GetContainerSlot(this));
}
}
SignalOutput(GetSlotId("Out"));
}
}
}
}
@@ -41,10 +41,6 @@ namespace ScriptCanvas
OperatorClear() = default;
void OnInit() override;
protected:
void OnInputSignal(const SlotId& slotId) override;
};
}
@@ -70,49 +70,6 @@ namespace ScriptCanvas
}
////
}
void OperatorEmpty::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorEmptyProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
SlotId sourceSlotId = OperatorEmptyProperty::GetSourceSlotId(this);
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
// Is the container empty?
auto emptyOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(*containerDatum, "Empty");
if (!emptyOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to call Empty on container: %s", emptyOutcome.GetError().c_str());
return;
}
Datum emptyResult = emptyOutcome.TakeValue();
bool isEmpty = *emptyResult.GetAs<bool>();
PushOutput(Datum(isEmpty), *GetSlot(OperatorEmptyProperty::GetIsEmptySlotId(this)));
if (isEmpty)
{
SignalOutput(OperatorEmptyProperty::GetTrueSlotId(this));
}
else
{
SignalOutput(OperatorEmptyProperty::GetFalseSlotId(this));
}
}
else
{
PushOutput(Datum(true), *GetSlot(OperatorEmptyProperty::GetIsEmptySlotId(this)));
SignalOutput(OperatorEmptyProperty::GetFalseSlotId(this));
}
SignalOutput(OperatorEmptyProperty::GetOutSlotId(this));
}
}
}
}
}
@@ -21,22 +21,15 @@ namespace ScriptCanvas
class OperatorEmpty : public Node
{
public:
SCRIPTCANVAS_NODE(OperatorEmpty);
void CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map<SlotId, AZStd::vector<SlotId>>& outSlotIdMap) const override;
static bool OperatorEmptyVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
OperatorEmpty() = default;
// Node...
void OnInit() override;
////
void OnInputSignal(const SlotId& slotId) override;
};
}
}
@@ -95,47 +95,6 @@ namespace ScriptCanvas
}
}
void OperatorErase::InvokeOperator()
{
Slot* inputSlot = GetFirstInputSourceSlot();
Slot* outputSlot = GetFirstOutputSourceSlot();
if (inputSlot && outputSlot)
{
SlotId sourceSlotId = inputSlot->GetId();
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
const Datum* inputKeyDatum = FindDatum(*m_inputSlots.begin());
AZ::Outcome<Datum, AZStd::string> valueOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(*containerDatum, "Erase", *inputKeyDatum);
if (valueOutcome.IsSuccess())
{
// Push the source container as an output to support chaining
PushOutput(*containerDatum, (*outputSlot));
auto outcomeInnerResult = valueOutcome.GetValue().GetAs< AZ::Outcome<void, void>>();
if (outcomeInnerResult && !outcomeInnerResult->IsSuccess())
{
SignalOutput(GetSlotId("Element Not Found"));
return;
}
}
}
}
SignalOutput(GetSlotId("Out"));
}
void OperatorErase::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -39,8 +39,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
private:
bool m_missedElementNotFound = false;
@@ -46,43 +46,6 @@ namespace ScriptCanvas
}
}
void OperatorFront::InvokeOperator()
{
const SlotSet& slotSets = GetSourceSlots();
if (!slotSets.empty())
{
SlotId sourceSlotId = (*slotSets.begin());
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
const Datum* inputKeyDatum = FindDatum(*m_inputSlots.begin());
AZ::Outcome<Datum, AZStd::string> valueOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(*containerDatum, "Front", *inputKeyDatum);
if (!valueOutcome.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to call Front on container: %s", valueOutcome.GetError().c_str());
return;
}
if (Data::IsVectorContainerType(containerDatum->GetType()))
{
PushOutput(valueOutcome.TakeValue(), *GetSlot(*m_outputSlots.begin()));
}
}
}
SignalOutput(GetSlotId("Out"));
}
void OperatorFront::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -35,7 +35,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
};

Some files were not shown because too many files have changed in this diff Show More