Merged stabilization/2106 -> development (resolved merge conflicts).

Signed-off-by: Chris Galvan <chgalvan@amazon.com>
This commit is contained in:
Chris Galvan
2021-07-08 13:56:47 -05:00
489 changed files with 1685 additions and 13777 deletions
@@ -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;
}
};
}
@@ -7,7 +7,6 @@
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Asset/Functions/RuntimeFunctionAssetHandler.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
@@ -19,6 +18,7 @@
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/Entity.h>
#include <ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h>
namespace ScriptCanvas
{
@@ -168,7 +168,12 @@ namespace ScriptCanvas
{
if (nodeId == m_sourceEndpoint.GetNodeId() || nodeId == m_targetEndpoint.GetNodeId())
{
GraphRequestBus::Event(*GraphNotificationBus::GetCurrentBusId(), &GraphRequests::DisconnectById, GetEntityId());
Slot* sourceSlot{};
NodeRequestBus::EventResult(sourceSlot, m_sourceEndpoint.GetNodeId(), &NodeRequests::GetSlot, m_sourceEndpoint.GetSlotId());
if (sourceSlot)
{
GraphRequestBus::Event(sourceSlot->GetNode()->GetOwningScriptCanvasId(), &GraphRequests::DisconnectById, GetEntityId());
}
}
}
}
@@ -60,8 +60,6 @@ namespace ScriptCanvas
// GraphNotificationBus
void OnNodeRemoved(const ID& nodeId) override;
void UpdateConnectionStatus(NodeUpdateSlotReport& report);
protected:
//-------------------------------------------------------------------------
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
@@ -11,7 +11,6 @@
#include "Contracts/DisallowReentrantExecutionContract.h"
#include "Contracts/DisplayGroupConnectedSlotLimitContract.h"
#include "Contracts/DynamicTypeContract.h"
#include "Contracts/ExclusivePureDataContract.h"
#include "Contracts/IsReferenceTypeContract.h"
#include "Contracts/MathOperatorContract.h"
#include "Contracts/MethodOverloadContract.h"
@@ -1,56 +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 "ExclusivePureDataContract.h"
#include <ScriptCanvas/Core/ContractBus.h>
#include <ScriptCanvas/Core/GraphBus.h>
#include <ScriptCanvas/Core/NodeBus.h>
#include <ScriptCanvas/Core/Endpoint.h>
#include <ScriptCanvas/Core/Slot.h>
namespace ScriptCanvas
{
AZ::Outcome<void, AZStd::string> ExclusivePureDataContract::HasNoPureDataConnection(const Slot& dataInputSlot) const
{
bool isOnPureDataThread(true);
NodeRequestBus::EventResult(isOnPureDataThread, dataInputSlot.GetNodeId(), &NodeRequests::IsOnPureDataThread, dataInputSlot.GetId());
if (!isOnPureDataThread)
{
return AZ::Success();
}
return AZ::Failure(AZStd::string("There is already a pure data input into this slot"));
}
AZ::Outcome<void, AZStd::string> ExclusivePureDataContract::OnEvaluate(const Slot& sourceSlot, const Slot& targetSlot) const
{
if (sourceSlot.GetDescriptor().CanConnectTo(targetSlot.GetDescriptor()))
{
if (sourceSlot.GetDescriptor().IsInput())
{
return HasNoPureDataConnection(sourceSlot);
}
else if (targetSlot.GetDescriptor().IsInput())
{
return HasNoPureDataConnection(targetSlot);
}
}
return AZ::Failure(AZStd::string("invalid data connection attempted"));
}
void ExclusivePureDataContract::Reflect(AZ::ReflectContext* reflection)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
{
serializeContext->Class<ExclusivePureDataContract, Contract>()
->Version(0)
;
}
}
}
@@ -1,30 +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/Contract.h>
namespace ScriptCanvas
{
class ExclusivePureDataContract
: public Contract
{
public:
AZ_CLASS_ALLOCATOR(ExclusivePureDataContract, AZ::SystemAllocator, 0);
AZ_RTTI(ExclusivePureDataContract, "{E48A0B26-B6B7-4AF3-9341-9E5C5C1F0DE8}", Contract);
// no multiple literals, variables, defaults, gets, or any other new form of data that can be routed without getting pushed by execution
~ExclusivePureDataContract() override = default;
static void Reflect(AZ::ReflectContext* reflection);
protected:
AZ::Outcome<void, AZStd::string> OnEvaluate(const Slot& sourceSlot, const Slot& targetSlot) const override;
AZ::Outcome<void, AZStd::string> HasNoPureDataConnection(const Slot& dataInputSlot) const;
};
}
@@ -12,40 +12,32 @@
#include <AzCore/Serialization/IdUtils.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/Utils.h>
#include <AzFramework/Entity/EntityContextBus.h>
#include <ScriptCanvas/Asset/Functions/ScriptCanvasFunctionAsset.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/Connection.h>
#include <ScriptCanvas/Core/Core.h>
#include <ScriptCanvas/Core/Datum.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Core/PureData.h>
#include <ScriptCanvas/Data/BehaviorContextObject.h>
#include <ScriptCanvas/Grammar/AbstractCodeModel.h>
#include <ScriptCanvas/Debugger/ValidationEvents/DataValidation/DataValidationIds.h>
#include <ScriptCanvas/Data/PropertyTraits.h>
#include <ScriptCanvas/Debugger/StatusBus.h>
#include <ScriptCanvas/Debugger/ValidationEvents/DataValidation/DataValidationEvents.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ExecutionValidation/ExecutionValidationIds.h>
#include <ScriptCanvas/Debugger/ValidationEvents/DataValidation/DataValidationIds.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ExecutionValidation/ExecutionValidationEvents.h>
#include <ScriptCanvas/Libraries/Core/UnaryOperator.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ExecutionValidation/ExecutionValidationIds.h>
#include <ScriptCanvas/Grammar/AbstractCodeModel.h>
#include <ScriptCanvas/Libraries/Core/BinaryOperator.h>
#include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
#include <ScriptCanvas/Libraries/Core/ErrorHandler.h>
#include <ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h>
#include <ScriptCanvas/Libraries/Core/Method.h>
#include <ScriptCanvas/Libraries/Core/Start.h>
#include <ScriptCanvas/Libraries/Core/SendScriptEvent.h>
#include <ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h>
#include <ScriptCanvas/Libraries/Core/ScriptEventBase.h>
#include <ScriptCanvas/Libraries/Core/SendScriptEvent.h>
#include <ScriptCanvas/Libraries/Core/Start.h>
#include <ScriptCanvas/Libraries/Core/UnaryOperator.h>
#include <ScriptCanvas/Profiler/Driller.h>
#include <ScriptCanvas/Translation/Translation.h>
#include <ScriptCanvas/Debugger/StatusBus.h>
#include <ScriptCanvas/Variable/VariableBus.h>
#include <ScriptCanvas/Variable/VariableData.h>
@@ -58,6 +50,7 @@ namespace GraphCpp
MergeScriptAssetDescriptions,
VariablePanelSymantics,
AddVersionData,
RemoveFunctionGraphMarker,
// label your version above
Current
};
@@ -77,6 +70,11 @@ namespace ScriptCanvas
componentElementNode.AddElementWithData(context, "m_assetType", azrtti_typeid<RuntimeAsset>());
}
if (componentElementNode.GetVersion() < GraphCpp::GraphVersion::RemoveFunctionGraphMarker)
{
componentElementNode.RemoveElementByName(AZ_CRC_CE("isFunctionGraph"));
}
return true;
}
@@ -107,18 +105,15 @@ namespace ScriptCanvas
Nodes::ComparisonExpression::Reflect(context);
Datum::Reflect(context);
BehaviorContextObjectPtrReflect(context);
GraphData::Reflect(context);
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<Graph, AZ::Component>()
->Version(GraphCpp::GraphVersion::Current, &GraphComponentVersionConverter)
->Field("m_graphData", &Graph::m_graphData)
->Field("executionMode", &Graph::m_executionMode)
->Field("m_assetType", &Graph::m_assetType)
->Field("isFunctionGraph", &Graph::m_isFunctionGraph)
->Field("versionData", &Graph::m_versionData)
;
}
@@ -128,8 +123,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)
@@ -148,6 +141,7 @@ namespace ScriptCanvas
}
m_graphData.BuildEndpointMap();
for (auto& connectionEntity : m_graphData.m_connections)
{
if (connectionEntity)
@@ -159,21 +153,6 @@ namespace ScriptCanvas
StatusRequestBus::Handler::BusConnect(scriptCanvasId);
}
bool Graph::IsFunctionGraph() const
{
if (m_isFunctionGraph)
{
return true;
}
return false;
}
void Graph::MarkFunctionGraph()
{
m_isFunctionGraph = true;
}
void Graph::MarkVersion()
{
m_versionData.MarkLatest();
@@ -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
@@ -112,9 +110,6 @@ namespace ScriptCanvas
Graph* GetGraph() { return this; }
bool IsFunctionGraph() const;
void MarkFunctionGraph();
GraphData* GetGraphData() override { return &m_graphData; }
const GraphData* GetGraphDataConst() const override { return &m_graphData; }
const VariableData* GetVariableDataConst() const { return const_cast<Graph*>(this)->GetVariableData(); }
@@ -174,14 +169,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 +183,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;
@@ -208,7 +201,6 @@ namespace ScriptCanvas
AZ::Data::AssetType m_assetType;
private:
bool m_isFunctionGraph = false;
ScriptCanvasId m_scriptCanvasId;
ExecutionMode m_executionMode = ExecutionMode::Interpreted;
VersionData m_versionData;
@@ -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
{
@@ -51,7 +54,7 @@ namespace ScriptCanvas
virtual bool FindConnection(AZ::Entity*& connectionEntity, const Endpoint& firstEndpoint, const Endpoint& otherEndpoint) const = 0;
virtual Slot* FindSlot(const Endpoint& endpoint) const = 0;
//! Retrieves the Entity this Graph component is located on
//! NOTE: There can be multiple Graph components on the same entity so calling FindComponent may not not return this GraphComponent
virtual AZ::Entity* GetGraphEntity() const = 0;
@@ -59,7 +62,7 @@ namespace ScriptCanvas
//! Retrieves the Graph Component directly using the BusId
virtual Graph* GetGraph() = 0;
virtual bool Connect(const AZ::EntityId& sourceNodeId, const SlotId& sourceSlot, const AZ::EntityId& targetNodeId,const SlotId& targetSlot) = 0;
virtual bool Connect(const AZ::EntityId& sourceNodeId, const SlotId& sourceSlot, const AZ::EntityId& targetNodeId, const SlotId& targetSlot) = 0;
virtual bool Disconnect(const AZ::EntityId& sourceNodeId, const SlotId& sourceSlot, const AZ::EntityId& targetNodeId, const SlotId& targetSlot) = 0;
virtual bool ConnectByEndpoint(const Endpoint& sourceEndpoint, const Endpoint& targetEndpoint) = 0;
@@ -88,7 +91,7 @@ namespace ScriptCanvas
virtual bool AddItem(AZ::Entity* itemEntity) = 0;
//! Remove item if it is on the graph
virtual bool RemoveItem(AZ::Entity* itemEntity) = 0;
//! Retrieves a pointer the GraphData structure stored on the graph
virtual GraphData* GetGraphData() = 0;
virtual const GraphData* GetGraphDataConst() const = 0;
@@ -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
@@ -29,8 +29,7 @@ namespace ScriptCanvas
friend class Node;
friend class GraphVariable;
friend class PureData;
public:
AZ_CLASS_ALLOCATOR(ModifiableDatumView, AZ::SystemAllocator, 0);
@@ -1,133 +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 <Data/Data.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Core/PureData.h>
#include <AzCore/std/typetraits/function_traits.h>
namespace ScriptCanvas
{
namespace Nodes
{
template<typename t_Node, typename t_Datum>
class NativeDatumNode
: public PureData
{
public:
using t_ThisType = NativeDatumNode<t_Node, t_Datum>;
AZ_RTTI(((NativeDatumNode<t_Node, t_Datum>), "{B7D8D8D6-B2F1-481A-A712-B07D1C19555F}", t_Node, t_Datum), PureData, AZ::Component);
AZ_COMPONENT_INTRUSIVE_DESCRIPTOR_TYPE(NativeDatumNode);
AZ_COMPONENT_BASE(NativeDatumNode, PureData);
static void Reflect(AZ::ReflectContext* reflection)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
{
serializeContext->Class<t_ThisType, PureData>()
->Version(0)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<t_ThisType>("NativeDatumNode", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
;
}
}
}
~NativeDatumNode() override = default;
protected:
virtual void ConfigureSetters()
{
Data::SetterContainer setterWrappers = Data::ExplodeToSetters(Data::FromAZType(Data::Traits<t_Datum>::GetAZType()));
for (const auto& setterWrapperPair : setterWrappers)
{
SlotId setterSlotId;
const Data::SetterWrapper& setterWrapper = setterWrapperPair.second;
const AZStd::string argName = AZStd::string::format("%s: %s", Data::GetName(setterWrapper.m_propertyType).data(), setterWrapper.m_propertyName.data());
AZStd::string_view argumentTooltip;
// Add the slot if it doesn't exist
setterSlotId = FindSlotIdForDescriptor(argName, SlotDescriptors::DataIn());
if (!setterSlotId.IsValid())
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = argName;
slotConfiguration.m_toolTip = argumentTooltip;
slotConfiguration.SetType(setterWrapper.m_propertyType);
slotConfiguration.SetConnectionType(ConnectionType::Input);
setterSlotId = AddSlot(slotConfiguration);
}
if (setterSlotId.IsValid())
{
m_propertyAccount.m_getterSetterIdPairs[setterWrapperPair.first].second = setterSlotId;
m_propertyAccount.m_settersByInputSlot.emplace(setterSlotId, setterWrapperPair.second);
}
}
}
virtual void ConfigureGetters()
{
Data::GetterContainer getterWrappers = Data::ExplodeToGetters(Data::FromAZType(Data::Traits<t_Datum>::GetAZType()));
for (const auto& getterWrapperPair : getterWrappers)
{
SlotId getterSlotId;
const Data::GetterWrapper& getterWrapper = getterWrapperPair.second;
const AZStd::string resultSlotName(AZStd::string::format("%s: %s", getterWrapper.m_propertyName.data(), Data::GetName(getterWrapper.m_propertyType).data()));
// Add the slot if it doesn't exist
getterSlotId = FindSlotIdForDescriptor(resultSlotName, SlotDescriptors::DataOut());
if (!getterSlotId.IsValid())
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = resultSlotName;
slotConfiguration.SetType(getterWrapper.m_propertyType);
slotConfiguration.SetConnectionType(ConnectionType::Output);
getterSlotId = AddSlot(slotConfiguration);
}
if (getterSlotId.IsValid())
{
m_propertyAccount.m_getterSetterIdPairs[getterWrapperPair.first].first = getterSlotId;
m_propertyAccount.m_gettersByInputSlot.emplace(getterSlotId, getterWrapperPair.second);
}
}
}
virtual void ConfigureProperties()
{
if (IsConfigured())
{
return;
}
ConfigureGetters();
ConfigureSetters();
m_configured = true;
}
void OnInit() override
{
AddInputAndOutputTypeSlot(Data::FromAZType<t_Datum>());
ConfigureProperties();
}
};
}
}
@@ -19,11 +19,9 @@
#include <ScriptCanvas/Core/Attributes.h>
#include <ScriptCanvas/Core/Contract.h>
#include <ScriptCanvas/Core/Contracts/ConnectionLimitContract.h>
#include <ScriptCanvas/Core/Contracts/ExclusivePureDataContract.h>
#include <ScriptCanvas/Core/Contracts/DynamicTypeContract.h>
#include <ScriptCanvas/Core/GraphBus.h>
#include <ScriptCanvas/Core/NodeableNode.h>
#include <ScriptCanvas/Core/PureData.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
#include <ScriptCanvas/Variable/VariableBus.h>
@@ -48,9 +46,7 @@ namespace NodeCpp
// add your named version above
Current,
};
};
}
namespace ScriptCanvas
@@ -397,7 +393,6 @@ namespace ScriptCanvas
void Node::Reflect(AZ::ReflectContext* context)
{
Slot::Reflect(context);
ExclusivePureDataContract::Reflect(context);
Nodes::NodeableNode::Reflect(context);
// Version Conversion Reflection
@@ -492,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()
@@ -730,26 +718,11 @@ namespace ScriptCanvas
// for each output slot...
// for each connected node...
// remove the ability to default it...
// ...and until a more viable solution is available, variable get input in another node must be exclusive
EndpointsResolved connections = GetConnectedNodes(inputSlot);
if (!connections.empty())
{
bool isConnectedToPureData = false;
for (auto& nodePtrSlotId : connections)
{
if (azrtti_cast<const PureData*>(nodePtrSlotId.first))
{
isConnectedToPureData = true;
break;
}
}
if (!isConnectedToPureData)
{
m_possiblyStaleInput.insert(slotId);
}
m_possiblyStaleInput.insert(slotId);
}
}
}
@@ -757,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))
{
@@ -804,9 +777,7 @@ namespace ScriptCanvas
bool Node::IsTargetInDataFlowPath(const Node* targetNode) const
{
AZStd::unordered_set<ID> path;
return azrtti_cast<const PureData*>(this)
|| azrtti_cast<const PureData*>(targetNode)
|| (targetNode && IsTargetInDataFlowPath(targetNode->GetEntityId(), path));
return (targetNode && IsTargetInDataFlowPath(targetNode->GetEntityId(), path));
}
bool Node::IsTargetInDataFlowPath(const ID& targetNodeId, AZStd::unordered_set<ID>& path) const
@@ -866,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)
@@ -1620,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))
@@ -1936,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());
}
}
@@ -2361,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();
}
@@ -2448,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
@@ -2459,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)
{
@@ -2478,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)
{
@@ -2491,7 +2442,7 @@ namespace ScriptCanvas
AZ::Data::AssetId Node::GetGraphAssetId() const
{
return m_runtimeBus->GetAssetId();
return m_graphRequestBus->GetAssetId();
}
AZStd::string Node::GetGraphAssetName() const
@@ -2504,7 +2455,7 @@ namespace ScriptCanvas
GraphIdentifier Node::GetGraphIdentifier() const
{
return m_runtimeBus->GetGraphIdentifier();
return m_graphRequestBus->GetGraphIdentifier();
}
bool Node::IsSanityCheckRequired() const
@@ -2674,7 +2625,7 @@ namespace ScriptCanvas
return;
}
auto node = m_runtimeBus->FindNode(endpoint.GetNodeId());
auto node = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (node)
{
@@ -2862,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
@@ -2902,7 +2853,7 @@ namespace ScriptCanvas
bool Node::IsActivated() const
{
return m_runtimeBus;
return m_graphRequestBus;
}
EndpointsResolved Node::GetConnectedNodes(const Slot& slot) const
@@ -2911,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());
@@ -2935,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());
@@ -2959,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());
@@ -2983,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
@@ -3040,9 +2957,8 @@ namespace ScriptCanvas
FindModifiableDatumView(slotId, datumView);
if (datumView.IsValid())
{
{
datumView.AssignToDatum(newInput);
OnInputChanged((*datumView.GetDatum()), slotId);
}
}
@@ -3056,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,230 +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 "PureData.h"
namespace ScriptCanvas
{
const char* PureData::k_getThis("Get");
const char* PureData::k_setThis("Set");
PureData::~PureData()
{
}
const AZStd::unordered_map<AZStd::string, AZStd::pair<SlotId, SlotId>>& PureData::GetPropertyNameSlotMap() const
{
return m_propertyAccount.m_getterSetterIdPairs;
}
void PureData::AddInputAndOutputTypeSlot(const Data::Type& type, const void* source)
{
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = k_setThis;
slotConfiguration.SetConnectionType(ConnectionType::Input);
slotConfiguration.ConfigureDatum(AZStd::move(Datum(type, Datum::eOriginality::Original, source, AZ::Uuid::CreateNull())));
AddSlot(slotConfiguration);
}
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = k_getThis;
slotConfiguration.SetConnectionType(ConnectionType::Output);
slotConfiguration.SetType(type);
AddSlot(slotConfiguration);
}
}
void PureData::AddInputTypeAndOutputTypeSlot(const Data::Type& type)
{
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = k_setThis;
slotConfiguration.SetConnectionType(ConnectionType::Input);
slotConfiguration.SetType(type);
AddSlot(slotConfiguration);
}
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = k_getThis;
slotConfiguration.SetConnectionType(ConnectionType::Output);
slotConfiguration.SetType(type);
AddSlot(slotConfiguration);
}
}
void PureData::OnActivate()
{
PushThis();
for (const auto& propertySlotIdsPair : m_propertyAccount.m_getterSetterIdPairs)
{
const SlotId& getterSlotId = propertySlotIdsPair.second.first;
CallGetter(getterSlotId);
}
}
void PureData::OnInputChanged(const Datum& input, [[maybe_unused]] const SlotId& id)
{
if (IsActivated())
{
OnOutputChanged(input);
}
}
AZStd::string_view PureData::GetInputDataName() const
{
return k_setThis;
}
AZStd::string_view PureData::GetOutputDataName() const
{
return k_getThis;
}
void PureData::CallGetter(const SlotId& getterSlotId)
{
auto getterFuncIt = m_propertyAccount.m_gettersByInputSlot.find(getterSlotId);
Slot* getterSlot = GetSlot(getterSlotId);
if (getterSlot && getterFuncIt != m_propertyAccount.m_gettersByInputSlot.end())
{
AZStd::vector<AZStd::pair<Node*, const SlotId>> outputNodes(ModConnectedNodes(*getterSlot));
if (!outputNodes.empty())
{
auto getterOutcome = getterFuncIt->second.m_getterFunction((*FindDatum(GetSlotId(k_setThis))));
if (!getterOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), getterOutcome.GetError().data());
return;
}
for (auto& nodePtrSlot : outputNodes)
{
if (nodePtrSlot.first)
{
Node::SetInput(*nodePtrSlot.first, nodePtrSlot.second, getterOutcome.GetValue());
}
}
}
}
}
void PureData::SetInput(const Datum& input, const SlotId& id)
{
if (id == FindSlotIdForDescriptor(GetInputDataName(), SlotDescriptors::DataIn()))
{
// push this value, as usual
Node::SetInput(input, id);
// now, call every getter, as every property has (presumably) been changed
for (const auto& propertyNameSlotIdsPair : m_propertyAccount.m_getterSetterIdPairs)
{
const SlotId& getterSlotId = propertyNameSlotIdsPair.second.first;
CallGetter(getterSlotId);
}
}
else
{
SetProperty(input, id);
}
}
void PureData::SetInput(Datum&& input, const SlotId& id)
{
if (id == FindSlotIdForDescriptor(GetInputDataName(), SlotDescriptors::DataIn()))
{
// push this value, as usual
Node::SetInput(AZStd::move(input), id);
if (IsActivated())
{
// now, call every getter, as every property has (presumably) been changed
for (const auto& propertyNameSlotIdsPair : m_propertyAccount.m_getterSetterIdPairs)
{
const SlotId& getterSlotId = propertyNameSlotIdsPair.second.first;
CallGetter(getterSlotId);
}
}
}
else
{
SetProperty(AZStd::move(input), id);
}
}
void PureData::SetProperty(const Datum& input, const SlotId& setterId)
{
auto methodBySlotIter = m_propertyAccount.m_settersByInputSlot.find(setterId);
if (methodBySlotIter == m_propertyAccount.m_settersByInputSlot.end())
{
AZ_Error("Script Canvas", false, "BehaviorContextObject SlotId %s did not route to a setter", setterId.m_id.ToString<AZStd::string>().data());
return;
}
if (!methodBySlotIter->second.m_setterFunction)
{
AZ_Error("Script Canvas", false, "BehaviorContextObject setter is not invocable for SlotId %s is nullptr", setterId.m_id.ToString<AZStd::string>().data());
return;
}
ModifiableDatumView datumView;
FindModifiableDatumView(GetSlotId(k_setThis), datumView);
Datum* datum = datumView.ModifyDatum();
auto setterOutcome = methodBySlotIter->second.m_setterFunction((*datum), input);
if (!setterOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), setterOutcome.TakeError().data());
return;
}
datumView.SignalModification();
PushThis();
auto getterSetterIt = m_propertyAccount.m_getterSetterIdPairs.find(methodBySlotIter->second.m_propertyName);
if (getterSetterIt != m_propertyAccount.m_getterSetterIdPairs.end())
{
CallGetter(getterSetterIt->second.first);
}
}
void PureData::Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<PureData, Node>()
->Version(0)
;
AZ::EditContext* editContext = serializeContext->GetEditContext();
if (editContext)
{
editContext->Class<PureData>("PureData", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
;
}
}
}
}
@@ -1,111 +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/Node.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/Datum.h>
#include <ScriptCanvas/Data/PropertyTraits.h>
namespace AZ
{
class BehaviorClass;
struct BehaviorValueParameter;
class ReflectContext;
}
namespace ScriptCanvas
{
struct PropertyAccount
{
AZStd::unordered_map<SlotId, Data::GetterWrapper> m_gettersByInputSlot;
AZStd::unordered_map<SlotId, Data::SetterWrapper> m_settersByInputSlot;
// The first slot id of the pair is the Getter SlotId, the second slot id of the pair is the Setter SlotID
AZStd::unordered_map<AZStd::string, AZStd::pair<SlotId, SlotId>> m_getterSetterIdPairs;
};
class PureData
: public Node
{
public:
AZ_COMPONENT(PureData, "{8B80FF54-0786-4FEE-B4A3-12907EBF8B75}", Node);
static void Reflect(AZ::ReflectContext* reflectContext);
static const char* k_getThis;
static const char* k_setThis;
const AZStd::unordered_map<AZStd::string, AZStd::pair<SlotId, SlotId>>& GetPropertyNameSlotMap() const;
AZ_INLINE AZ::Outcome<DependencyReport, void> GetDependencies() const override { return AZ::Success(DependencyReport{}); }
~PureData() override;
protected:
void AddInputAndOutputTypeSlot(const Data::Type& type, const void* defaultValue = nullptr);
template<typename DatumType>
void AddDefaultInputAndOutputTypeSlot(DatumType&& defaultValue);
void AddInputTypeAndOutputTypeSlot(const Data::Type& type);
bool IsDeprecated() const override { return true; }
void OnActivate() override;
void OnInputChanged(const Datum& input, const SlotId& id) override;
void MarkDefaultableInput() override {}
AZ_INLINE void OnOutputChanged(const Datum& output) const
{
Slot* slot = GetSlotByName(GetOutputDataName());
if (slot)
{
OnOutputChanged(output, (*slot));
}
}
AZ_INLINE void OnOutputChanged(const Datum& output, const Slot& outputSlot) const
{
PushOutput(output, outputSlot);
}
// push data out
AZ_INLINE void PushThis()
{
auto slotId = GetSlotId(GetInputDataName());
if (auto setDatum = FindDatum(slotId))
{
OnInputChanged(*setDatum, slotId);
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), "No input datum in a PureData class %s. You must push your data manually in OnActivate() if no input is connected!");
}
}
AZStd::string_view GetInputDataName() const;
AZStd::string_view GetOutputDataName() const;
void SetInput(const Datum& input, const SlotId& id) override;
void SetInput(Datum&& input, const SlotId& id) override;
void SetProperty(const Datum& input, const SlotId& id);
void CallGetter(const SlotId& getterSlotId);
bool IsConfigured() { return m_configured; }
PropertyAccount m_propertyAccount;
bool m_configured = false;
};
template<typename DatumType>
void PureData::AddDefaultInputAndOutputTypeSlot(DatumType&& defaultValue)
{
AddInputDatumSlot(GetInputDataName(), "", Datum::eOriginality::Original, AZStd::forward<DatumType>(defaultValue));
AddOutputTypeSlot(GetOutputDataName(), "", Data::FromAZType(azrtti_typeid<AZStd::decay_t<DatumType>>()), OutputStorage::Optional);
}
template<>
void PureData::AddDefaultInputAndOutputTypeSlot<Data::Type>(Data::Type&&) = delete;
}
@@ -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>;
}
@@ -231,12 +231,6 @@ namespace ScriptCanvas
// Add the slot type contract by default, It is used for filtering input/output slots and flow/data slots
m_contracts.emplace_back(AZStd::make_unique<SlotTypeContract>());
// Every DataIn slot has a contract validating that only 1 connection from any PureData node is allowed
if (IsData() && IsInput())
{
AddContract({ []() { return aznew ExclusivePureDataContract(); } });
}
for (const auto& contractDesc : slotConfiguration.m_contractDescs)
{
AddContract(contractDesc);
@@ -390,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());
}
}
}
@@ -590,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)"; }
@@ -105,7 +83,7 @@ namespace ScriptCanvas
////
int m_timeUnits = 0;
int m_tickOrder = static_cast<int>(AZ::TICK_DEFAULT);
int m_tickOrder = 1000; // from TICK_DEFAULT
bool m_isActive = false;
@@ -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;
@@ -474,11 +443,6 @@ namespace ScriptCanvas
});
}
void ExpressionNodeBase::OnResult([[maybe_unused]] const ExpressionEvaluation::ExpressionResult& result)
{
AZ_Assert(false, "Implementing node must override OnResult.");
}
ExpressionEvaluation::ParseOutcome ExpressionNodeBase::ParseExpression([[maybe_unused]] const AZStd::string& formatString)
{
AZ_Assert(false , "Implementing node must override OnResult.");
@@ -37,8 +37,6 @@ namespace ScriptCanvas
AZStd::string GetRawFormat() const;
const AZStd::unordered_map<AZStd::string, SlotId>& GetSlotsByName() const;
protected:
@@ -53,10 +51,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;
@@ -80,14 +74,11 @@ namespace ScriptCanvas
AZ::Crc32 GetPropertyId() const { return AZ_CRC("FormatStringProperty", 0x2c587efa); }
protected:
virtual void OnResult(const ExpressionEvaluation::ExpressionResult& result);
virtual ExpressionEvaluation::ParseOutcome ParseExpression(const AZStd::string& formatString);
virtual AZStd::string GetExpressionSeparator() const;
private:
void PushVariable(const AZStd::string& variableName, const Datum& datum);
// NodePropertyInterface...
@@ -110,7 +101,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);
}
}
};
}
@@ -1,88 +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 "Assign.h"
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
void Assign::OnInit()
{
AddSlot("In", "", SlotType::ExecutionIn);
AddSlot("Out", "", SlotType::ExecutionOut);
AddInputDatumDynamicTypedSlot("Source");
AddSlot("Target", "", SlotType::DataOut);
}
Data::Type Assign::GetSlotDataType(const SlotId& slotId) const
{
if (Slot* sourceSlot = GetSlot(GetSlotId("Source")))
{
auto inputs = GetConnectedNodes(*sourceSlot);
// contracts should enforce this, but in case it breaks...
if (inputs.size() == 1)
{
auto input = *inputs.begin();
return input.first->GetSlotDataType(input.second);
}
else
{
AZ_Error("ScriptCanvas", (inputs.size() == 0), "Multiple inputs to 'Assign' are forbidden");
}
}
return Data::Type::Invalid();
}
void Assign::OnInputSignal(const SlotId&)
{
if (auto input = GetDatumByIndex(k_sourceInputIndex))
{
PushOutput(*input, *GetSlotByIndex(k_targetSlotIndex));
}
SignalOutput(GetSlotId("Out"));
}
AZStd::Outcome<void, AZStd::string> Assign::SlotAcceptsType(const SlotId& slotID, const Data::Type& type) const
{
Slot* sourceSlot = GetSlot(GetSlotId("Source"));
Slot* targetSlot = GetSlot(GetSlotId("Target"));
if (sourceSlot == nullptr
|| targetSlot == nullptr)
{
return AZ::Failure(AZStd::string("Unable to find all necessary slots on node");)
}
return DynamicSlotAcceptsType(slotID, type, Node::DynamicTypeArity::Single, *targetSlot, AZStd::vector<Slot*>{sourceSlot});
}
void Assign::Reflect(AZ::ReflectContext* reflectContext)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<Assign, Node>()
->Version(0)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<Assign>("Assign", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/ScriptCanvas/Placeholder.png")
;
}
}
}
}
}
}
@@ -1,39 +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/GraphBus.h>
#include <ScriptCanvas/Core/Node.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
class Assign
: public Node
{
public:
AZ_COMPONENT(Assign, "{E734ADCE-D822-4487-9681-5A80D8E4D263}", Node);
static void Reflect(AZ::ReflectContext* reflectContext);
protected:
static const int k_sourceInputIndex = 0;
static const int k_targetSlotIndex = 3;
Data::Type GetSlotDataType(const SlotId& slotId) const override;
void OnInit() override;
void OnInputSignal(const SlotId&) override;
AZ::Outcome<void, AZStd::string> SlotAcceptsType(const SlotId&, const Data::Type&) const override;
};
}
}
}
@@ -1,216 +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 "BehaviorContextObjectNode.h"
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/std/string/string_view.h>
#include <ScriptCanvas/Data/PropertyTraits.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
namespace Internal
{
static const AZ::u32 k_thisParamIndex(0);
static const AZ::u32 k_setValueParamIndex(1);
static const AZ::u32 k_firstFirstPropertyDataSlotIndex(2);
static const AZ::u32 k_valueArgumentIndex(1);
static const char* k_setThis("Set");
}
AZStd::string BehaviorContextObjectNode::GetDebugName() const
{
if (auto input = FindDatum(GetSlotId(Internal::k_setThis)))
{
return Data::GetName(input->GetType());
}
return "Invalid";
}
void BehaviorContextObjectNode::InitializeObject(const AZ::Uuid& azType)
{
// \todo this works with basic types, and it probably shouldn't
if (auto bcClass = AZ::BehaviorContextHelper::GetClass(azType))
{
InitializeObject(*bcClass);
}
else
{
const void* defaultValue = nullptr;
if (Data::IsEntityID(azType))
{
defaultValue = &ScriptCanvas::GraphOwnerId;
}
AddInputAndOutputTypeSlot(Data::FromAZType(azType), defaultValue);
}
}
void BehaviorContextObjectNode::InitializeObject(const AZStd::string& classNameString)
{
if (auto bcClass = AZ::BehaviorContextHelper::GetClass(classNameString))
{
InitializeObject(*bcClass);
}
}
void BehaviorContextObjectNode::InitializeObject(const AZ::BehaviorClass& behaviorClass)
{
m_className = behaviorClass.m_name;
const void* defaultValue = nullptr;
if (Data::IsEntityID(behaviorClass.m_typeId))
{
defaultValue = &ScriptCanvas::GraphOwnerId;
}
AddInputAndOutputTypeSlot(Data::FromAZType(behaviorClass.m_typeId), defaultValue);
ConfigureProperties(behaviorClass);
}
void BehaviorContextObjectNode::InitializeObject(const Data::Type& type)
{
if (auto bcClass = AZ::BehaviorContextHelper::GetClass(type.GetAZType()))
{
InitializeObject(*bcClass);
}
}
void BehaviorContextObjectNode::ConfigureSetters(const AZ::BehaviorClass& behaviorClass)
{
Data::SetterContainer setterWrappers = Data::ExplodeToSetters(Data::FromAZType(behaviorClass.m_typeId));
for (const auto& setterWrapperPair : setterWrappers)
{
SlotId setterSlotId;
auto propertyIt = behaviorClass.m_properties.find(setterWrapperPair.first);
if (propertyIt != behaviorClass.m_properties.end())
{
const Data::SetterWrapper& setterWrapper = setterWrapperPair.second;
const AZStd::string argName = AZStd::string::format("%s: %s", Data::GetName(setterWrapper.m_propertyType).data(), setterWrapper.m_propertyName.data());
const AZStd::string* argumentTooltipPtr = propertyIt->second->m_setter->GetArgumentToolTip(Internal::k_setValueParamIndex);
AZStd::string_view argumentTooltip = argumentTooltipPtr ? AZStd::string_view(*argumentTooltipPtr) : AZStd::string_view{};
// Add the slot if it doesn't exist
setterSlotId = FindSlotIdForDescriptor(argName, SlotDescriptors::DataIn());
if (!setterSlotId.IsValid())
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = argName;
slotConfiguration.m_toolTip = argumentTooltip;
slotConfiguration.SetType(setterWrapper.m_propertyType);
slotConfiguration.SetConnectionType(ConnectionType::Input);
setterSlotId = AddSlot(slotConfiguration);
}
}
if (setterSlotId.IsValid())
{
m_propertyAccount.m_getterSetterIdPairs[setterWrapperPair.first].second = setterSlotId;
m_propertyAccount.m_settersByInputSlot.emplace(setterSlotId, setterWrapperPair.second);
}
}
}
void BehaviorContextObjectNode::ConfigureGetters(const AZ::BehaviorClass& behaviorClass)
{
Data::GetterContainer getterWrappers = Data::ExplodeToGetters(Data::FromAZType(behaviorClass.m_typeId));
for (const auto& getterWrapperPair : getterWrappers)
{
SlotId getterSlotId;
auto propertyIt = behaviorClass.m_properties.find(getterWrapperPair.first);
if (propertyIt != behaviorClass.m_properties.end())
{
const Data::GetterWrapper& getterWrapper = getterWrapperPair.second;
const AZStd::string resultSlotName(AZStd::string::format("%s: %s", getterWrapper.m_propertyName.data(), Data::GetName(getterWrapper.m_propertyType).data()));
// Add the slot if it doesn't exist
getterSlotId = FindSlotIdForDescriptor(resultSlotName, SlotDescriptors::DataOut());
if (!getterSlotId.IsValid())
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = resultSlotName;
slotConfiguration.SetType(getterWrapper.m_propertyType);
slotConfiguration.SetConnectionType(ConnectionType::Output);
getterSlotId = AddSlot(slotConfiguration);
}
}
if (getterSlotId.IsValid())
{
m_propertyAccount.m_getterSetterIdPairs[getterWrapperPair.first].first = getterSlotId;
m_propertyAccount.m_gettersByInputSlot.emplace(getterSlotId, getterWrapperPair.second);
}
}
}
void BehaviorContextObjectNode::ConfigureProperties(const AZ::BehaviorClass& behaviorClass)
{
if (IsConfigured())
{
return;
}
ConfigureGetters(behaviorClass);
ConfigureSetters(behaviorClass);
m_configured = true;
}
void BehaviorContextObjectNode::OnInit()
{
if (auto input = FindDatum(GetSlotId(k_setThis)))
{
if (!input->Empty())
{
AddInputTypeAndOutputTypeSlot(input->GetType());
}
}
}
void BehaviorContextObjectNode::OnWriteEnd()
{
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
auto bcClass = !m_className.empty() ? AZ::BehaviorContextHelper::GetClass(m_className) : nullptr;
if (bcClass)
{
ConfigureProperties(*bcClass);
}
}
void BehaviorContextObjectNode::Reflect(AZ::ReflectContext* reflectContext)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<BehaviorContextObjectNode, Node>()
->Version(1)
->EventHandler<SerializeContextOnWriteEndHandler<BehaviorContextObjectNode>>()
->Field("m_className", &BehaviorContextObjectNode::m_className)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<BehaviorContextObjectNode>("BehaviorContextObjectNode", "BehaviorContextObjectNode")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
;
}
}
}
}
}
}
@@ -1,73 +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/Node.h>
#include <ScriptCanvas/Core/PureData.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/Datum.h>
namespace AZ
{
class BehaviorClass;
struct BehaviorValueParameter;
class ReflectContext;
}
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
class BehaviorContextObjectNode
: public PureData
{
public:
//\todo move to behavior context
enum ParameterCount
{
Getter = 1,
Setter = 2,
};
AZ_COMPONENT(BehaviorContextObjectNode, "{4344869D-2543-4FA3-BCD0-B6DB1E815928}", PureData);
static void Reflect(AZ::ReflectContext* reflectContext);
BehaviorContextObjectNode() = default;
~BehaviorContextObjectNode() override = default;
AZStd::string GetDebugName() const override;
void InitializeObject(const AZ::Uuid& azType);
void InitializeObject(const AZStd::string& classNameString);
void InitializeObject(const Data::Type& type);
void OnWriteEnd();
protected:
void InitializeObject(const AZ::BehaviorClass& behaviorClass);
void OnInit() override;
virtual void ConfigureSetters(const AZ::BehaviorClass& behaviorClass);
virtual void ConfigureGetters(const AZ::BehaviorClass& behaviorClass);
void ConfigureProperties(const AZ::BehaviorClass& behaviorClass);
private:
AZStd::recursive_mutex m_mutex; // post-serialization
AZStd::string m_className;
BehaviorContextObjectNode(const BehaviorContextObjectNode&) = delete;
};
}
}
}
@@ -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()
{
{
@@ -1,6 +1,6 @@
/*
* 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
*
*/
@@ -10,7 +10,6 @@
#include <AzCore/std/typetraits/remove_cv.h>
#include <AzCore/std/typetraits/function_traits.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Core/PureData.h>
#include <ScriptCanvas/Core/Datum.h>
namespace ScriptCanvas
@@ -24,7 +23,7 @@ namespace ScriptCanvas
AZ_COMPONENT(BinaryOperator, "{5BD0E8C7-9B0A-42F5-9EB0-199E6EC8FA99}", Node);
static void Reflect(AZ::ReflectContext* reflection);
static const char* k_lhsName;
static const char* k_rhsName;
static const char* k_resultName;
@@ -34,8 +33,6 @@ namespace ScriptCanvas
static const char* k_onTrue;
static const char* k_onFalse;
protected:
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& /*executionSlot*/, CombinedSlotType targetSlotType, const Slot* /*executionChildSlot*/) const override
{
@@ -48,15 +45,9 @@ 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;
};
class ArithmeticExpression
: public BinaryOperator
{
@@ -66,24 +57,20 @@ namespace ScriptCanvas
static void Reflect(AZ::ReflectContext* reflection);
bool IsDeprecated() const override { return true; }
void CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map<SlotId, AZStd::vector<SlotId>>& outSlotIdMap) const override;
protected:
// adds Number inputs, adds Number output type
void OnInit() override;
void OnInputSignal(const SlotId& slot) override;
};
class BooleanExpression
: public BinaryOperator
{
public:
AZ_COMPONENT(BooleanExpression, "{36C69825-CFF8-4F70-8F3B-1A9227E8BEEA}", BinaryOperator);
static void Reflect(AZ::ReflectContext* reflection);
//////////////////////////////////////////////////////////////////////////
@@ -106,31 +93,27 @@ namespace ScriptCanvas
//////////////////////////////////////////////////////////////////////////
protected:
// initialize boolean expression, adds boolean output type calls
// initialize boolean expression, adds boolean output type calls
void OnInit() override;
virtual void InitializeBooleanExpression();
void OnInputSignal(const SlotId& slot) override;
};
// accepts any type, checks for type equality, and then value equality or pointer equality
class EqualityExpression
: public BooleanExpression
: public BooleanExpression
{
public:
AZ_COMPONENT(EqualityExpression, "{78D20EB6-BA07-4071-B646-7C2D68A0A4A6}", BooleanExpression);
static void Reflect(AZ::ReflectContext* reflection);
protected:
// adds any required input types
void InitializeBooleanExpression() override;
private:
SlotId m_firstSlotId;
SlotId m_secondSlotId;
ScriptCanvas::Data::Type m_displayType;
};
@@ -142,11 +125,10 @@ namespace ScriptCanvas
AZ_COMPONENT(ComparisonExpression, "{82C50EAD-D3DD-45D2-BFCE-981D95771DC8}", EqualityExpression);
static void Reflect(AZ::ReflectContext* reflection);
protected:
// adds number types
void InitializeBooleanExpression() override;
};
}
}
}
}
@@ -99,13 +99,9 @@ namespace ScriptCanvas
void Core::InitNodeRegistry(NodeRegistry& nodeRegistry)
{
using namespace ScriptCanvas::Nodes::Core;
AddNodeToRegistry<Core, Error>(nodeRegistry);
AddNodeToRegistry<Core, ErrorHandler>(nodeRegistry);
AddNodeToRegistry<Core, Method>(nodeRegistry);
AddNodeToRegistry<Core, MethodOverloaded>(nodeRegistry);
AddNodeToRegistry<Core, BehaviorContextObjectNode>(nodeRegistry);
AddNodeToRegistry<Core, Start>(nodeRegistry);
AddNodeToRegistry<Core, ScriptCanvas::Nodes::Core::String>(nodeRegistry);
AddNodeToRegistry<Core, EBusEventHandler>(nodeRegistry);
AddNodeToRegistry<Core, AzEventHandler>(nodeRegistry);
AddNodeToRegistry<Core, ExtractProperty>(nodeRegistry);
@@ -124,13 +120,9 @@ namespace ScriptCanvas
AZStd::vector<AZ::ComponentDescriptor*> Core::GetComponentDescriptors()
{
return AZStd::vector<AZ::ComponentDescriptor*>({
ScriptCanvas::Nodes::Core::Error::CreateDescriptor(),
ScriptCanvas::Nodes::Core::ErrorHandler::CreateDescriptor(),
ScriptCanvas::Nodes::Core::Method::CreateDescriptor(),
ScriptCanvas::Nodes::Core::MethodOverloaded::CreateDescriptor(),
ScriptCanvas::Nodes::Core::BehaviorContextObjectNode::CreateDescriptor(),
ScriptCanvas::Nodes::Core::Start::CreateDescriptor(),
ScriptCanvas::Nodes::Core::String::CreateDescriptor(),
ScriptCanvas::Nodes::Core::EBusEventHandler::CreateDescriptor(),
ScriptCanvas::Nodes::Core::AzEventHandler::CreateDescriptor(),
ScriptCanvas::Nodes::Core::ExtractProperty::CreateDescriptor(),
@@ -10,10 +10,7 @@
// This header is only meant to include the nodes and should not contain
// shared code
#include "BehaviorContextObjectNode.h"
#include "EBusEventHandler.h"
#include "Error.h"
#include "ErrorHandler.h"
#include "ExtractProperty.h"
#include "FunctionDefinitionNode.h"
#include "ForEach.h"
@@ -28,4 +25,3 @@
#include "SendScriptEvent.h"
#include "SetVariable.h"
#include "Start.h"
#include "String.h"
@@ -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{});
@@ -149,12 +130,12 @@ namespace ScriptCanvas
{
return IsIDRequired();
}
bool EBusEventHandler::IsAutoConnected() const
{
return m_autoConnectToGraphOwner;
}
const Datum* EBusEventHandler::GetHandlerStartAddress() const
{
return FindDatum(GetSlotId(c_busIdName));
@@ -222,7 +203,7 @@ namespace ScriptCanvas
{
return AZ::Success(entry->m_eventName);
}
return AZ::Failure();
}
@@ -263,7 +244,7 @@ namespace ScriptCanvas
{
return EventHandlerTranslationHelper::GetSlotsInExecutionThreadByType(*this, executionSlot, targetSlotType);
}
AZStd::vector<SlotId> EBusEventHandler::GetNonEventSlotIds() const
{
AZStd::vector<SlotId> nonEventSlotIds;
@@ -330,7 +311,7 @@ namespace ScriptCanvas
return true;
}
const AZ::BehaviorEBusHandler::BusForwarderEvent& event = m_handler->GetEvents()[eventIndex];
const AZ::BehaviorEBusHandler::BusForwarderEvent& event = m_handler->GetEvents()[eventIndex];
// Compare output type
const bool eventHasOutput = !event.m_parameters.empty() && !event.m_parameters.front().m_typeId.IsNull() && event.m_parameters.front().m_typeId != azrtti_typeid<void>();
@@ -470,7 +451,7 @@ namespace ScriptCanvas
config.m_name = c_busIdName;
config.m_toolTip = busToolTip;
config.SetConnectionType(ConnectionType::Input);
if (busId == azrtti_typeid<AZ::EntityId>())
{
config.SetDefaultValue(GraphOwnerId);
@@ -478,7 +459,7 @@ namespace ScriptCanvas
else
{
Data::Type busIdType(AZ::BehaviorContextHelper::IsStringParameter(m_ebus->m_idParam) ? Data::Type::String() : Data::FromAZType(busId));
config.ConfigureDatum(AZStd::move(Datum(busIdType, Datum::eOriginality::Original)));
}
@@ -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);
@@ -806,7 +655,7 @@ namespace ScriptCanvas
return AZStd::find(m_parameterSlotIds.begin(), m_parameterSlotIds.end(), slotId) != m_parameterSlotIds.end();
}
}
bool EBusEventEntry::EBusEventEntryVersionConverter(AZ::SerializeContext& serializeContext, AZ::SerializeContext::DataElementNode& rootElement)
{
if (rootElement.GetVersion() == 0)
@@ -36,7 +36,7 @@ namespace ScriptCanvas
static void Reflect(AZ::ReflectContext* context);
AZ_TYPE_INFO(EBusEventEntry, "{92A20C1B-A54A-4583-97DB-A894377ACE21}");
AZStd::string m_eventName;
EBusEventId m_eventId;
SlotId m_eventSlotId;
@@ -44,7 +44,7 @@ namespace ScriptCanvas
AZStd::vector<SlotId> m_parameterSlotIds;
int m_numExpectedArguments = {};
bool m_resultEvaluated = {};
bool m_shouldHandleEvent = false;
bool m_isHandlingEvent = false;
@@ -54,7 +54,7 @@ namespace ScriptCanvas
};
//! Provides a node that represents an EBus handler
class EBusEventHandler
class EBusEventHandler
: public Node
, public EBusHandlerNodeRequestBus::Handler
{
@@ -68,7 +68,7 @@ namespace ScriptCanvas
using Events = AZStd::vector<EBusEventEntry>;
using EventMap = AZStd::map<AZ::Crc32, EBusEventEntry>;
EBusEventHandler()
EBusEventHandler()
: m_autoConnectToGraphOwner(true)
{}
@@ -78,11 +78,8 @@ 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;
bool ContainsReferencesToVariables(const AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const override;
@@ -98,14 +95,8 @@ namespace ScriptCanvas
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;
@@ -128,7 +119,7 @@ namespace ScriptCanvas
AZStd::vector<SlotId> GetNonEventSlotIds() const override;
AZ::Outcome<DependencyReport, void> GetDependencies() const override;
bool IsEventSlotId(const SlotId& slotId) const;
bool IsEventHandler() const override;
@@ -138,7 +129,7 @@ namespace ScriptCanvas
bool IsVariableWriteHandler() const override;
bool IsValid() const;
inline bool IsIDRequired() const
{
return m_ebus && BehaviorContextUtils::GetEBusAddressPolicy(*m_ebus) == AZ::EBusAddressPolicy::ById;
@@ -165,16 +156,10 @@ namespace ScriptCanvas
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& executionSlot, CombinedSlotType targetSlotType, const Slot* executionChildSlot) const override;
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;
@@ -1,84 +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 "Error.h"
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/Contracts/ContractRTTI.h>
#include <ScriptCanvas/Core/Contracts/ConnectionLimitContract.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
void Error::OnInit()
{
{
ExecutionSlotConfiguration slotConfiguration("In", ConnectionType::Input);
AddSlot(slotConfiguration);
}
{
DynamicDataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = "This";
slotConfiguration.m_dynamicDataType = DynamicDataType::Any;
slotConfiguration.SetConnectionType(ConnectionType::Output);
AddSlot(slotConfiguration); // \todo for testing only, we need to ability to arbitrarily connect nodes themeselve to slots (as input to function call or error handling) or directly (as the flow of execution with arrows if easier to read...)
}
{
DataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = "Description";
slotConfiguration.SetConnectionType(ConnectionType::Input);
slotConfiguration.ConfigureDatum(AZStd::move(Datum(AZStd::move(Data::Type::String()), Datum::eOriginality::Copy)));
AddSlot(slotConfiguration);
}
}
void Error::OnInputSignal(const SlotId&)
{
const Datum* input = FindDatum(GetSlotId("Description"));
if (const Data::StringType* desc = input ? input->GetAs<Data::StringType>() : nullptr)
{
SCRIPTCANVAS_REPORT_ERROR((*this), desc->data());
}
else
{
// \todo get a more descriptive default error report
SCRIPTCANVAS_REPORT_ERROR((*this), "Undescribed error");
}
}
void Error::Reflect(AZ::ReflectContext* reflectContext)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<Error, Node>()
->Version(0)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<Error>("Error", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Utilities/Debug")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/ScriptCanvas/Error.png")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
;
}
}
}
}
}
}
@@ -1,34 +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/Node.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
class Error
: public Node
{
public:
AZ_COMPONENT(Error, "{C6928F30-87BA-4FFE-A3C0-B6096C161DD0}", Node);
static void Reflect(AZ::ReflectContext* reflection);
bool IsDeprecated() const override { return true; }
protected:
void OnInit() override;
void OnInputSignal(const SlotId&) override;
};
}
}
}
@@ -1,74 +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 "ErrorHandler.h"
#include <ScriptCanvas/Core/Contracts/ConnectionLimitContract.h>
#include <ScriptCanvas/Core/Contracts/ContractRTTI.h>
#include <ScriptCanvas/Core/PureData.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
const char* ErrorHandler::k_sourceName = "Source";
void ErrorHandler::OnInit()
{
{
ExecutionSlotConfiguration slotConfiguration("Out", ConnectionType::Output);
AddSlot(slotConfiguration);
}
{
DynamicDataSlotConfiguration slotConfiguration;
slotConfiguration.m_name = k_sourceName;
slotConfiguration.SetConnectionType(ConnectionType::Input);
slotConfiguration.m_dynamicDataType = DynamicDataType::Any;
// \todo split node abstractions into executable and !executable
AZStd::vector<AZ::Uuid> forbiddenTypes{ azrtti_typeid<PureData>() };
auto func = [forbiddenTypes]() { return aznew ContractRTTI(forbiddenTypes, ContractRTTI::Flags::Exclusive); };
ContractDescriptor descriptor{ AZStd::move(func) };
slotConfiguration.m_contractDescs.emplace_back(descriptor);
AddSlot(slotConfiguration);
}
}
AZStd::vector<AZStd::pair<Node*, const SlotId>> ErrorHandler::GetSources() const
{
return ModConnectedNodes(*GetSlot(GetSlotId(k_sourceName)));
}
void ErrorHandler::Reflect(AZ::ReflectContext* reflectContext)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<ErrorHandler, Node>()
->Version(0)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<ErrorHandler>("Error Handler", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Utilities/Debug")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/ScriptCanvas/ErrorHandler.png")
;
}
}
}
}
}
}
@@ -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
*
*/
#pragma once
#include <ScriptCanvas/Core/Node.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
class ErrorHandler
: public Node
{
public:
AZ_COMPONENT(ErrorHandler, "{CF23B5A6-827C-4364-9714-EA99612D6CAE}", Node);
static void Reflect(AZ::ReflectContext* reflection);
AZStd::vector<AZStd::pair<Node*, const SlotId>> GetSources() const;
bool IsDeprecated() const override { return true; }
protected:
static const char* k_sourceName;
void OnInit() override;
};
}
}
}
@@ -5,8 +5,6 @@
*
*/
#include <ScriptCanvas/Libraries/Core/ExtractProperty.h>
#include <ScriptCanvas/Libraries/Core/BehaviorContextObjectNode.h>
#include <Libraries/Core/MethodUtility.h>
namespace ScriptCanvas
@@ -58,37 +56,12 @@ namespace ScriptCanvas
AddPropertySlots(dataType);
}
}
Data::Type ExtractProperty::GetSourceSlotDataType() const
{
return m_dataType;
}
void ExtractProperty::OnInputSignal(const SlotId& slotID)
{
if (slotID == GetSlotId(GetInputSlotName()))
{
if (auto input = FindDatum(ExtractPropertyProperty::GetSourceSlotId(this)))
{
for(auto&& propertyAccount : m_propertyAccounts)
{
Slot* propertySlot = GetSlot(propertyAccount.m_propertySlotId);
if (propertySlot && propertyAccount.m_getterFunction)
{
auto outputOutcome = propertyAccount.m_getterFunction(*input);
if (!outputOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), outputOutcome.TakeError().data());
return;
}
PushOutput(outputOutcome.TakeValue(), *propertySlot);
}
}
}
SignalOutput(GetSlotId(GetOutputSlotName()));
}
}
void ExtractProperty::AddPropertySlots(const Data::Type& type)
{
AZStd::unordered_map<AZStd::string, SlotId> versionedInfo;
@@ -108,7 +81,7 @@ namespace ScriptCanvas
{
return AZ::Success(DependencyReport::NativeLibrary(Data::GetName(m_dataType)));
}
PropertyFields ExtractProperty::GetPropertyFields() const
{
PropertyFields propertyFields;
@@ -44,17 +44,13 @@ namespace ScriptCanvas
bool IsOutOfDate(const VersionData& graphVersion) const override;
////
protected:
bool IsPropertySlot(const SlotId& slotId) const;
void OnInit() override;
UpdateResult OnUpdateNode() override;
void OnInputSignal(const SlotId&) override;
void OnSlotDisplayTypeChanged(const SlotId& slotId, const Data::Type& dataType) override;
void AddPropertySlots(const Data::Type& type);
@@ -6,7 +6,6 @@
*/
#include <ScriptCanvas/Libraries/Core/ForEach.h>
#include <ScriptCanvas/Libraries/Core/BehaviorContextObjectNode.h>
#include <ScriptCanvas/Utils/VersionConverters.h>
#include <Libraries/Core/MethodUtility.h>
@@ -10,7 +10,6 @@
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/parallel/mutex.h>
#include <ScriptCanvas/Asset/Functions/ScriptCanvasFunctionAsset.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/SubgraphInterface.h>
#include <ScriptCanvas/Core/Graph.h>
@@ -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,7 +287,8 @@ 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, GetOwningScriptCanvasId(), &GraphRequests::GetVariables);
if (variableMap && baseType.IsValid())
{
@@ -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;
@@ -58,13 +58,12 @@ namespace ScriptCanvas
const Slot* GetVariableOutputSlot() const override;
// Translation
//////////////////////////////////////////////////////////////////////////
protected:
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();
@@ -86,11 +86,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))
@@ -126,7 +121,7 @@ namespace ScriptCanvas
{
return AZ::Failure();
}
DependencyReport dependencyNames;
for (size_t index(0), sentinel = m_method->GetNumArguments(); index < sentinel; ++index)
{
@@ -136,7 +131,7 @@ namespace ScriptCanvas
return AZ::Success(dependencyNames);
}
AZ::Outcome<Grammar::LexicalScope, void> Method::GetFunctionCallLexicalScope(const Slot* /*slot*/) const
{
if (m_method)
@@ -144,7 +139,7 @@ namespace ScriptCanvas
Grammar::LexicalScope lexicalScope;
if (m_method->IsMember()
|| AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, m_method->m_attributes))
|| AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, m_method->m_attributes))
{
lexicalScope.m_type = Grammar::LexicalScopeType::Variable;
}
@@ -165,7 +160,7 @@ namespace ScriptCanvas
if (m_method)
{
if (m_method->IsMember()
|| AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, m_method->m_attributes))
|| AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, m_method->m_attributes))
{
auto name = BehaviorContextUtils::FindExposedMethodName(*m_method, m_class);
if (!name.empty())
@@ -177,7 +172,7 @@ namespace ScriptCanvas
return AZ::Success(m_lookupName);
}
EventType Method::GetFunctionEventType(const Slot*) const
{
return m_eventType;
@@ -211,7 +206,7 @@ namespace ScriptCanvas
m_lookupName = config.m_lookupName ? AZStd::string(*config.m_lookupName) : config.m_method.m_name;
m_methodType = config.m_methodType;
m_eventType = config.m_eventType;
auto isExposableOutcome = IsExposable(config.m_method);
AZ_Warning("ScriptCanvas", isExposableOutcome.IsSuccess(), "BehaviorContext Method %s is no longer exposable to ScriptCanvas: %s", isExposableOutcome.GetError().data());
ConfigureMethod(config.m_method, config.m_class);
@@ -327,7 +322,7 @@ namespace ScriptCanvas
}
}
void Method::InitializeEvent(const NamespacePath&, AZStd::string_view ebusName, AZStd::string_view eventName)
void Method::InitializeEvent(const NamespacePath&, AZStd::string_view ebusName, AZStd::string_view eventName)
{
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
@@ -703,7 +698,7 @@ namespace ScriptCanvas
return TupleType{ method, m_methodType, eventType, bcClass };
}
return TupleType{ nullptr, MethodType::Count, EventType::Count, nullptr};
return TupleType{ nullptr, MethodType::Count, EventType::Count, nullptr };
}
void Method::OnWriteEnd()
@@ -809,13 +804,13 @@ namespace ScriptCanvas
{
editContext->Class<Method>("Method", "Method")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
;
}
}
}
}
}
}
}
}
}
@@ -182,6 +182,6 @@ namespace ScriptCanvas
Method(const Method&) = delete;
};
}
}
}
}
}
}
@@ -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())
@@ -126,7 +27,7 @@ namespace ScriptCanvas
AZStd::unordered_map<size_t, const AZ::BehaviorMethod*> GetTupleGetMethods(const AZ::TypeId& typeId)
{
AZStd::unordered_map<size_t, const AZ::BehaviorMethod*> tupleGetMethodMap;
AZ::BehaviorContext* behaviorContext{};
AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationRequests::GetBehaviorContext);
auto bcClassIterator = behaviorContext->m_typeToClassMap.find(typeId);
@@ -182,4 +83,4 @@ namespace ScriptCanvas
return AZ::Failure();
}
}
}
@@ -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;
@@ -93,7 +93,7 @@ namespace ScriptCanvas
bool isNewSlot = true;
const auto busToolTip = AZStd::string::format("%s (Type: %s)", c_busIdTooltip, m_ebus->m_idParam.m_name);
const AZ::TypeId& busId = m_ebus->m_idParam.m_typeId;
const AZ::TypeId& busId = m_ebus->m_idParam.m_typeId;
SlotId addressSlotId;
@@ -117,8 +117,8 @@ namespace ScriptCanvas
}
else
{
Data::Type busIdType(AZ::BehaviorContextHelper::IsStringParameter(m_ebus->m_idParam) ? Data::Type::String() : Data::FromAZType(busId));
Data::Type busIdType(AZ::BehaviorContextHelper::IsStringParameter(m_ebus->m_idParam) ? Data::Type::String() : Data::FromAZType(busId));
config.ConfigureDatum(AZStd::move(Datum(busIdType, Datum::eOriginality::Original)));
config.m_contractDescs = { { [busIdType]() { return aznew RestrictedTypeContract({ busIdType }); } } };
}
@@ -177,11 +177,6 @@ namespace ScriptCanvas
m_userData.m_methodDefinition = methodDefinition;
AZ_Assert(!event.m_parameters.empty(), "No parameters in event!");
if (!events[eventIndex].m_function)
{
m_handler->InstallGenericHook(events[eventIndex].m_name, &OnEventGenericHook, &m_userData);
}
if (m_eventMap.find(eventId) == m_eventMap.end())
{
m_eventMap[eventId] = ConfigureEbusEntry(*methodDefinition, event, populationMapping);
@@ -272,7 +267,7 @@ namespace ScriptCanvas
SlotId slotId = AddSlot(slotConfiguration, isNewSlot);
AZ_Error("ScriptCanvas", populationMapping.find(argIdentifier) == populationMapping.end(), "Trying to create the same slot twice. Unable to create sane mapping.");
populationMapping[argIdentifier] = slotId;
eBusEventEntry.m_parameterSlotIds.push_back(slotId);
}
@@ -286,7 +281,7 @@ namespace ScriptCanvas
slotConfiguration.m_isLatent = true;
slotConfiguration.m_name = eventID;
slotConfiguration.SetConnectionType(ConnectionType::Output);
slotConfiguration.SetConnectionType(ConnectionType::Output);
slotConfiguration.m_addUniqueSlotByNameAndType = true;
auto remappingIter = m_eventSlotMapping.find(outputSlotId);
@@ -309,12 +304,6 @@ namespace ScriptCanvas
return eBusEventEntry;
}
void ReceiveScriptEvent::OnEventGenericHook(void* userData, const char* eventName, int eventIndex, AZ::BehaviorValueParameter* result, int numParameters, AZ::BehaviorValueParameter* parameters)
{
ReceiveScriptEvent::EventHookUserData* eventHookUserData(reinterpret_cast<ReceiveScriptEvent::EventHookUserData*>(userData));
eventHookUserData->m_handler->OnEvent(eventName, eventIndex, result, numParameters, parameters);
}
void ReceiveScriptEvent::SetAutoConnectToGraphOwner(bool enabled)
{
ScriptCanvas::Slot* connectSlot = ReceiveScriptEventProperty::GetConnectSlot(this);
@@ -325,197 +314,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
{
@@ -727,7 +535,7 @@ namespace ScriptCanvas
{
AZ::BehaviorContext* behaviorContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationBus::Events::GetBehaviorContext);
const auto& ebusIterator = behaviorContext->m_ebuses.find(m_definition.GetName());
if (ebusIterator == behaviorContext->m_ebuses.end())
{
@@ -771,51 +579,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);
@@ -42,7 +42,6 @@ namespace ScriptCanvas
~ReceiveScriptEvent() override;
void OnActivate() override;
void OnPostActivate() override;
void OnDeactivate() override;
const AZ::Data::AssetId GetAssetId() const { return m_scriptEventAssetId; }
@@ -55,11 +54,11 @@ namespace ScriptCanvas
AZStd::optional<size_t> GetEventIndex(AZStd::string eventName) const override;
AZStd::vector<SlotId> GetEventSlotIds() const override;
AZStd::vector<SlotId> GetNonEventSlotIds() const override;
bool IsIDRequired() const;
bool IsEventSlotId(const SlotId& slotId) const;
// NodeVersioning...
bool IsOutOfDate(const VersionData& graphVersion) const override;
UpdateResult OnUpdateNode() override;
@@ -87,16 +86,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 +97,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);
@@ -133,6 +122,6 @@ namespace ScriptCanvas
bool m_connected;
};
}
}
}
}
@@ -59,7 +59,7 @@ namespace ScriptCanvas
if (slot == nullptr)
{
// Handle older versions and improperly updated names
for (auto testUnit : { BaseTimerNode::TimeUnits::Seconds, BaseTimerNode::TimeUnits::Ticks})
for (auto testUnit : { BaseTimerNode::TimeUnits::Seconds, BaseTimerNode::TimeUnits::Ticks })
{
AZStd::string legacyName = BaseTimerNode::s_timeUnitNames[static_cast<int>(testUnit)];
@@ -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>
@@ -23,7 +21,7 @@ namespace ScriptCanvas
{
namespace Internal
{
void ScriptEventEntry::Reflect(AZ::ReflectContext* context)
void ScriptEventEntry::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
@@ -156,7 +154,7 @@ namespace ScriptCanvas
}
m_definition = definition;
}
}
void ScriptEventBase::OnDeactivate()
{
@@ -108,8 +108,6 @@ namespace ScriptCanvas
virtual void Initialize(const AZ::Data::AssetId assetId);
protected:
// AZ::Data::AssetBus::Handler...
@@ -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))
@@ -271,7 +208,7 @@ namespace ScriptCanvas
asset.BlockUntilLoadComplete();
const ScriptEvents::ScriptEvent& definition = asset.Get()->m_definition;
// If no name has been serialized, this is a new node, so initialize it to the Script Event's definition values.
if (m_busId == ScriptCanvas::EBusBusId())
{
@@ -295,7 +232,7 @@ namespace ScriptCanvas
}
NamespacePath emptyNamespacePath;
ScriptEvents::ScriptEventBus::BroadcastResult(m_scriptEvent, &ScriptEvents::ScriptEventRequests::RegisterScriptEvent, assetId, m_version);
AZ::BehaviorMethod* method{};
@@ -362,9 +299,9 @@ namespace ScriptCanvas
ScriptEvents::Method scriptEventMethod;
definition.FindMethod(method->m_name, scriptEventMethod);
size_t argIndex = 0;
// Address slot (BusId)
if (method->HasBusId())
{
@@ -460,7 +397,7 @@ namespace ScriptCanvas
{
return true;
}
RegisterScriptEvent(asset);
if (asset && asset.IsReady())
@@ -491,7 +428,7 @@ namespace ScriptCanvas
{
ConfigureMethod(*method);
InitializeResultSlotId();
return true;
}
}
@@ -591,7 +528,7 @@ namespace ScriptCanvas
if (m_scriptEvent == nullptr)
{
return false;
}
}
m_ebus = m_scriptEvent->GetBehaviorBus();
@@ -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, GetOwningScriptCanvasId(), &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);
@@ -61,13 +61,12 @@ namespace ScriptCanvas
PropertyFields GetPropertyFields() const override;
// Translation
//////////////////////////////////////////////////////////////////////////
protected:
void OnInit() override;
void OnPostActivate() override;
void OnInputSignal(const SlotId&) override;
void OnPostActivate() override;
void AddSlots();
void RemoveSlots();
@@ -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;
};
}
}
@@ -1,47 +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/NativeDatumNode.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
class String
: public NativeDatumNode<String, Data::StringType>
{
public:
using ParentType = NativeDatumNode<String, Data::StringType>;
AZ_COMPONENT(String, "{9C9B9D96-1838-4493-A14D-40C77B4DB5DD}", ParentType);
static void Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<String, PureData>()
->Version(3)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<String>("String", "Holds a string value")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/ScriptCanvas/String.png")
;
}
}
}
};
}
}
}
@@ -18,17 +18,6 @@ namespace ScriptCanvas
const char* UnaryOperator::k_valueName = "Value";
const char* UnaryOperator::k_resultName = "Result";
Datum UnaryOperator::Evaluate([[maybe_unused]] const Datum& value)
{
AZ_Assert(false, "Evaluate must be overridden");
return Datum();
};
void UnaryOperator::OnInputSignal([[maybe_unused]] const SlotId& slot)
{
AZ_Assert(false, "OnInputSignal must be overridden");
}
void UnaryOperator::ConfigureSlots()
{
{
@@ -68,25 +57,6 @@ namespace ScriptCanvas
{
}
void UnaryExpression::OnInputSignal(const SlotId&)
{
const Datum output = Evaluate(*FindDatumByIndex(k_datumIndex));
if (auto slot = GetSlot(GetOutputSlotId()))
{
PushOutput(output, *slot);
}
const bool* value = output.GetAs<bool>();
if (value && *value)
{
SignalOutput(GetSlotId(k_onTrue));
}
else
{
SignalOutput(GetSlotId(k_onFalse));
}
}
void UnaryExpression::ConfigureSlots()
{
{
@@ -10,7 +10,6 @@
#include <AzCore/std/typetraits/remove_cv.h>
#include <AzCore/std/typetraits/function_traits.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Core/PureData.h>
#include <ScriptCanvas/Core/Datum.h>
namespace ScriptCanvas
@@ -32,8 +31,6 @@ namespace ScriptCanvas
static const char* k_onTrue;
static const char* k_onFalse;
protected:
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot&, CombinedSlotType targetSlotType, const Slot*) const override
{
@@ -45,15 +42,7 @@ namespace ScriptCanvas
void ConfigureSlots() override;
// must be overridden with the binary operations
virtual Datum Evaluate(const Datum& value);
// Triggered by the execution signal
void OnInputSignal(const SlotId& slot) override;
SlotId GetOutputSlotId() const;
};
class UnaryExpression : public UnaryOperator
@@ -67,11 +56,7 @@ namespace ScriptCanvas
void ConfigureSlots() override;
void OnInputSignal(const SlotId& slot) override;
virtual void InitializeUnaryExpression();
};
}
}
@@ -11,8 +11,6 @@
namespace ScriptCanvas
{
static bool OldEntityIdIsValidNodeVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootNodeElement)
{
int nodeElementIndex = rootNodeElement.FindElement(AZ_CRC("BaseClass1", 0xd4925735));
@@ -64,7 +62,7 @@ namespace ScriptCanvas
const AZ::TypeId nodeFunctionGenericMultiReturnTemplateTypeId("{DC5B1799-6C5B-4190-8D90-EF0C2D1BCE4E}");
const AZ::TypeId oldEntityIdIsValidFuncSignatureTypeId = azrtti_typeid<bool(*)(AZ::EntityId)>();
const AZ::TypeId oldEntityIdIsValidTypeId("{7CEC53AE-E12B-4738-B542-4587B8B95DC2}");
// Aggregate NodeFunctionGenericMultiReturn<bool(*)(AZ::EntityId), OldIsValidTraits> typeid
// NOTE: Aggregation order addition is not commutative and must be in the added last to first: (FirstUuid + ( SecondUuid + (ThirdUuid + ... + (NthUuid))
const AZ::TypeId oldIsValidNodeAggregateTypeId = nodeFunctionGenericMultiReturnTemplateTypeId + (oldEntityIdIsValidFuncSignatureTypeId + oldEntityIdIsValidTypeId);
@@ -72,8 +70,6 @@ namespace ScriptCanvas
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflection))
{
using namespace ScriptCanvas::Nodes::Entity;
SCRIPT_CANVAS_GENERICS_TO_VM(EntityIDNodes::Registrar, EntityID, behaviorContext, EntityIDNodes::k_categoryName);
SCRIPT_CANVAS_GENERICS_TO_VM(EntityNodes::Registrar, Entity, behaviorContext, EntityNodes::k_categoryName);
}
@@ -82,25 +78,15 @@ namespace ScriptCanvas
void Entity::InitNodeRegistry(NodeRegistry& nodeRegistry)
{
using namespace ScriptCanvas::Nodes::Entity;
AddNodeToRegistry<Entity, Rotate>(nodeRegistry);
AddNodeToRegistry<Entity, EntityID>(nodeRegistry);
AddNodeToRegistry<Entity, EntityRef>(nodeRegistry);
EntityIDNodes::Registrar::AddToRegistry<Entity>(nodeRegistry);
EntityNodes::Registrar::AddToRegistry<Entity>(nodeRegistry);
}
AZStd::vector<AZ::ComponentDescriptor*> Entity::GetComponentDescriptors()
{
AZStd::vector<AZ::ComponentDescriptor*> descriptors = {
ScriptCanvas::Nodes::Entity::Rotate::CreateDescriptor(),
ScriptCanvas::Nodes::Entity::EntityID::CreateDescriptor(),
ScriptCanvas::Nodes::Entity::EntityRef::CreateDescriptor()
};
AZStd::vector<AZ::ComponentDescriptor*> descriptors;
EntityIDNodes::Registrar::AddDescriptors(descriptors);
EntityNodes::Registrar::AddDescriptors(descriptors);
return descriptors;
}
}
@@ -10,9 +10,6 @@
// This header is only meant to include the nodes and should not contain
// shared code
#include "Rotate.h"
#include "RotateMethod.h"
#include "EntityIDNode.h"
#include "EntityIDNodes.h"
#include "EntityRef.h"
#include "EntityNodes.h"
@@ -1,47 +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/NativeDatumNode.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Entity
{
class EntityID
: public NativeDatumNode<EntityID, Data::EntityIDType>
{
public:
using ParentType = NativeDatumNode<EntityID, Data::EntityIDType>;
AZ_COMPONENT(EntityID, "{37F26070-F29B-412A-9228-86D8D10F3C32}", ParentType);
static void Reflect(AZ::ReflectContext* reflection)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
{
serializeContext->Class<EntityID, PureData>()
->Version(0)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<EntityID>("EntityID", "Stores a reference to an entity")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/ScriptCanvas/EntityID.png")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
;
}
}
}
};
}
}
}
@@ -1,79 +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/Libraries/Entity/Entity.h>
#include <ScriptCanvas/Core/NativeDatumNode.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Entity
{
class EntityRef
: public NativeDatumNode<EntityRef, Data::EntityIDType>
{
public:
using ParentType = NativeDatumNode<EntityRef, Data::EntityIDType>;
AZ_COMPONENT(EntityRef, "{0EE5782F-B241-4127-AE53-E6746B00447F}", ParentType);
static void Reflect(AZ::ReflectContext* reflection)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
{
serializeContext->Class<EntityRef, PureData>()
->Version(2)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
// EntityRef node is special in that it's only created when we drag in an entity from the main scene.
// And is unmodifiable(essentially an external constant). As such, we hide it from the node palette.
editContext->Class<EntityRef>("EntityID", "Stores a reference to an entity")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/ScriptCanvas/EntityRef.png")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
;
}
}
}
AZ_INLINE void SetEntityRef(const AZ::EntityId& id)
{
ModifiableDatumView datumView;
FindModifiableDatumView(GetSlotId(k_setThis), datumView);
if (datumView.IsValid())
{
// only called on edit time creation, so no need to push out the data, consider cutting this function if possible
datumView.SetAs(id);
OnOutputChanged((*datumView.GetDatum()));
}
}
AZ_INLINE AZ::EntityId GetEntityRef() const
{
AZ::EntityId retVal;
if (auto input = FindDatum(GetSlotId(k_setThis)))
{
const AZ::EntityId* inputId = input->GetAs<AZ::EntityId>();
if (inputId)
{
retVal = (*inputId);
}
}
return retVal;
}
};
}
}
}
@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScriptCanvas Include="Include/ScriptCanvas/Libraries/Entity/Rotate.h" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Class Name="Rotate"
QualifiedName="ScriptCanvas::Nodes::Entity::Rotate"
PreferredClassName="Rotate"
Uuid="{6F802B53-E726-430D-9F41-63CFC783F91D}"
Base="ScriptCanvas::Node"
Category="Entity/Transform"
Version="4"
Deprecated="true"
EditAttributes="AZ::Edit::Attributes::CategoryStyle@.method;ScriptCanvas::Attributes::Node::TitlePaletteOverride@MethodNodeTitlePalette"
GeneratePropertyFriend="True"
Description="Rotates the given entity by the specified amount.">
<In Name="In" Description=""/>
<Out Name="Out" Description=""/>
<Property Name="Entity"
Description="The entity to apply the rotation on."
Type="AZ::EntityId"
DefaultValue="ScriptCanvas::GraphOwnerId"
IsInput="True"
IsOutput="False" />
<Property Name="Euler Angles"
Description="Euler angles, Pitch/Yaw/Roll."
Type="AZ::Vector3"
IsInput="True"
IsOutput="False" />
</Class>
</ScriptCanvas>
@@ -1,56 +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 <Libraries/Entity/Rotate.h>
#include <ScriptCanvas/Execution/ErrorBus.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/Transform.h>
#include <ScriptCanvas/Core/GraphBus.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Entity
{
void Rotate::OnInputSignal(const SlotId&)
{
AZ::EntityId targetEntity = RotateProperty::GetEntity(this);
if (!targetEntity.IsValid())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Invalid entity specified");
return;
}
AZ::Entity* entity = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, targetEntity);
if (entity)
{
AZ::Vector3 angles = AZ::Vector3::CreateZero();
if (entity->GetState() == AZ::Entity::State::Active)
{
angles = RotateProperty::GetEulerAngles(this);
AZ::Quaternion rotation = AZ::ConvertEulerDegreesToQuaternion(angles);
AZ::Transform currentTransform = AZ::Transform::CreateIdentity();
AZ::TransformBus::EventResult(currentTransform, targetEntity, &AZ::TransformInterface::GetWorldTM);
currentTransform.SetRotation((rotation * currentTransform.GetRotation().GetNormalized()));
AZ::TransformBus::Event(targetEntity, &AZ::TransformInterface::SetWorldTM, currentTransform);
}
}
SignalOutput(RotateProperty::GetOutSlotId(this));
}
}
}
}
@@ -1,44 +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/Node.h>
#include <AzCore/Math/Vector3.h>
#include <Include/ScriptCanvas/Libraries/Entity/Rotate.generated.h>
// LY-103055 Temporary workaround to fix compile error when building Android NDK 19 and above due to AzCodeGenerator
// not receiving the correct clang system includes
namespace AZ
{
class EntityId;
class Vector3;
}
namespace ScriptCanvas
{
namespace Nodes
{
namespace Entity
{
//! Deprecated: see Entity Transform class' reflection of method "Rotate"
class Rotate
: public Node
{
public:
SCRIPTCANVAS_NODE(Rotate);
void OnInputSignal(const SlotId&) override;
};
}
}
}
@@ -12,6 +12,21 @@
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/containers/unordered_map.h>
#define REFLECT_MATH_LIBRARY_TYPE(MathType, Guid)\
struct MathType\
{\
AZ_TYPE_INFO(MathType, Guid);\
static void Reflect(AZ::ReflectContext* reflection)\
{\
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))\
{\
serializeContext->Class<MathType>()\
->Version(0)\
;\
}\
}\
};
namespace AZ
{
class ReflectContext;
@@ -45,7 +60,7 @@ namespace ScriptCanvas
virtual ~LibraryDefinition() = default;
static const NodeRegistry::NodeList GetNodes(const AZ::Uuid& libraryType)
{
{
NodeRegistry& registry = (*GetNodeRegistry());
const auto& libraryIterator = registry.m_nodeMap.find(libraryType);
if (libraryIterator != registry.m_nodeMap.end())
@@ -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
{
{
@@ -28,7 +28,7 @@ namespace ScriptCanvas
return AZ::Success(DependencyReport{});
}
bool Any::IsNoOp() const
bool Any::IsNoOp() const
{
return true;
}
@@ -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)
{
@@ -30,7 +30,7 @@ namespace ScriptCanvas
Current
};
public:
SCRIPTCANVAS_NODE(Any);
@@ -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;
@@ -56,10 +54,8 @@ namespace ScriptCanvas
/// Translation
bool IsNoOp() const override;
AZ::Outcome<DependencyReport, void> GetDependencies() const override;
protected:
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot&, CombinedSlotType targetSlotType, const Slot*) 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();
};
@@ -1,48 +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/NativeDatumNode.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Logic
{
class Boolean
: public NativeDatumNode<Boolean, bool>
{
public:
using ParentType = NativeDatumNode<Boolean, bool>;
AZ_COMPONENT(Boolean, "{263E8CAE-9F20-4198-A937-14761A46D996}", ParentType);
static void Reflect(AZ::ReflectContext* reflection)
{
ParentType::Reflect(reflection);
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
{
serializeContext->Class<Boolean, ParentType>()
->Version(4)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<Boolean>("Boolean", "A boolean value (true/false)")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/ScriptCanvas/Boolean.png")
;
}
}
}
};
}
}
}
@@ -27,11 +27,11 @@ namespace ScriptCanvas
SCRIPTCANVAS_NODE(Break);
Break() = default;
Break() = default;
AZ::Outcome<DependencyReport, void> GetDependencies() const override;
};
}
@@ -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:
@@ -58,7 +54,7 @@ namespace ScriptCanvas
void FixupStateNames();
int m_numOutputs;
size_t m_executionSlot;
AZStd::vector< SlotId > m_orderedOutputSlots;
@@ -17,29 +17,12 @@ namespace ScriptCanvas
{
Gate::Gate()
: Node()
, m_condition(false)
{}
AZ::Outcome<DependencyReport, void> Gate::GetDependencies() const
{
return AZ::Success(DependencyReport{});
}
void Gate::OnInputSignal(const SlotId&)
{
SlotId trueSlot = GateProperty::GetTrueSlotId(this);
SlotId falseSlot = GateProperty::GetFalseSlotId(this);
m_condition = GateProperty::GetCondition(this);
if (m_condition)
{
SignalOutput(trueSlot);
}
else
{
SignalOutput(falseSlot);
}
}
}
}
}
@@ -9,7 +9,6 @@
#include <ScriptCanvas/Core/Core.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Libraries/Logic/Boolean.h>
#include <Include/ScriptCanvas/Libraries/Logic/Gate.generated.h>
@@ -24,7 +23,6 @@ namespace ScriptCanvas
: public Node
{
public:
SCRIPTCANVAS_NODE(Gate);
Gate();
@@ -36,22 +34,11 @@ namespace ScriptCanvas
bool IsIfBranch() const override { return true; }
protected:
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& /*executionSlot*/, CombinedSlotType targetSlotType, const Slot* /*executionChildSlot*/) const override
{
return AZ::Success(GetSlotsByType(targetSlotType));
}
//////////////////////////////////////////////////////////////////////////
void OnInputSignal(const SlotId&) override;
private:
bool m_condition;
};
}
}
@@ -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;
};
}
}
@@ -39,7 +39,7 @@ namespace ScriptCanvas
{
{
auto func = []() { return aznew IsReferenceTypeContract(); };
ContractDescriptor descriptor{ AZStd::move(func) };
ContractDescriptor descriptor{ AZStd::move(func) };
DynamicDataSlotConfiguration slotConfiguration;
@@ -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;
};
}
}
@@ -43,7 +43,6 @@ namespace ScriptCanvas
using namespace ScriptCanvas::Nodes::Logic;
AddNodeToRegistry<Logic, And>(nodeRegistry);
AddNodeToRegistry<Logic, Any>(nodeRegistry);
AddNodeToRegistry<Logic, Boolean>(nodeRegistry);
AddNodeToRegistry<Logic, Break>(nodeRegistry);
AddNodeToRegistry<Logic, Cycle>(nodeRegistry);
AddNodeToRegistry<Logic, Gate>(nodeRegistry);
@@ -54,7 +53,7 @@ namespace ScriptCanvas
AddNodeToRegistry<Logic, Once>(nodeRegistry);
AddNodeToRegistry<Logic, Or>(nodeRegistry);
AddNodeToRegistry<Logic, OrderedSequencer>(nodeRegistry);
AddNodeToRegistry<Logic, Sequencer>(nodeRegistry);
AddNodeToRegistry<Logic, Sequencer>(nodeRegistry);
AddNodeToRegistry<Logic, TargetedSequencer>(nodeRegistry);
AddNodeToRegistry<Logic, WeightedRandomSequencer>(nodeRegistry);
AddNodeToRegistry<Logic, While>(nodeRegistry);
@@ -65,7 +64,6 @@ namespace ScriptCanvas
return AZStd::vector<AZ::ComponentDescriptor*>({
ScriptCanvas::Nodes::Logic::And::CreateDescriptor(),
ScriptCanvas::Nodes::Logic::Any::CreateDescriptor(),
ScriptCanvas::Nodes::Logic::Boolean::CreateDescriptor(),
ScriptCanvas::Nodes::Logic::Break::CreateDescriptor(),
ScriptCanvas::Nodes::Logic::Cycle::CreateDescriptor(),
ScriptCanvas::Nodes::Logic::Gate::CreateDescriptor(),
@@ -80,7 +78,7 @@ namespace ScriptCanvas
ScriptCanvas::Nodes::Logic::TargetedSequencer::CreateDescriptor(),
ScriptCanvas::Nodes::Logic::WeightedRandomSequencer::CreateDescriptor(),
ScriptCanvas::Nodes::Logic::While::CreateDescriptor(),
});
});
}
}
}
@@ -12,7 +12,6 @@
#include "And.h"
#include "Any.h"
#include "Boolean.h"
#include "Break.h"
#include "Cycle.h"
#include "Gate.h"

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