The Great ScriptCanvas Purge, Part IV

Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com>
This commit is contained in:
chcurran
2021-07-06 13:13:16 -07:00
parent fa7accf2dc
commit 360236b89e
173 changed files with 131 additions and 6154 deletions
@@ -1,145 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Asset/AssetCommon.h>
#include <ScriptCanvas/Asset/AssetDescription.h>
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
#include <AzCore/std/containers/vector.h>
namespace AZ
{
class Entity;
}
namespace ScriptCanvasEditor
{
class ScriptCanvasFunctionAsset;
class Graph;
class ScriptCanvasFunctionDescription : public ScriptCanvas::AssetDescription
{
public:
AZ_TYPE_INFO(ScriptCanvasFunctionDescription, "{B53569F6-8408-40FC-9A72-ED873BEF162E}");
ScriptCanvasFunctionDescription()
: AssetDescription(
azrtti_typeid<ScriptCanvasEditor::ScriptCanvasFunctionAsset>(),
"Script Canvas Function",
"Script Canvas Function Graph Asset",
"@devassets@/scriptcanvas/functions",
".scriptcanvas_fn",
"Script Canvas Function",
"Untitled-Function-%i",
"Script Canvas Function Files (*.scriptcanvas_fn)",
"Script Canvas Function",
"Script Canvas Function",
"Icons/ScriptCanvas/Viewport/ScriptCanvas_Function.png",
AZ::Color(0.192f, 0.149f, 0.392f, 1.0f),
true
)
{}
};
// TODO-LS: move these to their own file
class ScriptCanvasDataRequests : public AZ::ComponentBus
{
public:
virtual void SetPrettyName(const char* name) = 0;
virtual AZStd::string GetPrettyName() = 0;
};
using ScriptCanvasDataRequestBus = AZ::EBus<ScriptCanvasDataRequests>;
class ScriptCanvasFunctionDataComponent
: public AZ::Component
, ScriptCanvasDataRequestBus::MultiHandler
{
public:
AZ_COMPONENT(ScriptCanvasFunctionDataComponent, "{440BB6DC-4E70-4304-A926-252925F77433}");
void Activate() override
{
AZ::EntityId entityId = GetEntityId();
ScriptCanvasDataRequestBus::MultiHandler::BusConnect(entityId);
}
void Deactivate() override
{
ScriptCanvasDataRequestBus::MultiHandler::BusDisconnect();
AZ::EntityId entityId = GetEntityId();
}
void SetPrettyName(const char* name) override
{
m_assetPrettyName = name;
}
AZStd::string GetPrettyName() override
{
return m_assetPrettyName;
}
static void Reflect(AZ::ReflectContext* reflectContext)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<ScriptCanvasFunctionDataComponent, AZ::Component>()
->Version(2)
->Field("m_assetPrettyName", &ScriptCanvasFunctionDataComponent::m_assetPrettyName)
->Field("m_version", &ScriptCanvasFunctionDataComponent::m_functionDataComponentVersion)
;
}
}
size_t m_functionDataComponentVersion = 0;
AZStd::string m_assetPrettyName;
};
class ScriptCanvasFunctionAsset
: public ScriptCanvas::ScriptCanvasAssetBase
{
public:
AZ_RTTI(ScriptCanvasFunctionAsset, "{ED078D3C-938D-41F8-A5F6-CC04311ECF4F}", ScriptCanvasAssetBase);
AZ_CLASS_ALLOCATOR(ScriptCanvasFunctionAsset, AZ::SystemAllocator, 0);
ScriptCanvasFunctionAsset(const AZ::Data::AssetId& assetId = AZ::Data::AssetId(AZ::Uuid::CreateRandom()), AZ::Data::AssetData::AssetStatus status = AZ::Data::AssetData::AssetStatus::NotLoaded)
: ScriptCanvasAssetBase(assetId, status)
{
m_data = aznew ScriptCanvas::ScriptCanvasData();
}
~ScriptCanvasFunctionAsset() override
{}
ScriptCanvas::AssetDescription GetAssetDescription() const override
{
return ScriptCanvasFunctionDescription();
}
using Description = ScriptCanvasFunctionDescription;
ScriptCanvasFunctionDataComponent* m_cachedComponent = nullptr;
ScriptCanvasFunctionDataComponent* GetFunctionData()
{
if (m_cachedComponent == nullptr)
{
m_cachedComponent = GetScriptCanvasEntity()->FindComponent<ScriptCanvasFunctionDataComponent>();
}
return m_cachedComponent;
}
};
}
@@ -122,8 +122,6 @@ namespace ScriptCanvas
{
const auto& scriptCanvasId = GetScriptCanvasId();
GraphRequestBus::Handler::BusConnect(scriptCanvasId);
RuntimeRequestBus::Handler::BusConnect(scriptCanvasId);
ValidationRequestBus::Handler::BusConnect(scriptCanvasId);
for (auto& nodeEntity : m_graphData.m_nodes)
@@ -142,6 +140,7 @@ namespace ScriptCanvas
}
m_graphData.BuildEndpointMap();
for (auto& connectionEntity : m_graphData.m_connections)
{
if (connectionEntity)
@@ -19,7 +19,6 @@
#include <ScriptCanvas/Debugger/Bus.h>
#include <ScriptCanvas/Execution/ErrorBus.h>
#include <ScriptCanvas/Execution/ExecutionContext.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Debugger/StatusBus.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ValidationEvent.h>
@@ -35,7 +34,6 @@ namespace ScriptCanvas
class Graph
: public AZ::Component
, protected GraphRequestBus::Handler
, protected RuntimeRequestBus::Handler
, protected StatusRequestBus::Handler
, private AZ::EntityBus::Handler
, private ValidationRequestBus::Handler
@@ -174,14 +172,12 @@ namespace ScriptCanvas
void RefreshConnectionValidity(bool warnOnRemoval = false);
//// RuntimeRequestBus::Handler
AZ::Data::AssetId GetAssetId() const override { return AZ::Data::AssetId(); }
GraphIdentifier GetGraphIdentifier() const override { return GraphIdentifier(GetAssetId(), 0); }
AZStd::string GetAssetName() const override { return ""; }
AZ::EntityId GetRuntimeEntityId() const override { return GetEntity() ? GetEntityId() : AZ::EntityId(); }
VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeId) const override { return runtimeId; }
VariableId FindRuntimeVariableIdByAssetVariableId(VariableId assetId) const override { return assetId; }
AZ::EntityId FindAssetNodeIdByRuntimeNodeId(AZ::EntityId editorNode) const override { return editorNode; }
AZ::EntityId FindRuntimeNodeIdByAssetNodeId(AZ::EntityId runtimeNode) const override { return runtimeNode; }
@@ -190,8 +186,8 @@ namespace ScriptCanvas
const GraphVariableMapping* GetVariables() const override;
GraphVariable* FindVariable(AZStd::string_view propName) override;
GraphVariable* FindVariableById(const VariableId& variableId) override;
Data::Type GetVariableType(const VariableId& variableId) const override;
AZStd::string_view GetVariableName(const VariableId& variableId) const override;
Data::Type GetVariableType(const VariableId& variableId) const;
AZStd::string_view GetVariableName(const VariableId& variableId) const;
bool IsGraphObserved() const override;
void SetIsGraphObserved(bool isObserved) override;
@@ -11,6 +11,7 @@
#include "Endpoint.h"
#include <ScriptCanvas/Variable/VariableCore.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/vector.h>
@@ -23,6 +24,8 @@ namespace ScriptCanvas
class Graph;
class Slot;
using EndpointMapConstIterator = AZStd::unordered_multimap<Endpoint, Endpoint>::const_iterator;
//! These are public graph requests
class GraphRequests : public AZ::EBusTraits
{
@@ -104,8 +107,49 @@ namespace ScriptCanvas
virtual void SetIsGraphObserved(bool observed) = 0;
virtual bool IsGraphObserved() const = 0;
};
virtual VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeId) const = 0;
virtual AZ::EntityId FindAssetNodeIdByRuntimeNodeId(AZ::EntityId editorNode) const = 0;
virtual AZ::Data::AssetId GetAssetId() const = 0;
virtual GraphIdentifier GetGraphIdentifier() const = 0;
virtual AZStd::string GetAssetName() const = 0;
//! Looks up the nodeId within the bus handler
virtual Node* FindNode(AZ::EntityId nodeId) const = 0;
virtual AZ::EntityId FindRuntimeNodeIdByAssetNodeId(AZ::EntityId runtimeNode) const = 0;
//! Returns the entity id of the execution component
virtual AZ::EntityId GetRuntimeEntityId() const = 0;
virtual AZStd::pair< EndpointMapConstIterator, EndpointMapConstIterator > GetConnectedEndpointIterators(const Endpoint& endpoint) const = 0;
//! Returns whether the given endpoint has any connections
virtual bool IsEndpointConnected(const Endpoint& endpoint) const = 0;
//! Retrieves VariableData structure which manages variable data for the execution component
virtual VariableData* GetVariableData() = 0;
virtual const VariableData* GetVariableDataConst() const = 0;
//! Retrieves a map of variable id to variable name and variable datums pair
virtual const GraphVariableMapping* GetVariables() const = 0;
//! Searches for a variable with the specified name
//! returns pointer to the first variable with the specified name or nullptr
virtual GraphVariable* FindVariable(AZStd::string_view varName) = 0;
//! Searches for a variable by VariableId
//! returns a pair of <variable datum pointer, variable name> with the supplied id
//! The variable datum pointer is non-null if the variable has been found
virtual GraphVariable* FindVariableById(const VariableId& variableId) = 0;
virtual AZ::Data::AssetType GetAssetType() const = 0;
};
using GraphRequestBus = AZ::EBus<GraphRequests>;
class GraphNotifications : public AZ::EBusTraits
@@ -487,23 +487,16 @@ namespace ScriptCanvas
void Node::Activate()
{
SignalBus::Handler::BusConnect(GetEntityId());
SetRuntimeBus(RuntimeRequestBus::FindFirstHandler(m_scriptCanvasId));
AZ_Assert(m_runtimeBus, "Invalid m_executionUniqueId given for RuntimeRequestBus");
m_graphRequestBus = GraphRequestBus::FindFirstHandler(m_scriptCanvasId);
AZ_Assert(m_graphRequestBus, "Invalid m_executionUniqueId given for RuntimeRequestBus");
OnActivate();
MarkDefaultableInput();
}
void Node::Deactivate()
{
OnDeactivate();
SignalBus::Handler::BusDisconnect();
SetRuntimeBus(RuntimeRequestBus::FindFirstHandler(m_scriptCanvasId));
m_graphRequestBus = GraphRequestBus::FindFirstHandler(m_scriptCanvasId);
}
void Node::PostActivate()
@@ -737,7 +730,7 @@ namespace ScriptCanvas
bool Node::IsInEventHandlingScope(const ID& possibleEventHandler) const
{
Node* node = m_runtimeBus->FindNode(possibleEventHandler);
Node* node = m_graphRequestBus->FindNode(possibleEventHandler);
if (auto eventHandler = azrtti_cast<ScriptCanvas::Nodes::Core::EBusEventHandler*>(node))
{
@@ -844,7 +837,7 @@ namespace ScriptCanvas
GraphVariable* Node::FindGraphVariable(const VariableId& variableId) const
{
return m_runtimeBus->FindVariableById(variableId);
return m_graphRequestBus->FindVariableById(variableId);
}
void Node::OnSlotConvertedToValue(const SlotId& slotId)
@@ -1598,24 +1591,6 @@ namespace ScriptCanvas
NodeNotificationsBus::Event(GetEntityId(), &NodeNotifications::OnSlotDisplayTypeChanged, slotId, dataType);
}
void Node::SignalInput(const SlotId& slotId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas);
SC_EXECUTION_TRACE_SIGNAL_INPUT((*this), (InputSignal(CreateNodeInputSignal(slotId))));
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::%s::SignalInput", GetNodeName().c_str());
OnInputSignal(slotId);
}
}
void Node::SignalOutput(const SlotId& slotId, ExecuteMode mode)
{
AZ_UNUSED(slotId);
AZ_UNUSED(mode);
}
AZ::Outcome<void, AZStd::string> Node::SlotAcceptsType(const SlotId& slotID, const Data::Type& type) const
{
if (auto slot = GetSlot(slotID))
@@ -1914,7 +1889,7 @@ namespace ScriptCanvas
if (slot.GetDescriptor() == slotDescriptor
&& (allowLatentSlots || !slot.IsLatent()))
{
AZStd::vector<Endpoint> connectedEndpoints = m_runtimeBus->GetConnectedEndpoints(Endpoint{ GetEntityId(), slot.GetId() });
AZStd::vector<Endpoint> connectedEndpoints = m_graphRequestBus->GetConnectedEndpoints(Endpoint{ GetEntityId(), slot.GetId() });
endpoints.insert(endpoints.end(), connectedEndpoints.begin(), connectedEndpoints.end());
}
}
@@ -2339,9 +2314,7 @@ namespace ScriptCanvas
void Node::SetOwningScriptCanvasId(ScriptCanvasId scriptCanvasId)
{
m_scriptCanvasId = scriptCanvasId;
SetRuntimeBus(RuntimeRequestBus::FindFirstHandler(m_scriptCanvasId));
m_graphRequestBus = GraphRequestBus::FindFirstHandler(m_scriptCanvasId);
OnGraphSet();
}
@@ -2426,7 +2399,7 @@ namespace ScriptCanvas
AZ::EntityId Node::GetGraphEntityId() const
{
return m_runtimeBus->GetRuntimeEntityId();
return m_graphRequestBus->GetRuntimeEntityId();
}
NodePtrConstList Node::FindConnectedNodesByDescriptor(const SlotDescriptor& slotDescriptor, bool followLatentConnections) const
@@ -2437,7 +2410,7 @@ namespace ScriptCanvas
for (const auto& endpoint : GetAllEndpointsByDescriptor(slotDescriptor, followLatentConnections))
{
Node* connectedNode = m_runtimeBus->FindNode(endpoint.GetNodeId());
Node* connectedNode = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (connectedNode)
{
@@ -2456,7 +2429,7 @@ namespace ScriptCanvas
for (const auto& endpoint : GetAllEndpointsByDescriptor(slotDescriptor, followLatentConnections))
{
Node* connectedNode = m_runtimeBus->FindNode(endpoint.GetNodeId());
Node* connectedNode = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (connectedNode)
{
@@ -2469,7 +2442,7 @@ namespace ScriptCanvas
AZ::Data::AssetId Node::GetGraphAssetId() const
{
return m_runtimeBus->GetAssetId();
return m_graphRequestBus->GetAssetId();
}
AZStd::string Node::GetGraphAssetName() const
@@ -2482,7 +2455,7 @@ namespace ScriptCanvas
GraphIdentifier Node::GetGraphIdentifier() const
{
return m_runtimeBus->GetGraphIdentifier();
return m_graphRequestBus->GetGraphIdentifier();
}
bool Node::IsSanityCheckRequired() const
@@ -2652,7 +2625,7 @@ namespace ScriptCanvas
return;
}
auto node = m_runtimeBus->FindNode(endpoint.GetNodeId());
auto node = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (node)
{
@@ -2840,7 +2813,7 @@ namespace ScriptCanvas
bool Node::IsConnected(const Slot& slot) const
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Node::IsConnected");
return slot.IsVariableReference() || m_runtimeBus->IsEndpointConnected(slot.GetEndpoint());
return slot.IsVariableReference() || m_graphRequestBus->IsEndpointConnected(slot.GetEndpoint());
}
bool Node::IsConnected(const SlotId& slotId) const
@@ -2880,7 +2853,7 @@ namespace ScriptCanvas
bool Node::IsActivated() const
{
return m_runtimeBus;
return m_graphRequestBus;
}
EndpointsResolved Node::GetConnectedNodes(const Slot& slot) const
@@ -2889,17 +2862,17 @@ namespace ScriptCanvas
EndpointsResolved connectedNodes;
auto endpointIters = m_runtimeBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
auto endpointIters = m_graphRequestBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
for (auto endpointIter = endpointIters.first; endpointIter != endpointIters.second; ++endpointIter)
{
const Endpoint& endpoint = endpointIter->second;
auto node = m_runtimeBus->FindNode(endpoint.GetNodeId());
auto node = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (node == nullptr)
{
AZStd::string assetName = m_runtimeBus->GetAssetName();
AZ::EntityId assetNodeId = m_runtimeBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZStd::string assetName = m_graphRequestBus->GetAssetName();
AZ::EntityId assetNodeId = m_graphRequestBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZ_Warning("Script Canvas", false, "Unable to find node with id (id: %s) in the graph '%s'. Most likely the node was serialized with a type that is no longer reflected",
assetNodeId.ToString().data(), assetName.data());
@@ -2913,8 +2886,8 @@ namespace ScriptCanvas
auto endpointSlot = node->GetSlot(endpoint.GetSlotId());
if (!endpointSlot)
{
AZStd::string assetName = m_runtimeBus->GetAssetName();
AZ::EntityId assetNodeId = m_runtimeBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZStd::string assetName = m_graphRequestBus->GetAssetName();
AZ::EntityId assetNodeId = m_graphRequestBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZ_Warning("Script Canvas", false, "Endpoint was missing slot. id (id: %s) in the graph '%s'.",
assetNodeId.ToString().data(), assetName.data());
@@ -2937,18 +2910,18 @@ namespace ScriptCanvas
void Node::ModConnectedNodes(const Slot& slot, AZStd::vector<AZStd::pair<Node*, const SlotId>>& connectedNodes) const
{
auto endpointIters = m_runtimeBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
auto endpointIters = m_graphRequestBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
for (auto endpointIter = endpointIters.first; endpointIter != endpointIters.second; ++endpointIter)
{
const Endpoint& endpoint = endpointIter->second;
auto node = m_runtimeBus->FindNode(endpoint.GetNodeId());
auto node = m_graphRequestBus->FindNode(endpoint.GetNodeId());
if (node == nullptr)
{
AZStd::string assetName = m_runtimeBus->GetAssetName();
AZ::EntityId assetNodeId = m_runtimeBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZStd::string assetName = m_graphRequestBus->GetAssetName();
AZ::EntityId assetNodeId = m_graphRequestBus->FindAssetNodeIdByRuntimeNodeId(endpoint.GetNodeId());
AZ_Error("Script Canvas", false, "Unable to find node with id (id: %s) in the graph '%s'. Most likely the node was serialized with a type that is no longer reflected",
assetNodeId.ToString().data(), assetName.data());
@@ -2961,41 +2934,7 @@ namespace ScriptCanvas
bool Node::HasConnectedNodes(const Slot& slot) const
{
return m_runtimeBus->IsEndpointConnected(Endpoint{ GetEntityId(), slot.GetId() });
}
void Node::OnInputChanged(Node& node, const Datum& input, const SlotId& slotID)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas);
node.OnInputChanged(input, slotID);
}
void Node::PushOutput(const Datum& output, const Slot& slot) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas);
if (slot.IsVariableReference())
{
GraphVariable* variable = slot.GetVariable();
if (variable)
{
ModifiableDatumView datumView;
variable->ConfigureDatumView(datumView);
datumView.AssignToDatum(output);
}
}
else
{
auto endpointIters = m_runtimeBus->GetConnectedEndpointIterators(Endpoint{ GetEntityId(), slot.GetId() });
for (auto endpointIter = endpointIters.first; endpointIter != endpointIters.second; ++endpointIter)
{
Node* node = m_runtimeBus->FindNode(endpointIter->second.GetNodeId());
node->SetInput(output, endpointIter->second.GetSlotId());
}
}
return m_graphRequestBus->IsEndpointConnected(Endpoint{ GetEntityId(), slot.GetId() });
}
void Node::ForEachConnectedNode(const Slot& slot, AZStd::function<void(Node&, const SlotId&)> callable) const
@@ -3018,9 +2957,8 @@ namespace ScriptCanvas
FindModifiableDatumView(slotId, datumView);
if (datumView.IsValid())
{
{
datumView.AssignToDatum(newInput);
OnInputChanged((*datumView.GetDatum()), slotId);
}
}
@@ -3034,7 +2972,6 @@ namespace ScriptCanvas
if (datumView.IsValid())
{
datumView.AssignToDatum(newInput);
OnInputChanged((*datumView.GetDatum()), slotId);
}
}
@@ -22,12 +22,10 @@
#include <ScriptCanvas/Core/ExecutionNotificationsBus.h>
#include <ScriptCanvas/Core/GraphBus.h>
#include <ScriptCanvas/Core/NodeBus.h>
#include <ScriptCanvas/Core/SignalBus.h>
#include <ScriptCanvas/Core/Slot.h>
#include <ScriptCanvas/Debugger/StatusBus.h>
#include <ScriptCanvas/Execution/ErrorBus.h>
#include <ScriptCanvas/Execution/ExecutionBus.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
#include <ScriptCanvas/Grammar/Primitives.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ValidationEvent.h>
@@ -400,7 +398,6 @@ namespace ScriptCanvas
class Node
: public AZ::Component
, public DatumNotificationBus::Handler
, private SignalBus::Handler
, public NodeRequestBus::Handler
, public EndpointNotificationBus::MultiHandler
{
@@ -542,7 +539,6 @@ namespace ScriptCanvas
AZStd::vector<AZStd::pair<const Node*, SlotId>> FindConnectedNodesAndSlotsByDescriptor(const SlotDescriptor& slotType, bool followLatentConnections = false) const;
AZStd::vector<const Slot*> GetSlotsByType(CombinedSlotType slotType) const;
AZStd::vector<Endpoint> GetConnectedEndpoints(SlotId outSlot) const;
bool IsConnected(const Slot& slot) const;
bool IsConnected(const SlotId& slotId) const;
@@ -845,7 +841,6 @@ namespace ScriptCanvas
void SignalSlotsReordered();
static void OnInputChanged(Node& node, const Datum& input, const SlotId& slotID);
static void SetInput(Node& node, const SlotId& id, const Datum& input);
static void SetInput(Node& node, const SlotId& id, Datum&& input);
@@ -892,7 +887,6 @@ protected:
void Configure();
protected:
TransientSlotIdentifier ConstructTransientIdentifier(const Slot& slot) const;
DatumVector GatherDatumsForDescriptor(SlotDescriptor descriptor) const;
@@ -900,7 +894,6 @@ protected:
SlotDataMap CreateInputMap() const;
SlotDataMap CreateOutputMap() const;
Signal CreateNodeInputSignal(const SlotId& slotId) const;
Signal CreateNodeOutputSignal(const SlotId& slotId) const;
@@ -954,6 +947,7 @@ protected:
//! This is a used by CodeGen to configure slots just prior to OnInit.
virtual void ConfigureSlots() {}
//! Entity level initialization, perform any resource allocation here that should be available throughout the node's existence.
virtual void OnInit() {}
@@ -968,13 +962,11 @@ protected:
//! Entity level activation, perform entity lifetime setup here, i.e. connect to EBuses
virtual void OnActivate() {}
//! Entity level deactivation, perform any entity lifetime release here, i.e disconnect from EBuses
virtual void OnDeactivate() {}
virtual void OnPostActivate() {}
//! Any node that is not pure data will perform its operation assuming that all input has been pushed and is reasonably valid
// perform your derived nodes work in OnInputSignal(const SlotId&)
virtual void OnInputSignal(const SlotId& /*slot*/) {}
//! Signal sent once the OwningScriptCanvasId is set.
virtual void OnGraphSet() {}
@@ -1000,25 +992,12 @@ protected:
void ModConnectedNodes(const Slot& slot, AZStd::vector<AZStd::pair<Node*, const SlotId>>&) const;
bool HasConnectedNodes(const Slot& slot) const;
virtual void OnInputChanged(const Datum& /*input*/, const SlotId& /*slotID*/) {}
//////////////////////////////////////////////////////////////////////////
//! The body of the node's execution, implement the node's work here.
void PushOutput(const Datum& output, const Slot& slot) const;
void SetOwningScriptCanvasId(ScriptCanvasId scriptCanvasId);
void SetGraphEntityId(AZ::EntityId graphEntityId);
// on activate, simple expressions need to push this data
virtual void SetInput(const Datum& input, const SlotId& id);
virtual void SetInput(Datum&& input, const SlotId& id);
//! Any node that is not pure data will perform its operation assuming that all input has been pushed and is reasonably valid
// perform your derived nodes work in OnInputSignal(const SlotId&)
void SignalInput(const SlotId& slot) override final;
//! This must be called manually to send execution out of a specific slot
void SignalOutput(const SlotId& slot, ExecuteMode mode = ExecuteMode::Normal) override final;
bool SlotExists(AZStd::string_view name, const SlotDescriptor& slotDescriptor) const;
bool IsTargetInDataFlowPath(const ID& targetNodeId, AZStd::unordered_set<ID>& path) const;
@@ -1027,10 +1006,6 @@ protected:
void PopulateNodeType();
void SetRuntimeBus(RuntimeRequests* runtimeBus) { m_runtimeBus = runtimeBus; }
RuntimeRequests* GetRuntimeBus() const { return m_runtimeBus; }
GraphScopedNodeId GetScopedNodeId() const { return GraphScopedNodeId(GetOwningScriptCanvasId(), GetEntityId()); }
private:
@@ -1070,102 +1045,17 @@ protected:
AZStd::vector< VisualExtensionSlotConfiguration > m_visualExtensions;
// Cache pointer to the owning Graph
RuntimeRequests* m_runtimeBus = nullptr;
GraphRequests* m_graphRequestBus = nullptr;
ScriptCanvas::SlotId m_removingSlot;
public:
template<typename t_Value>
const t_Value* GetInput_UNIT_TEST(AZStd::string_view slotName)
{
return GetInput_UNIT_TEST<t_Value>(GetSlotId(slotName));
}
template<typename t_Value>
t_Value* ModInput_UNIT_TEST(AZStd::string_view slotName)
{
return ModInput_UNIT_TEST<t_Value>(GetSlotId(slotName));
}
template<typename t_Value>
const t_Value* GetInput_UNIT_TEST(const SlotId& slotId)
{
const Datum* input = FindDatum(slotId);
return input ? input->GetAs<t_Value>() : nullptr;
}
template<typename t_Value>
t_Value* ModInput_UNIT_TEST(const SlotId& slotId)
{
auto slotIter = m_slotIdIteratorCache.find(slotId);
if (slotIter != m_slotIdIteratorCache.end())
{
Slot* slot = &(*slotIter->second.m_slotIterator);
if (slot->IsVariableReference())
{
AZ_Assert(false, "Variable references are not supported in Unit Test methods.");
}
else
{
return slotIter->second.GetDatumIter()->ModAs<t_Value>();
}
}
return nullptr;
}
const Datum* GetInput_UNIT_TEST(AZStd::string_view slotName)
{
return GetInput_UNIT_TEST(GetSlotId(slotName));
}
const Datum* GetInput_UNIT_TEST(const SlotId& slotId)
{
return FindDatum(slotId);
}
// initializes the node input to the value passed in, not a pointer to it
template<typename t_Value>
void SetInput_UNIT_TEST(AZStd::string_view slotName, const t_Value& value)
{
SetInput_UNIT_TEST<t_Value>(GetSlotId(slotName), value);
}
template<typename t_Value>
void SetInput_UNIT_TEST(const SlotId& slotId, const t_Value& value)
{
SetInput(Datum(value), slotId);
}
void SetInput_UNIT_TEST(AZStd::string_view slotName, const Datum& value)
{
SetInput_UNIT_TEST(GetSlotId(slotName), value);
}
void SetInput_UNIT_TEST(AZStd::string_view slotName, Datum&& value)
{
SetInput_UNIT_TEST(GetSlotId(slotName), AZStd::move(value));
}
void SetInput_UNIT_TEST(const SlotId& slotId, Datum&& value)
{
SetInput(AZStd::move(value), slotId);
}
template<typename t_Func, t_Func, typename, size_t>
friend struct Internal::MultipleOutputHelper;
template<typename ResultType, typename t_Traits, typename>
friend struct Internal::OutputSlotHelper;
template<typename ResultType, typename t_Traits, typename>
friend struct Internal::PushOutputHelper;
template<typename ResultType, typename ResultIndexSequence, typename t_Func, t_Func function, typename t_Traits>
friend struct Internal::CallHelper;
template<size_t... inputDatumIndices>
friend struct SetDefaultValuesByIndex;
};
@@ -1238,104 +1128,6 @@ protected:
}
};
template<typename ResultType, typename t_Traits, typename = AZStd::void_t<>>
struct PushOutputHelper
{
template<size_t... Is>
static void PushOutput(Node& node, ResultType&& result, AZStd::index_sequence<Is...>)
{
// protect against changes to the function that generated the node
if (auto slot = node.GetSlotByIndex(t_Traits::s_resultsSlotIndicesStart))
{
node.PushOutput(Datum(AZStd::forward<ResultType>(result)), *slot);
}
}
};
template<typename t_Traits>
struct PushOutputHelper<void, t_Traits, void>
{
template<size_t... Is> static void PushOutput(Node& node, AZStd::ignore_t result, AZStd::index_sequence<Is...>) {}
};
template<typename ResultType, typename t_Traits>
struct PushOutputHelper<ResultType, t_Traits, AZStd::enable_if_t<IsTupleLike<ResultType>::value>>
{
template<size_t t_Index>
static void PushOutputFold(Node& node, ResultType&& tupleResult)
{
// protect against changes to the function that generated the node
if (auto slot = node.GetSlotByIndex(t_Traits::s_resultsSlotIndicesStart + t_Index))
{
node.PushOutput(Datum(AZStd::get<t_Index>(AZStd::forward<ResultType>(tupleResult))), *slot);
}
}
template<size_t... Is>
static void PushOutput(Node& node, ResultType&& tupleResult, AZStd::index_sequence<Is...>)
{
(PushOutputFold<Is>(node, AZStd::forward<ResultType>(tupleResult)), ...);
}
};
template<typename ResultType, typename ResultIndexSequence, typename t_Func, t_Func function, typename t_Traits>
struct CallHelper
{
// protect against changes to the function that generated the node
template<typename... t_Args, size_t... Indices>
static bool IsIndexSafe(Node& node, const AZStd::index_sequence<Indices...>&)
{
return (true && ... && (node.FindDatumByIndex(Indices) != nullptr && node.FindDatumByIndex(Indices)->GetAs<AZStd::decay_t<t_Args>>() != nullptr));
}
template<typename... t_Args, size_t... ArgIndices>
static void Call(Node& node, AZStd::Internal::pack_traits_arg_sequence<t_Args...>, [[maybe_unused]] AZStd::index_sequence<ArgIndices...> sequence)
{
#if !defined(_RELEASE)
if (IsIndexSafe<t_Args...>(node, sequence))
{
PushOutputHelper<ResultType, t_Traits>::PushOutput(node, AZStd::invoke(function, *node.FindDatumByIndex(ArgIndices)->GetAs<AZStd::decay_t<t_Args>>()...), ResultIndexSequence());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((node), "Generic function Node (%s) could not be executed, due to missing slot for source definition."
"this is likely due to changing the function signature. See serialization log for potential errors & warnings.", node.GetNodeName().c_str());
}
#else
PushOutputHelper<ResultType, t_Traits>::PushOutput(node, AZStd::invoke(function, *node.FindDatumByIndex(ArgIndices)->GetAs<AZStd::decay_t<t_Args>>()...), ResultIndexSequence());
#endif//!defined(_RELEASE)
}
};
template<typename ResultIndexSequence, typename t_Func, t_Func function, typename t_Traits>
struct CallHelper<void, ResultIndexSequence, t_Func, function, t_Traits>
{
// protect against changes to the function that generated the node
template<typename... t_Args, size_t... Indices>
static bool IsIndexSafe(Node& node, const AZStd::index_sequence<Indices...>&)
{
return true && (... && (node.FindDatumByIndex(Indices) != nullptr && node.FindDatumByIndex(Indices)->GetAs<AZStd::decay_t<t_Args>>() != nullptr));
}
template<typename... t_Args, size_t... ArgIndices>
static void Call(Node& node, AZStd::Internal::pack_traits_arg_sequence<t_Args...>, [[maybe_unused]] AZStd::index_sequence<ArgIndices...> sequence)
{
#if !defined(_RELEASE)
if (IsIndexSafe<t_Args...>(node, sequence))
{
AZStd::invoke(function, *node.FindDatumByIndex(ArgIndices)->GetAs<AZStd::decay_t<t_Args>>()...);
}
else
{
SCRIPTCANVAS_REPORT_ERROR((node), "Generic function Node (%s) could not be executed, due to missing slot for source definition."
"this is likely due to changing the function signature. See serialization log for potential errors & warnings.", node.GetNodeName().c_str());
}
#else
AZStd::invoke(function, *node.FindDatumByIndex(ArgIndices)->GetAs<AZStd::decay_t<t_Args>>()...);
#endif//!defined(_RELEASE)
}
};
template<typename t_Func, t_Func function, typename t_Traits, size_t NumOutputs>
struct MultipleOutputHelper
{
@@ -1346,11 +1138,6 @@ protected:
{
OutputSlotHelper<ResultType, t_Traits>::AddOutputSlot(node, ResultIndexSequence());
}
static void Call(Node& node)
{
CallHelper<ResultType, ResultIndexSequence, t_Func, function, t_Traits>::Call(node, typename AZStd::function_traits<t_Func>::arg_sequence{}, AZStd::make_index_sequence<AZStd::function_traits<t_Func>::arity>{});
}
};
template<typename t_Func, t_Func function, typename t_Traits, typename t_Result, typename = AZStd::void_t<>>
@@ -248,8 +248,6 @@ namespace ScriptCanvas
return AZ::Success(scope);
}
protected:
template<typename ArgType, size_t Index>
@@ -298,13 +296,6 @@ namespace ScriptCanvas
MultipleOutputInvoker<t_Func, function, t_Traits>::Add(*this);
}
void OnInputSignal(const SlotId&) override
{
MultipleOutputInvoker<t_Func, function, t_Traits>::Call(*this);
SignalOutput(GetSlotId("Out"));
}
static bool VersionConverter(AZ::SerializeContext& serializeContext, AZ::SerializeContext::DataElementNode& rootElement);
static bool ConvertOldNodeGeneric(AZ::SerializeContext& serializeContext, AZ::SerializeContext::DataElementNode& rootElement);
@@ -1,36 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include "Core.h"
#include <AzCore/EBus/EBus.h>
namespace ScriptCanvas
{
enum class ExecuteMode
{
Normal,
UntilNodeIsFoundInStack
};
class SignalInterface : public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
typedef ID BusIdType;
//////////////////////////////////////////////////////////////////////////
virtual void SignalInput(const SlotId& slot) = 0;
virtual void SignalOutput(const SlotId& slot, ExecuteMode mode = ExecuteMode::Normal) = 0;
};
using SignalBus = AZ::EBus<SignalInterface>;
}
@@ -384,15 +384,10 @@ namespace ScriptCanvas
if (m_variable)
{
VariableNotificationBus::Handler::BusConnect(m_variable->GetGraphScopedId());
if (IsInput())
{
m_node->OnInputChanged((*m_variable->GetDatum()), GetId());
}
}
else
else if (m_node)
{
SCRIPTCANVAS_REPORT_ERROR((*m_node), "Node (%s) is attempting to execute using an invalid Variable Reference", m_node->GetNodeName().c_str());
AZ_Warning("ScriptCanvas", false, "Node (%s) is attempting to initialize an invalid Variable Reference", m_node->GetNodeName().c_str());
}
}
}
@@ -584,11 +579,6 @@ namespace ScriptCanvas
return m_isLatentSlot;
}
void Slot::OnVariableValueChanged()
{
m_node->OnInputChanged((*m_variable->GetDatum()), GetId());
}
void Slot::SetDynamicDataType(DynamicDataType dynamicDataType)
{
AZ_Assert(m_dynamicDataType == DynamicDataType::None, "Set Dynamic Data Type is meant to be used for a node wise version conversion step. Not as a run time reconfiguration of a dynamic type.");
@@ -167,10 +167,6 @@ namespace ScriptCanvas
bool IsLatent() const;
// VariableNotificationBus
void OnVariableValueChanged() override;
////
// Here to allow conversion of the previously untyped any slots into the dynamic type any.
void SetDynamicDataType(DynamicDataType dynamicDataType);
@@ -266,16 +266,6 @@ namespace ScriptCanvas
const In* FindIn(const AZStd::string& inSlotId) const;
const Out* FindLatentOut(const AZStd::string& latent) const;
LexicalScope GetLexicalScope(bool isSourcePure) const;
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
public:
bool IsAllInputOutputShared() const;
// all input/output are used in every in/out/latent slot?
bool m_isAllInputOutputShared = false;
void MarkAllInputOutputShared();
#endif
};
AZStd::string ToString(const In& in, size_t tabs = 0);
@@ -1,103 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <ScriptCanvas/Core/Endpoint.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/string/string_view.h>
#include <ScriptCanvas/Core/ExecutionNotificationsBus.h>
#include <ScriptCanvas/Data/Data.h>
#include <ScriptCanvas/Variable/VariableCore.h>
namespace ScriptCanvas
{
struct GraphData;
class GraphVariable;
class VariableData;
using EndpointMapConstIterator = AZStd::unordered_multimap<Endpoint, Endpoint>::const_iterator;
//! Runtime Request Bus for interfacing with the runtime execution component
class RuntimeRequests : public AZ::EBusTraits
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
//! BusIdType represents a unique id for the execution component
//! Because multiple Script Canvas graphs can execute on the same entity
//! this is not an "EntityId" in the sense that it uniquely identifies an entity.
using BusIdType = ScriptCanvasId;
virtual VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeId) const = 0;
virtual VariableId FindRuntimeVariableIdByAssetVariableId(VariableId assetId) const = 0;
virtual AZ::EntityId FindAssetNodeIdByRuntimeNodeId(AZ::EntityId editorNode) const = 0;
virtual AZ::Data::AssetId GetAssetId() const = 0;
virtual GraphIdentifier GetGraphIdentifier() const = 0;
virtual AZStd::string GetAssetName() const = 0;
//! Looks up the nodeId within the bus handler
virtual Node* FindNode(AZ::EntityId nodeId) const = 0;
virtual AZ::EntityId FindRuntimeNodeIdByAssetNodeId(AZ::EntityId runtimeNode) const = 0;
//! Returns the entity id of the execution component
virtual AZ::EntityId GetRuntimeEntityId() const = 0;
//! Returns a container of nodes
virtual AZStd::vector<AZ::EntityId> GetNodes() const = 0;
//! Returns a container of connections
virtual AZStd::vector<AZ::EntityId> GetConnections() const = 0;
//! Returns a container of all endpoints to which the supplied endpoint is connected point
virtual AZStd::vector<Endpoint> GetConnectedEndpoints(const Endpoint& endpoint) const = 0;
virtual AZStd::pair< EndpointMapConstIterator, EndpointMapConstIterator > GetConnectedEndpointIterators(const Endpoint& endpoint) const = 0;
//! Returns whether the given endpoint has any connections
virtual bool IsEndpointConnected(const Endpoint& endpoint) const = 0;
//! Retrieves GraphData structure which manages the nodes and connections of an executing graph
virtual GraphData* GetGraphData() = 0;
virtual const GraphData* GetGraphDataConst() const = 0;
//! Retrieves VariableData structure which manages variable data for the execution component
virtual VariableData* GetVariableData() = 0;
virtual const VariableData* GetVariableDataConst() const = 0;
//! Retrieves a map of variable id to variable name and variable datums pair
virtual const GraphVariableMapping* GetVariables() const = 0;
//! Searches for a variable with the specified name
//! returns pointer to the first variable with the specified name or nullptr
virtual GraphVariable* FindVariable(AZStd::string_view varName) = 0;
//! Searches for a variable by VariableId
//! returns a pair of <variable datum pointer, variable name> with the supplied id
//! The variable datum pointer is non-null if the variable has been found
virtual GraphVariable* FindVariableById(const VariableId& variableId) = 0;
//! Returns the type associated with the specified variable.
virtual Data::Type GetVariableType(const VariableId& variableId) const = 0;
//! Looks up the variable name that the variable data is associated with in the handler of the bus
virtual AZStd::string_view GetVariableName(const VariableId& variableId) const = 0;
virtual bool IsGraphObserved() const = 0;
virtual void SetIsGraphObserved(bool isObserved) = 0;
virtual AZ::Data::AssetType GetAssetType() const = 0;
};
using RuntimeRequestBus = AZ::EBus<RuntimeRequests>;
}
@@ -2248,17 +2248,6 @@ namespace ScriptCanvas
m_subgraphInterface.SetNamespacePath(m_source.m_namespacePath);
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
if (m_source.m_graph->IsFunctionGraph())
{
m_variableScopeMeaning = VariableScopeMeaning_LegacyFunctions::FunctionPrototype;
m_subgraphInterface.MarkAllInputOutputShared();
}
else
{
m_variableScopeMeaning = VariableScopeMeaning_LegacyFunctions::ValueInitialization;
}
#endif
// The Order Matters: begin
// add all data to the ACM for easy look up in input/output processing for ACM nodes
@@ -594,24 +594,6 @@ namespace ScriptCanvas
void ParseExecutionIfStatementBooleanExpression(ExecutionTreePtr booleanExpressionExecution, AZStd::string executionName, LexicalScope lexicalScope);
void ParseExecutionIfStatementInternalFunction(ExecutionTreePtr internalFunctionExecution);
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
public:
AZStd::vector<VariablePtr> FindAllVariablesInVariableFlagScope(VariableFlags::Scope scope) const;
// scrape variables for scope, every Scope::In and InOut
AZStd::vector<VariablePtr> FindSubGraphInputValues() const;
// scrape variables for scope, every Scope::Out and InOut
AZStd::vector<VariablePtr> FindSubGraphOutputValues() const;
AZStd::vector<VariableConstPtr> GetLocalVariablesUser() const;
VariableScopeMeaning_LegacyFunctions GetVariableScopeMeaning() const;
private:
VariableScopeMeaning_LegacyFunctions m_variableScopeMeaning = VariableScopeMeaning_LegacyFunctions::ValueInitialization;
#endif
}; // class AbstractCodeModel
template<typename T>
@@ -1,283 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "PrimitivesDeclarations.h"
#if defined(FUNCTION_LEGACY_SUPPORT_ENABLED)
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/Datum.h>
#include <ScriptCanvas/Core/EBusHandler.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/GraphData.h>
#include <ScriptCanvas/Core/ModifiableDatumView.h>
#include <ScriptCanvas/Core/Nodeable.h>
#include <ScriptCanvas/Core/NodeableNode.h>
#include <ScriptCanvas/Core/NodeableNodeOverloaded.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <ScriptCanvas/Core/SlotNames.h>
#include <ScriptCanvas/Core/SubgraphInterfaceUtility.h>
#include <ScriptCanvas/Debugger/ValidationEvents/DataValidation/ScopedDataConnectionEvent.h>
#include <ScriptCanvas/Debugger/ValidationEvents/ParsingValidation/ParsingValidations.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
#include <ScriptCanvas/Grammar/ParsingMetaData.h>
#include <ScriptCanvas/Libraries/Core/AzEventHandler.h>
#include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
#include <ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h>
#include <ScriptCanvas/Libraries/Core/ExtractProperty.h>
#include <ScriptCanvas/Libraries/Core/ForEach.h>
#include <ScriptCanvas/Libraries/Core/FunctionCallNode.h>
#include <ScriptCanvas/Libraries/Core/Method.h>
#include <ScriptCanvas/Libraries/Core/MethodUtility.h>
#include <ScriptCanvas/Libraries/Core/Start.h>
#include <ScriptCanvas/Translation/TranslationUtilities.h>
#include <ScriptCanvas/Utils/VersionConverters.h>
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
#include <ScriptCanvas/Variable/VariableBus.h>
#include <ScriptCanvas/Variable/VariableData.h>
#include <ScriptEvents/ScriptEventsAsset.h>
#include <ScriptEvents/ScriptEventsBus.h>
#include "AbstractCodeModel.h"
#include "FunctionsLegacySupport.h"
#include "GrammarContextBus.h"
#include "ParsingUtilities.h"
#include "Primitives.h"
namespace ScriptCanvas
{
namespace Grammar
{
void AbstractCodeModel::AddAllVariablesPreParse_LegacyFunctions()
{
// all variables assumed to be NOT persistent - in the live code they are reset when activated
// variables with no scope In/Out is assumed to be persistent, this is a mess with tick handlers
// warn on any variable attempted to be read before written
AZ_Assert(m_variableScopeMeaning == VariableScopeMeaning_LegacyFunctions::FunctionPrototype, "new graph type added without full support");
auto& sourceVariables = m_source.m_variableData->GetVariables();
AZStd::set<const GraphVariable*, GraphVariable::Comparator> sortedVariables;
for (const auto& variablePair : sourceVariables)
{
sortedVariables.insert(&variablePair.second);
}
for (auto& sourceVariable : sortedVariables)
{
auto datum = sourceVariable->GetDatum();
AZ_Assert(datum != nullptr, "the datum must be valid");
AddVariable(*datum, sourceVariable->GetVariableName(), sourceVariable->GetVariableId());
}
}
AZStd::vector<VariablePtr> AbstractCodeModel::FindSubGraphInputValues() const
{
return FindAllVariablesInVariableFlagScope(VariableFlags::Scope::Input);
}
AZStd::vector<VariablePtr> AbstractCodeModel::FindSubGraphOutputValues() const
{
return FindAllVariablesInVariableFlagScope(VariableFlags::Scope::Output);
}
AZStd::vector<VariablePtr> AbstractCodeModel::FindAllVariablesInVariableFlagScope(VariableFlags::Scope scope) const
{
AZStd::vector<VariablePtr> variables;
auto& sourceVariables = m_source.m_variableData->GetVariables();
for (auto& variable : m_variables)
{
if (IsSourceInScope(variable, scope))
{
variables.push_back(variable);
}
}
// sort by variable id
AZStd::sort(variables.begin(), variables.end(), [](const auto& lhs, const auto& rhs) { return lhs->m_sourceVariableId < rhs->m_sourceVariableId; });
return variables;
}
AZStd::vector<VariableConstPtr> AbstractCodeModel::GetLocalVariablesUser() const
{
AZStd::vector<VariableConstPtr> userLocalVariables;
if (m_variableScopeMeaning == VariableScopeMeaning_LegacyFunctions::FunctionPrototype)
{
for (auto variable : m_variables)
{
if (!variable->m_isMember
&& variable->m_sourceVariableId.IsValid()
&& !IsSourceInScope(variable, VariableFlags::Scope::Input)
&& !IsSourceInScope(variable, VariableFlags::Scope::Output))
{
userLocalVariables.push_back(variable);
}
}
}
return userLocalVariables;
}
VariableScopeMeaning_LegacyFunctions AbstractCodeModel::GetVariableScopeMeaning() const
{
return m_variableScopeMeaning;
}
bool SubgraphInterface::IsAllInputOutputShared() const
{
return m_isAllInputOutputShared;
}
void SubgraphInterface::MarkAllInputOutputShared()
{
m_isAllInputOutputShared = true;
}
} // namespace Grammar
namespace Nodes
{
namespace Core
{
void FunctionCallNode::BuildNodeFromSubgraphInterface
(const AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>& runtimeAsset
, const SlotExecution::Map& previousMap)
{
// build the node here, from the asset topology, take the node/variable ordering from the function runtime data as a suggestion
// deal with updates and conversions after
const Grammar::SubgraphInterface& subgraphInterface = runtimeAsset.Get()->m_runtimeData.m_interface;
m_prettyName = runtimeAsset.Get()->m_runtimeData.m_name;
if (!subgraphInterface.IsAllInputOutputShared())
{
AZ_Error("ScriptCanvas", false, "the current assumption is that there is no way to distinguish between the input/output of different nodelings");
return;
}
// for now, all outputs are shared
Grammar::Outputs outputs;
bool sharedOutputInitialized = false;
SlotExecution::Ins slotMapIns;
SlotExecution::Outs slotMapLatents;
int slotOffset = 0;
// add all ins->outs, in their display groups
for (size_t indexIn = 0; indexIn < subgraphInterface.GetInCount(); ++indexIn)
{
const Grammar::In& interfaceIn = subgraphInterface.GetIn(indexIn);
SlotExecution::In slotMapIn = AddExecutionInSlotFromInterface(interfaceIn, slotOffset++, previousMap.FindInSlotIdBySource(interfaceIn.sourceID));
if (!slotMapIn.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Execution In slot from sub graph interface");
return;
}
slotMapIn.inputs = AddDataInputSlotFromInterface(interfaceIn.inputs, interfaceIn.sourceID, interfaceIn.displayName, previousMap, slotOffset);
for (auto& input : slotMapIn.inputs)
{
if (!input.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Input slot from sub graph interface");
return;
}
}
for (auto& interfaceOut : interfaceIn.outs)
{
SlotExecution::Out slotMapOut = AddExecutionOutSlotFromInterface(interfaceIn, interfaceOut, slotOffset++, previousMap.FindOutSlotIdBySource(interfaceIn.sourceID, interfaceOut.sourceID));
if (!slotMapOut.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Execution Out slot from sub graph interface");
return;
}
if (!sharedOutputInitialized)
{
outputs = interfaceOut.outputs;
sharedOutputInitialized = true;
}
slotMapIn.outs.push_back(slotMapOut);
}
slotMapIns.push_back(slotMapIn);
}
// add all latents in their display groups
for (size_t indexLatent = 0; indexLatent < subgraphInterface.GetLatentOutCount(); ++indexLatent)
{
const Grammar::Out& interfaceLatent = subgraphInterface.GetLatentOut(indexLatent);
SlotExecution::Out slotMapLatentOut = AddExecutionLatentOutSlotFromInterface(interfaceLatent, slotOffset++, previousMap.FindLatentSlotIdBySource(interfaceLatent.sourceID));
if (!slotMapLatentOut.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Latent Out slot from sub graph interface");
return;
}
slotMapLatentOut.returnValues.values = AddDataInputSlotFromInterface(interfaceLatent.returnValues, interfaceLatent.sourceID, interfaceLatent.displayName, previousMap, slotOffset);
for (auto& input : slotMapLatentOut.returnValues.values)
{
if (!input.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Input slot from sub graph interface");
return;
}
}
if (!sharedOutputInitialized)
{
outputs = interfaceLatent.outputs;
sharedOutputInitialized = true;
}
slotMapLatents.push_back(slotMapLatentOut);
}
// add all outputs one time, since they are currently all required to be part of all the signatures [\todo must fix] , in a variable display group
SlotExecution::Outputs slotMapOutputs = AddDataOutputSlotFromInterface(outputs, "", previousMap, slotOffset);
for (auto& output : slotMapOutputs)
{
if (!output.slotId.IsValid())
{
AZ_Error("ScriptCanvas", false, "Failed to add Output slot from sub graph interface");
return;
}
}
if (!subgraphInterface.IsLatent())
{
for (auto& slotMapIn : slotMapIns)
{
for (auto& slotMapOut : slotMapIn.outs)
{
slotMapOut.outputs = slotMapOutputs;
}
}
}
else
{
for (auto& slotMapLatent : slotMapLatents)
{
slotMapLatent.outputs = slotMapOutputs;
}
}
// when returning variables: sort variables by source slot id, they are sorted in the slot map, so just take them from the slot map
m_slotExecutionMap = AZStd::move(SlotExecution::Map(AZStd::move(slotMapIns), AZStd::move(slotMapLatents)));
m_slotExecutionMapSourceInterface = subgraphInterface;
m_asset = runtimeAsset;
SignalSlotsReordered();
}
} // namespace Core
} // namespace Nodes
}
#endif
@@ -1,20 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
namespace ScriptCanvas
{
namespace Grammar
{
enum class VariableScopeMeaning_LegacyFunctions : AZ::u32
{
ValueInitialization,
FunctionPrototype,
};
}
}
@@ -19,10 +19,6 @@
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/string/string.h>
#if defined (FUNCTION_LEGACY_SUPPORT_ENABLED)
#include "FunctionsLegacySupport.h"
#endif
namespace AZ
{
class ReflectContext;
@@ -23,15 +23,6 @@ namespace ScriptCanvas
}
}
//////////////////
// BaseTimerNode
//////////////////
BaseTimerNode::~BaseTimerNode()
{
StopTimer();
}
void BaseTimerNode::OnInit()
{
AZStd::string slotName = GetTimeSlotName();
@@ -74,11 +65,6 @@ namespace ScriptCanvas
AddTimeDataSlot();
}
void BaseTimerNode::OnDeactivate()
{
StopTimer();
}
void BaseTimerNode::ConfigureVisualExtensions()
{
{
@@ -103,54 +89,7 @@ namespace ScriptCanvas
return nullptr;
}
void BaseTimerNode::OnSystemTick()
{
AZ::SystemTickBus::Handler::BusDisconnect();
if (!AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusConnect();
}
}
void BaseTimerNode::OnTick(float delta, AZ::ScriptTimePoint)
{
if (m_timeUnits == TimeUnits::Ticks)
{
m_timerCounter += 1;
}
switch (m_timeUnits)
{
case TimeUnits::Ticks:
m_timerCounter += 1;
break;
case TimeUnits::Milliseconds:
case TimeUnits::Seconds:
m_timerCounter += delta;
break;
default:
break;
}
while (m_timerCounter > m_timerDuration)
{
if (!m_isActive)
{
break;
}
m_timerCounter -= m_timerDuration;
OnTimeElapsed();
}
}
int BaseTimerNode::GetTickOrder()
{
return m_tickOrder;
}
void BaseTimerNode::AddTimeDataSlot()
{
if (!m_timeSlotId.IsValid())
@@ -174,70 +113,6 @@ namespace ScriptCanvas
}
}
void BaseTimerNode::StartTimer()
{
StopTimer();
m_isActive = true;
const Datum* datum = FindDatum(m_timeSlotId);
if (datum)
{
const Data::NumberType* timeAmount = datum->GetAs<Data::NumberType>();
if (timeAmount)
{
m_timerDuration = (*timeAmount);
m_timerCounter = 0;
// Manage the different unit types
if (m_timeUnits == TimeUnits::Ticks)
{
// Remove all of the floating points
m_timerDuration = aznumeric_cast<float>(aznumeric_cast<int>(m_timerDuration));
}
else if (m_timeUnits == TimeUnits::Milliseconds)
{
m_timerDuration /= 1000.0;
}
}
}
if (AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusDisconnect();
}
if (AZ::SystemTickBus::Handler::BusIsConnected())
{
AZ::SystemTickBus::Handler::BusDisconnect();
}
if (!AZ::IsClose(m_timerDuration, 0.0, DBL_EPSILON))
{
AZ::SystemTickBus::Handler::BusConnect();
}
else if (AllowInstantResponse())
{
while (m_isActive)
{
OnTimeElapsed();
}
}
}
void BaseTimerNode::StopTimer()
{
m_isActive = false;
m_timerCounter = 0.0;
m_timerDuration = 0.0;
AZ::SystemTickBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
}
AZStd::string BaseTimerNode::GetTimeSlotName() const
{
return GetBaseTimeSlotName();
@@ -283,11 +158,7 @@ namespace ScriptCanvas
{
return false;
}
void BaseTimerNode::OnTimeElapsed()
{
}
void BaseTimerNode::ConfigureTimeSlot(DataSlotConfiguration& configuration)
{
AZ_UNUSED(configuration);
@@ -7,10 +7,7 @@
#pragma once
#include <AzCore/Component/TickBus.h>
#include <ScriptCanvas/Core/Node.h>
#include <Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.generated.h>
namespace ScriptCanvas
@@ -23,8 +20,6 @@ namespace ScriptCanvas
class BaseTimerNode
: public Node
, public NodePropertyInterfaceListener
, public AZ::TickBus::Handler
, public AZ::SystemTickBus::Handler
{
public:
@@ -44,32 +39,16 @@ namespace ScriptCanvas
"Seconds"
};
virtual ~BaseTimerNode();
// Node...
void OnInit() override;
void OnConfigured() override;
void OnDeactivate() override;
void ConfigureVisualExtensions() override;
NodePropertyInterface* GetPropertyInterface(AZ::Crc32 propertyId) override;
////
// SystemTickBus...
void OnSystemTick() override;
////
// TickBus...
void OnTick(float delta, AZ::ScriptTimePoint timePoint) override;
int GetTickOrder() override;
////
// Method that will handle displaying and viewing of the time slot
void AddTimeDataSlot();
void StartTimer();
void StopTimer();
AZStd::string GetTimeSlotName() const;
protected:
@@ -83,7 +62,6 @@ namespace ScriptCanvas
bool IsActive() const;
virtual bool AllowInstantResponse() const;
virtual void OnTimeElapsed();
// Store until versioning is complete
virtual const char* GetTimeSlotFormat() const { return "Time (%s)"; }
@@ -112,37 +112,6 @@ namespace ScriptCanvas
}
}
void ExpressionNodeBase::OnInputSignal(const SlotId& slotId)
{
if (slotId == ExpressionNodeBaseProperty::GetInSlotId(this))
{
for (const SlotId& dirtySlotId : m_dirtyInputs)
{
auto variableIter = m_slotToVariableMap.find(dirtySlotId);
if (variableIter != m_slotToVariableMap.end())
{
PushVariable(variableIter->second, (*FindDatum(dirtySlotId)));
}
}
m_dirtyInputs.clear();
if (m_parseError.IsValidExpression() && m_expressionTree.GetTreeSize() != 0)
{
ExpressionEvaluation::ExpressionResult expressionResult;
ExpressionEvaluation::ExpressionEvaluationRequestBus::BroadcastResult(expressionResult, &ExpressionEvaluation::ExpressionEvaluationRequests::Evaluate, m_expressionTree);
OnResult(expressionResult);
}
}
}
void ExpressionNodeBase::OnInputChanged([[maybe_unused]] const Datum& input, const SlotId& slotId)
{
m_dirtyInputs.insert(slotId);
}
bool ExpressionNodeBase::CanDeleteSlot([[maybe_unused]] const SlotId& slotId) const
{
return m_handlingExtension;
@@ -53,10 +53,6 @@ namespace ScriptCanvas
void OnInit() override;
void OnPostActivate() override;
void ConfigureVisualExtensions() override;
void OnInputSignal(const SlotId& slotId) override;
void OnInputChanged(const Datum& input, const SlotId& slotId) override;
bool CanDeleteSlot(const SlotId& slotId) const override;
SlotId HandleExtension(AZ::Crc32 extensionId) override;
@@ -110,7 +106,6 @@ namespace ScriptCanvas
bool m_isInError = false;
AZStd::unordered_map<SlotId, AZStd::string> m_slotToVariableMap;
AZStd::unordered_set<SlotId> m_dirtyInputs;
AZStd::unordered_map<AZStd::string, SlotId> m_slotsByVariables;
ExpressionEvaluation::ParsingError m_parseError;
@@ -41,22 +41,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs == rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -40,21 +40,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs > rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -41,21 +41,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs >= rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -40,22 +40,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs < rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -40,22 +40,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs <= rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -40,22 +40,6 @@ namespace ScriptCanvas
}
}
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
ComparisonOutcome result(lhs != rhs);
if (result.IsSuccess())
{
return Datum(result.GetValue());
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), result.GetError().c_str());
return Datum(false);
}
}
};
}
@@ -75,20 +75,6 @@ namespace ScriptCanvas
}
}
void ArithmeticExpression::OnInputSignal(const SlotId& slotId)
{
if (slotId == GetSlotId(k_evaluateName))
{
const Datum output = Evaluate(*FindDatumByIndex(k_datumIndexLHS), *FindDatumByIndex(k_datumIndexRHS));
if (auto slot = GetSlot(GetOutputSlotId()))
{
PushOutput(output, *slot);
}
SignalOutput(GetSlotId(k_outName));
}
}
void ArithmeticExpression::Reflect(AZ::ReflectContext* reflection)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
@@ -107,17 +93,6 @@ namespace ScriptCanvas
}
}
Datum BinaryOperator::Evaluate([[maybe_unused]] const Datum& lhs, [[maybe_unused]] const Datum& rhs)
{
AZ_Assert(false, "Evaluate must be overridden");
return Datum();
};
void BinaryOperator::OnInputSignal([[maybe_unused]] const SlotId& slot)
{
AZ_Assert(false, "OnInputSignal must be overridden");
}
void BinaryOperator::OnInit()
{
{
@@ -159,28 +134,6 @@ namespace ScriptCanvas
AZ_Assert(false, "InitializeBooleanExpression must be overridden");
}
void BooleanExpression::OnInputSignal(const SlotId& slotId)
{
if (slotId == GetSlotId(k_evaluateName))
{
const Datum output = Evaluate(*FindDatumByIndex(k_datumIndexLHS), *FindDatumByIndex(k_datumIndexRHS));
if (auto slot = GetSlot(GetOutputSlotId()))
{
PushOutput(output, *slot);
}
const bool* result = output.GetAs<bool>();
if (result && *result)
{
SignalOutput(GetSlotId(k_onTrue));
}
else
{
SignalOutput(GetSlotId(k_onFalse));
}
}
}
void BooleanExpression::OnInit()
{
{
@@ -31,9 +31,7 @@ namespace ScriptCanvas
static const char* k_evaluateName;
static const char* k_outName;
static const char* k_onTrue;
static const char* k_onFalse;
static const char* k_onFalse;
protected:
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& /*executionSlot*/, CombinedSlotType targetSlotType, const Slot* /*executionChildSlot*/) const override
@@ -47,12 +45,6 @@ namespace ScriptCanvas
void OnInit() override;
// must be overridden with the binary operations
virtual Datum Evaluate(const Datum& lhs, const Datum& rhs);
// Triggered by the execution signal
void OnInputSignal(const SlotId& slot) override;
SlotId GetOutputSlotId() const;
};
@@ -71,10 +63,6 @@ namespace ScriptCanvas
protected:
// adds Number inputs, adds Number output type
void OnInit() override;
void OnInputSignal(const SlotId& slot) override;
};
class BooleanExpression
@@ -107,9 +95,7 @@ namespace ScriptCanvas
protected:
// initialize boolean expression, adds boolean output type calls
void OnInit() override;
virtual void InitializeBooleanExpression();
void OnInputSignal(const SlotId& slot) override;
virtual void InitializeBooleanExpression();
};
// accepts any type, checks for type equality, and then value equality or pointer equality
@@ -126,10 +112,8 @@ namespace ScriptCanvas
void InitializeBooleanExpression() override;
private:
SlotId m_firstSlotId;
SlotId m_secondSlotId;
ScriptCanvas::Data::Type m_displayType;
};
@@ -144,8 +128,7 @@ namespace ScriptCanvas
protected:
// adds number types
void InitializeBooleanExpression() override;
void InitializeBooleanExpression() override;
};
}
}
@@ -9,7 +9,6 @@
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/Utils.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Grammar/Primitives.h>
#include <ScriptCanvas/Grammar/ParsingUtilities.h>
#include <ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.h>
@@ -59,16 +58,6 @@ namespace ScriptCanvas
SetAutoConnectToGraphOwner(m_autoConnectToGraphOwner);
}
void EBusEventHandler::OnPostActivate()
{
}
void EBusEventHandler::OnDeactivate()
{
Disconnect();
}
void EBusEventHandler::OnGraphSet()
{
GraphScopedNodeId scopedNodeId(GetOwningScriptCanvasId(), GetEntityId());
@@ -127,14 +116,6 @@ namespace ScriptCanvas
}
}
void EBusEventHandler::Connect()
{
}
void EBusEventHandler::Disconnect()
{
}
AZ::Outcome<DependencyReport, void> EBusEventHandler::GetDependencies() const
{
return AZ::Success(DependencyReport{});
@@ -515,7 +496,6 @@ namespace ScriptCanvas
const AZ::BehaviorEBusHandler::BusForwarderEvent& event = events[eventIndex];
AZ_Assert(!event.m_parameters.empty(), "No parameters in event!");
m_handler->InstallGenericHook(events[eventIndex].m_name, &OnEventGenericHook, this);
if (m_eventMap.find(AZ::Crc32(event.m_name)) != m_eventMap.end())
{
@@ -621,137 +601,6 @@ namespace ScriptCanvas
}
}
void EBusEventHandler::OnEvent(const char* eventName, const int /*eventIndex*/, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "EBusEventHandler::OnEvent %s", eventName);
SCRIPTCANVAS_RETURN_IF_ERROR_STATE((*this));
auto iter = m_eventMap.find(AZ::Crc32(eventName));
if (iter == m_eventMap.end())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Invalid event index in Ebus handler");
return;
}
EBusEventEntry& ebusEventEntry = iter->second;
if (!ebusEventEntry.m_shouldHandleEvent || ebusEventEntry.m_isHandlingEvent)
{
AZ_Warning("ScriptCanvas", !ebusEventEntry.m_isHandlingEvent, "Found situation where in handling event(%s::%s) triggered the same event. Possible infinite loop, not handling second call.", GetEBusName().c_str(), eventName);
return;
}
ebusEventEntry.m_isHandlingEvent = true;
ebusEventEntry.m_resultEvaluated = !ebusEventEntry.IsExpectingResult();
AZ_Assert(ebusEventEntry.m_eventName.compare(eventName) == 0, "Wrong event handled by this EBusEventHandler! received %s, expected %s", eventName, ebusEventEntry.m_eventName.c_str());
AZ_Assert(numParameters == ebusEventEntry.m_numExpectedArguments, "Wrong number of events passed into EBusEventHandler %s", eventName);
// route my parameters to the connect nodes input
AZ_Assert(ebusEventEntry.m_parameterSlotIds.size() == numParameters, "Node %s-%s Num parameters = %d, but num output slots = %d", m_ebusName.c_str(), ebusEventEntry.m_eventName.c_str(), numParameters, ebusEventEntry.m_parameterSlotIds.size());
for (int parameterIndex(0); parameterIndex < numParameters; ++parameterIndex)
{
const Slot* slot = GetSlot(ebusEventEntry.m_parameterSlotIds[parameterIndex]);
const auto& value = *(parameters + parameterIndex);
const Datum input(value);
PushOutput(input, (*slot));
}
// now, this should pass execution off to the nodes that will push their output into this result input
SignalOutput(ebusEventEntry.m_eventSlotId, ExecuteMode::UntilNodeIsFoundInStack);
// route executed nodes output to my input, and my input to the result
if (ebusEventEntry.IsExpectingResult())
{
if (result)
{
if (const Datum* resultInput = FindDatum(ebusEventEntry.m_resultSlotId))
{
ebusEventEntry.m_resultEvaluated = resultInput->ToBehaviorContext(*result);
AZ_Warning("Script Canvas", ebusEventEntry.m_resultEvaluated, "Script Canvas failed to write a value back to the caller!");
}
else
{
AZ_Warning("Script Canvas", false, "Script Canvas handler expecting a result, but had no ability to return it");
}
}
else
{
AZ_Warning("Script Canvas", false, "Script Canvas handler is expecting a result, but was called without expecting one!");
}
}
else
{
AZ_Warning("Script Canvas", !result, "Script Canvas handler is not expecting a result, but was called expecting one!");
}
// route executed nodes output to my input, and my input to the result
AZ_Warning("Script Canvas", (result != nullptr) == ebusEventEntry.IsExpectingResult(), "Node %s-%s mismatch between expecting a result and getting one!", m_ebusName.c_str(), ebusEventEntry.m_eventName.c_str());
AZ_Warning("Script Canvas", ebusEventEntry.m_resultEvaluated, "Node %s-%s result not evaluated properly!", m_ebusName.c_str(), ebusEventEntry.m_eventName.c_str());
ebusEventEntry.m_isHandlingEvent = false;
}
void EBusEventHandler::OnInputSignal(const SlotId& slotId)
{
SlotId connectSlot = EBusEventHandlerProperty::GetConnectSlotId(this);
SlotId disconnectSlot = EBusEventHandlerProperty::GetDisconnectSlotId(this);
if (connectSlot == slotId)
{
if (IsIDRequired())
{
const Datum* busIdDatum = FindDatum(GetSlotId(c_busIdName));
if (!busIdDatum || busIdDatum->Empty())
{
SlotId failureSlot = EBusEventHandlerProperty::GetOnFailureSlotId(this);
SignalOutput(failureSlot);
SCRIPTCANVAS_REPORT_ERROR((*this), "In order to connect this node, a valid BusId must be provided.");
return;
}
}
Disconnect();
Connect();
SlotId onConnectSlotId = EBusEventHandlerProperty::GetOnConnectedSlotId(this);
SignalOutput(onConnectSlotId);
return;
}
else if (disconnectSlot == slotId)
{
Disconnect();
SlotId onDisconnectSlotId = EBusEventHandlerProperty::GetOnDisconnectedSlotId(this);
SignalOutput(onDisconnectSlotId);
return;
}
}
void EBusEventHandler::OnInputChanged(const Datum& /*input*/, const SlotId& /*slotId*/)
{
/*
if (GetExecutionType() == ExecutionType::Runtime
&& m_autoConnectToGraphOwner
&& slotId == FindSlotIdForDescriptor(c_busIdName, SlotDescriptors::DataIn()))
{
Disconnect();
Connect();
}
*/
}
void EBusEventHandler::OnEventGenericHook(void* userData, const char* eventName, int eventIndex, AZ::BehaviorValueParameter* result, int numParameters, AZ::BehaviorValueParameter* parameters)
{
EBusEventHandler* handler(reinterpret_cast<EBusEventHandler*>(userData));
handler->OnEvent(eventName, eventIndex, result, numParameters, parameters);
}
void EBusEventHandler::OnWriteEnd()
{
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
@@ -78,9 +78,6 @@ namespace ScriptCanvas
void OnInit() override;
void OnActivate() override;
void OnPostActivate() override;
void OnDeactivate() override;
void OnGraphSet() override;
void CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const override;
@@ -96,16 +93,10 @@ namespace ScriptCanvas
void InitializeEvent(int eventIndex);
bool IsOutOfDate(const VersionData& graphVersion) const override;
bool IsOutOfDate(const VersionData& graphVersion) const override;
bool CreateHandler(AZStd::string_view ebusName);
void Connect();
void Disconnect();
const EBusEventEntry* FindEventWithSlot(const Slot& slot) const;
AZ::Outcome<AZStd::string, void> GetFunctionCallName(const Slot* /*slot*/) const override;
@@ -166,16 +157,10 @@ namespace ScriptCanvas
inline bool IsConfigured() const { return !m_eventMap.empty(); }
void OnEvent(const char* eventName, const int eventIndex, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters);
void OnInputSignal(const SlotId&) override;
void OnInputChanged(const Datum& input, const SlotId& slotID) override;
private:
EBusEventHandler(const EBusEventHandler&) = delete;
static void OnEventGenericHook(void* userData, const char* eventName, int eventIndex, AZ::BehaviorValueParameter* result, int numParameters, AZ::BehaviorValueParameter* parameters);
EventMap m_eventMap;
AZStd::string m_ebusName;
ScriptCanvas::EBusBusId m_busId;
@@ -63,43 +63,6 @@ namespace ScriptCanvas
}
}
void GetVariableNode::OnInputSignal(const SlotId& slotID)
{
if (slotID == GetSlotId("In"))
{
SC_EXECUTION_TRACE_ANNOTATE_NODE((*this), CreateAnnotationData());
if (m_variableView.IsValid())
{
Slot* resultSlot = GetSlot(m_variableDataOutSlotId);
if (resultSlot)
{
const Datum* inputDatum = m_variableView.GetDatum();
PushOutput(*inputDatum, *resultSlot);
// Push the data for each property slot out as well
for (auto&& propertyAccount : m_propertyAccounts)
{
Slot* propertySlot = GetSlot(propertyAccount.m_propertySlotId);
if (propertySlot && propertyAccount.m_getterFunction)
{
auto outputOutcome = propertyAccount.m_getterFunction(*inputDatum);
if (!outputOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), outputOutcome.TakeError().data());
return;
}
PushOutput(outputOutcome.TakeValue(), *propertySlot);
}
}
}
}
SignalOutput(GetSlotId("Out"));
}
}
void GetVariableNode::CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const
{
if (m_variableId.IsValid())
@@ -324,8 +287,9 @@ namespace ScriptCanvas
ScriptCanvas::Data::Type baseType = ScriptCanvas::Data::Type::Invalid();
VariableRequestBus::EventResult(baseType, GetScopedVariableId(), &VariableRequests::GetType);
const GraphVariableMapping* variableMap = GetRuntimeBus()->GetVariables();
const GraphVariableMapping* variableMap = nullptr;
GraphRequestBus::EventResult(variableMap, *GraphNotificationBus::GetCurrentBusId(), &GraphRequests::GetVariables);
if (variableMap && baseType.IsValid())
{
for (const auto& variablePair : *variableMap)
@@ -360,12 +324,6 @@ namespace ScriptCanvas
VariableNodeNotificationBus::Event(GetEntityId(), &VariableNodeNotifications::OnVariableRemovedFromNode, removedVariableId);
}
AnnotateNodeSignal GetVariableNode::CreateAnnotationData()
{
AZ::EntityId assetNodeId = GetRuntimeBus()->FindAssetNodeIdByRuntimeNodeId(GetEntityId());
return AnnotateNodeSignal(CreateGraphInfo(GetOwningScriptCanvasId(), GetGraphIdentifier()), AnnotateNodeSignal::AnnotationLevel::Info, m_variableName, AZ::NamedEntityId(assetNodeId, GetNodeName()));
}
VariableId GetVariableNode::GetVariableIdRead(const Slot*) const
{
return m_variableId;
@@ -64,7 +64,6 @@ namespace ScriptCanvas
void OnInit() override;
void OnPostActivate() override;
void OnInputSignal(const SlotId&) override;
void AddOutputSlot();
void RemoveOutputSlot();
@@ -78,8 +77,6 @@ namespace ScriptCanvas
void OnVariableRemoved() override;
////
AnnotateNodeSignal CreateAnnotationData();
// Adds/Remove Property Slots from the GetVariable node
void AddPropertySlots(const Data::Type& type);
void ClearPropertySlots();
@@ -11,105 +11,6 @@
namespace ScriptCanvas
{
int CountMatchingInputTypes(const Grammar::FunctionPrototype& a, const Grammar::FunctionPrototype& b, const AZStd::vector<size_t>& checkedIndices)
{
AZ_Warning("ScriptCanvas", a.m_inputs.size() == b.m_inputs.size(), "Function inputs are not the same size");
int matching = 0;
if (a.m_inputs.size() == b.m_inputs.size())
{
if (checkedIndices.empty())
{
for (size_t index = 0; index < a.m_inputs.size(); ++index)
{
if (!a.m_inputs[index]->m_datum.GetType().IsValid()
|| a.m_inputs[index]->m_datum.GetType() == b.m_inputs[index]->m_datum.GetType())
{
++matching;
}
}
}
else
{
for (const auto checkedIndex : checkedIndices)
{
const auto index = checkedIndices[checkedIndex];
if (index < a.m_inputs.size())
{
if (!a.m_inputs[index]->m_datum.GetType().IsValid()
|| a.m_inputs[index]->m_datum.GetType() == b.m_inputs[index]->m_datum.GetType())
{
++matching;
}
}
else
{
AZ_Error("ScriptCanvas", false, "Overload checked index is no longer valid");
}
}
}
}
return matching;
}
BehaviorContextMethodHelper::CallResult BehaviorContextMethodHelper::Call(Node& node, bool isExpectingMultipleResults, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, AZStd::vector<SlotId>& resultSlotIds)
{
if (isExpectingMultipleResults)
{
return BehaviorContextMethodHelper::Call(node, method, paramBegin, paramEnd, resultSlotIds);
}
else
{
return BehaviorContextMethodHelper::Call(node, method, paramBegin, paramEnd, resultSlotIds[0]);
}
}
BehaviorContextMethodHelper::CallResult BehaviorContextMethodHelper::Call(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, SlotId resultSlotId)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Method::OnInputSignal::Call %s", method->m_name.c_str());
return CallGeneric(node, method, paramBegin, paramEnd, &AttemptCallWithResults, resultSlotId);
}
BehaviorContextMethodHelper::CallResult BehaviorContextMethodHelper::Call(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, AZStd::vector<SlotId>& resultSlotIds)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Method::OnInputSignal::Call %s", method->m_name.c_str());
return CallGeneric(node, method, paramBegin, paramEnd, &AttemptCallWithTupleResults, resultSlotIds);
}
AZ::Outcome<BehaviorContextMethodHelper::CallResult, AZStd::string> BehaviorContextMethodHelper::AttemptCallWithResults(Node&, const AZ::BehaviorMethod*, AZ::BehaviorValueParameter*, unsigned int, SlotId)
{
return AZ::Failure(AZStd::string("This method is slated for deletion"));
}
AZ::Outcome<BehaviorContextMethodHelper::CallResult, AZStd::string> BehaviorContextMethodHelper::AttemptCallWithTupleResults(Node&, const AZ::BehaviorMethod*, AZ::BehaviorValueParameter*, unsigned int, AZStd::vector<SlotId>)
{
return AZ::Failure(AZStd::string("This method is slated for deletion"));
}
AZ::Outcome<Datum, AZStd::string> BehaviorContextMethodHelper::CallTupleGetMethod(const AZ::BehaviorMethod*, Datum&)
{
return AZ::Failure(AZStd::string("This method is slated for deletion"));
}
AZ::Outcome<BehaviorContextMethodHelper::CallResult, AZStd::string> BehaviorContextMethodHelper::CallOutcomeTupleMethod(Node&, const SlotId&, Datum&, size_t, AZStd::string)
{
return AZ::Failure(AZStd::string("to be deleted"));
}
AZ::BehaviorValueParameter BehaviorContextMethodHelper::ToBehaviorValueParameter(const AZ::BehaviorMethod* method, size_t index, const Datum& datum)
{
const AZ::BehaviorParameter* datumParam = method->GetArgument(index);
auto toParamOutcome = datumParam ? datum.ToBehaviorValueParameter(*datumParam) : AZ::Failure(AZStd::string::format("BehaviorMethod contains nullptr BehaviorParameter at index %zu", index));
if (toParamOutcome)
{
return AZ::BehaviorValueParameter(toParamOutcome.TakeValue());
}
return AZ::BehaviorValueParameter();
}
AZStd::unordered_map<size_t, const AZ::BehaviorMethod*> GetTupleGetMethodsFromResult(const AZ::BehaviorMethod& method)
{
if (method.HasResult())
@@ -19,202 +19,9 @@ namespace ScriptCanvas::Grammar
namespace ScriptCanvas
{
int CountMatchingInputTypes(const Grammar::FunctionPrototype& a, const Grammar::FunctionPrototype& b, const AZStd::vector<size_t>& checkedIndices);
struct BehaviorContextMethodHelper
{
enum BehaviorContextInputOutput : size_t
{
MaxCount = 40,
};
enum class MethodCallStatus
{
NotAttempted = 0,
Attempted,
Failed,
Succeeded,
};
struct CallResult
{
const MethodCallStatus m_status = MethodCallStatus::NotAttempted;
const AZStd::string m_executionOutOverride = "Out";
AZ_INLINE CallResult(const MethodCallStatus status, AZStd::string executionOutOverride = "Out")
: m_status(status)
, m_executionOutOverride(executionOutOverride)
{}
};
template<typename t_Call, typename t_Slots>
static CallResult CallGeneric(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, t_Call attempt, t_Slots& slots);
static CallResult Call(Node& node, bool isExpectingMultipleResults, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, AZStd::vector<SlotId>& resultSlotIds);
static CallResult Call(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, SlotId resultSlotId);
static CallResult Call(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, AZStd::vector<SlotId>& resultSlotIds);
static AZ::Outcome<CallResult, AZStd::string> AttemptCallWithResults(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* params, unsigned int numExpectedArgs, SlotId resultSlotId);
static AZ::Outcome<CallResult, AZStd::string> AttemptCallWithTupleResults(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* params, unsigned int numExpectedArgs, AZStd::vector<SlotId> resultSlotIds);
template<typename ... Args>
static AZ::Outcome<Datum, AZStd::string> CallMethodOnDatum(const Datum& input, AZStd::string_view methodName, Args&& ... args);
template<typename ... Args>
static AZ::Outcome<Datum, AZStd::string> CallMethodOnDatumUnpackOutcomeSuccess(const Datum& input, AZStd::string_view methodName, Args&& ... args);
template<typename ... Args>
static AZStd::vector<AZ::BehaviorValueParameter> CreateParameterList(const AZ::BehaviorMethod* method, Args&&... args);
static AZ::Outcome<Datum, AZStd::string> CallTupleGetMethod(const AZ::BehaviorMethod* method, Datum& thisPointer);
private:
static AZ::Outcome<CallResult, AZStd::string> CallOutcomeTupleMethod(Node& node, const SlotId& resultSlotId, Datum& outcomeDatum, size_t index, AZStd::string outSlotName);
static AZ::BehaviorValueParameter ToBehaviorValueParameter(const AZ::BehaviorMethod* method, size_t index, const Datum& datum);
template <typename T>
static AZ::BehaviorValueParameter ToBehaviorValueParameter(const AZ::BehaviorMethod*, size_t, const T& arg);
template<typename ... Args, size_t ... Indices>
static AZStd::vector<AZ::BehaviorValueParameter> CreateParameterListInternal(const AZ::BehaviorMethod* method, AZStd::index_sequence<Indices...>, Args&&... args);
};
AZStd::unordered_map<size_t, const AZ::BehaviorMethod*> GetTupleGetMethodsFromResult(const AZ::BehaviorMethod& method);
AZStd::unordered_map<size_t, const AZ::BehaviorMethod*> GetTupleGetMethods(const AZ::TypeId& typeId);
AZ::Outcome<const AZ::BehaviorMethod*, void> GetTupleGetMethod(const AZ::TypeId& typeID, size_t index);
template<typename t_Call, typename t_Slots>
BehaviorContextMethodHelper::CallResult BehaviorContextMethodHelper::CallGeneric(Node& node, const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* paramBegin, AZ::BehaviorValueParameter* paramEnd, t_Call attempt, t_Slots& slots)
{
const auto numExpectedArgs(static_cast<unsigned int>(method->GetNumArguments()));
if ((paramEnd - paramBegin) == numExpectedArgs)
{
AZ::Outcome<CallResult, AZStd::string> withResultsOutcome = attempt(node, method, paramBegin, numExpectedArgs, slots);
if (!withResultsOutcome.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((node), "Script Canvas attempt to call %s with a result failed: %s", method->m_name.data(), withResultsOutcome.GetError().data());
return CallResult(MethodCallStatus::Failed);
}
else if (withResultsOutcome.GetValue().m_status == MethodCallStatus::Attempted)
{
return CallResult(MethodCallStatus::Succeeded, withResultsOutcome.GetValue().m_executionOutOverride);
}
else if (method->Call(paramBegin, numExpectedArgs))
{
return CallResult(MethodCallStatus::Succeeded);
}
else
{
SCRIPTCANVAS_REPORT_ERROR((node), "Script Canvas attempt to call %s failed", method->m_name.data());
return CallResult(MethodCallStatus::Failed);
}
}
else
{
SCRIPTCANVAS_REPORT_ERROR((node), "Script Canvas attempt to call %s failed, it expects %d args but called with %d", method->m_name.c_str(), numExpectedArgs, paramEnd - paramBegin);
return CallResult(MethodCallStatus::NotAttempted);
}
}
template<typename ... Args>
AZ::Outcome<Datum, AZStd::string> BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(const Datum& input, AZStd::string_view methodName, Args&& ... args)
{
AZ::Outcome<Datum, AZStd::string> methodCallResult = CallMethodOnDatum(input, methodName, args...);
if (methodCallResult.IsSuccess())
{
// Even when successfully called, the method will return an outcome as the result, we need to test that
// outcome in case any errors were returned from the invoked function call.
const Datum& methodCallResultDatum = methodCallResult.GetValue();
const auto* actualOutcome = methodCallResultDatum.GetAs<AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string>>();
if (actualOutcome && !actualOutcome->IsSuccess())
{
return AZ::Failure(AZStd::string::format("%s returned an error: %s", methodName.data(), actualOutcome->GetError().c_str()));
}
AZ::Outcome<Datum, AZStd::string> isSuccessCallResult = CallMethodOnDatum(methodCallResult.GetValue(), "IsSuccess");
if (isSuccessCallResult.IsSuccess())
{
if (*isSuccessCallResult.GetValue().GetAs<bool>())
{
return CallMethodOnDatum(methodCallResult.GetValue(), "GetValue");
}
else
{
return AZ::Failure(AZStd::string::format("%s returned an error", methodName.data()));
}
}
else
{
return AZ::Failure(AZStd::string::format("Script Canvas attempt to call %s failed, Failed to query result Outcome success", methodName.data()));
}
}
else
{
return AZ::Failure(methodCallResult.GetError());
}
return methodCallResult;
}
template<typename ... Args>
AZ::Outcome<Datum, AZStd::string> BehaviorContextMethodHelper::CallMethodOnDatum(const Datum& input, AZStd::string_view methodName, Args&& ... args)
{
const AZ::BehaviorClass* behaviorClass = AZ::BehaviorContextHelper::GetClass(input.GetType().GetAZType());
if (behaviorClass)
{
auto methodIt = behaviorClass->m_methods.find(methodName);
if (methodIt != behaviorClass->m_methods.end())
{
AZ::BehaviorMethod* method = methodIt->second;
const AZ::BehaviorParameter* resultType = method->HasResult() ? method->GetResult() : nullptr;
if (resultType)
{
// Populate parameters
AZStd::vector<AZ::BehaviorValueParameter> parameters = CreateParameterList(method, input, AZStd::forward<Args>(args)...);
return Datum::CallBehaviorContextMethodResult(method, resultType, parameters.begin(), (unsigned int)AZStd::GetMin(parameters.size(), method->GetNumArguments()), behaviorClass->m_name);
}
else
{
AZStd::vector<AZ::BehaviorValueParameter> parameters = CreateParameterList(method, input, AZStd::forward<Args>(args)...);
if (Datum::CallBehaviorContextMethod(method, parameters.begin(), (unsigned int)AZStd::GetMin(parameters.size(), method->GetNumArguments())).IsSuccess())
{
return AZ::Success(Datum());
}
}
}
else
{
return AZ::Failure(AZStd::string::format("ScriptCanvas Behavior Context method call failed; method named \"%s\" not found.", methodName.data()));
}
}
return AZ::Failure(AZStd::string::format("ScriptCanvas Behavior Context method call failed; unable to retrieve Behavior Class."));
}
template<typename ... Args>
AZStd::vector<AZ::BehaviorValueParameter> BehaviorContextMethodHelper::CreateParameterList(const AZ::BehaviorMethod* method, Args&&... args)
{
// Create an index sequence for the parameters and forward the arguments
return CreateParameterListInternal(method, AZStd::make_index_sequence<sizeof...(Args)>{}, AZStd::forward<Args>(args)...);
}
template <typename T>
AZ::BehaviorValueParameter BehaviorContextMethodHelper::ToBehaviorValueParameter(const AZ::BehaviorMethod*, size_t, const T& arg)
{
return AZ::BehaviorValueParameter(&arg);
}
template<typename ... Args, size_t ... Indices>
AZStd::vector<AZ::BehaviorValueParameter> BehaviorContextMethodHelper::CreateParameterListInternal(const AZ::BehaviorMethod* method, AZStd::index_sequence<Indices...>, Args&&... args)
{
// Unpack the arguments and the index sequence to populate the parameter list
return { ToBehaviorValueParameter(method, Indices, args)... };
}
}
@@ -12,8 +12,8 @@
#include <AzCore/Component/TickBus.h>
#include <AzCore/Asset/AssetManager.h>
#include <ScriptCanvas/Core/GraphBus.h>
#include <ScriptCanvas/Execution/ErrorBus.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.h>
#include <ScriptCanvas/Utils/VersionConverters.h>
@@ -75,7 +75,7 @@ namespace ScriptCanvas
AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, asset.GetId());
AZStd::string graphAssetName;
RuntimeRequestBus::EventResult(graphAssetName, GetOwningScriptCanvasId(), &RuntimeRequests::GetAssetName);
GraphRequestBus::EventResult(graphAssetName, GetOwningScriptCanvasId(), &GraphRequests::GetAssetName);
AZ_Error("Script Event", false, "The Script Event asset (%s) has been modified. Open the graph (%s) and re-save it.", assetInfo.m_relativePath.c_str(), graphAssetName.c_str());
return;
@@ -325,197 +325,16 @@ namespace ScriptCanvas
}
}
void ReceiveScriptEvent::OnEvent(const char* eventName, const int, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ReceiveScriptEvent::OnEvent %s", eventName);
SCRIPTCANVAS_RETURN_IF_ERROR_STATE((*this));
ScriptEvents::Method method;
if (!GetScriptEvent().FindMethod(eventName, method))
{
AZ_Warning("Script Events", false, "Failed to find method: %s when trying to handle it.", eventName);
return;
}
auto iter = m_eventMap.find(AZ::Crc32(method.GetNameProperty().GetId().ToString<AZStd::string>().c_str()));
if (iter == m_eventMap.end())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Invalid event index in Ebus handler");
return;
}
Internal::ScriptEventEntry& scriptEventEntry = iter->second;
if (!scriptEventEntry.m_shouldHandleEvent || scriptEventEntry.m_isHandlingEvent)
{
AZ_Warning("ScriptCanvas", !scriptEventEntry.m_isHandlingEvent, "Found situation where in handling event(%s::%s) triggered the same event. Possible infinite loop, not handling second call.", GetScriptEvent().GetName().c_str(), eventName);
return;
}
scriptEventEntry.m_isHandlingEvent = true;
scriptEventEntry.m_resultEvaluated = !scriptEventEntry.IsExpectingResult();
// route the parameters to the connect nodes input
if (scriptEventEntry.m_parameterSlotIds.size() != numParameters)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "The Script Event, %s, has %d parameters. While the ScriptCanvas Node (%s) has (%zu) slots. Make sure the node is updated in the Script Canvas graph.", eventName, numParameters, GetNodeName().c_str(), scriptEventEntry.m_parameterSlotIds.size());
}
else
{
for (int parameterIndex(0); parameterIndex < numParameters; ++parameterIndex)
{
const Slot* slot = GetSlot(scriptEventEntry.m_parameterSlotIds[parameterIndex]);
const auto& value = *(parameters + parameterIndex);
const Datum input(value);
if (slot->IsTypeMatchFor(input.GetType()))
{
PushOutput(input, *slot);
}
else
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Type mismatch in Script Event %s on ScriptCanvas Node (%s). Make sure the nodes is updated in the Script Canvas graph", eventName, GetNodeName().c_str());
}
}
}
{
// now, this should pass execution off to the nodes that will push their output into this result input
SignalOutput(scriptEventEntry.m_eventSlotId, ExecuteMode::UntilNodeIsFoundInStack);
}
// route executed nodes output to my input, and my input to the result
if (scriptEventEntry.IsExpectingResult())
{
if (result)
{
if (const Datum* resultInput = FindDatum(scriptEventEntry.m_resultSlotId))
{
scriptEventEntry.m_resultEvaluated = resultInput->ToBehaviorContext(*result);
AZ_Warning("Script Canvas", scriptEventEntry.m_resultEvaluated, "%s expects a result value of type %s to be provided, got %s", scriptEventEntry.m_eventName.c_str(), Data::GetName(resultInput->GetType()).c_str(), result->m_name);
}
else
{
AZ_Warning("Script Canvas", false, "Script Canvas handler expecting a result, but had no ability to return it");
}
}
else
{
AZ_Warning("Script Canvas", false, "Script Canvas handler is expecting a result, but was called without receiving one!");
}
}
else
{
AZ_Warning("Script Canvas", !result, "Script Canvas handler is not expecting a result, but was called receiving one!");
}
// route executed nodes output to my input, and my input to the result
AZ_Warning("Script Canvas", (result != nullptr) == scriptEventEntry.IsExpectingResult(), "Node %s-%s mismatch between expecting a result and getting one!", m_ebus->m_name.c_str(), scriptEventEntry.m_eventName.c_str());
AZ_Warning("Script Canvas", scriptEventEntry.m_resultEvaluated, "Node %s-%s result not evaluated properly!", m_ebus->m_name.c_str(), scriptEventEntry.m_eventName.c_str());
scriptEventEntry.m_isHandlingEvent = false;
}
void ReceiveScriptEvent::OnActivate()
{
SetAutoConnectToGraphOwner(m_autoConnectToGraphOwner);
ScriptEventBase::OnActivate();
}
void ReceiveScriptEvent::OnPostActivate()
{
}
void ReceiveScriptEvent::OnDeactivate()
{
Disconnect(false);
ScriptEventBase::OnDeactivate();
}
void ReceiveScriptEvent::Connect()
{
AZ::EntityId connectToEntityId;
AZ::BehaviorValueParameter busIdParameter;
busIdParameter.Set(m_ebus->m_idParam);
const AZ::Uuid busIdType = m_ebus->m_idParam.m_typeId;
const Datum* busIdDatum = IsIDRequired() ? FindDatum(GetSlotId(c_busIdName)) : nullptr;
if (busIdDatum && !busIdDatum->Empty())
{
if (busIdDatum->IS_A(Data::FromAZType(busIdType)) || busIdDatum->IsConvertibleTo(Data::FromAZType(busIdType)))
{
auto busIdOutcome = busIdDatum->ToBehaviorValueParameter(m_ebus->m_idParam);
if (busIdOutcome.IsSuccess())
{
busIdParameter = busIdOutcome.TakeValue();
}
}
if (busIdType == azrtti_typeid<AZ::EntityId>())
{
if (auto busEntityId = busIdDatum->GetAs<AZ::EntityId>())
{
if (!busEntityId->IsValid() || *busEntityId == ScriptCanvas::GraphOwnerId)
{
RuntimeRequestBus::EventResult(connectToEntityId, GetOwningScriptCanvasId(), &RuntimeRequests::GetRuntimeEntityId);
busIdParameter.m_value = &connectToEntityId;
}
}
}
}
if (!IsIDRequired() || busIdParameter.GetValueAddress())
{
if (m_connected)
{
// Ensure we disconnect if this bus is already connected, this could happen if a different bus Id is provided
// and this node is connected through the Connect slot.
m_handler->Disconnect();
}
AZ_VerifyError("Script Canvas", m_handler->Connect(&busIdParameter),
"Unable to connect to EBus with BusIdType %s. The BusIdType of the Script Event (%s) does not match the BusIdType provided.",
busIdType.ToString<AZStd::string>().data(), m_definition.GetName().c_str());
m_connected = true;
}
}
void ReceiveScriptEvent::CompleteDisconnection()
{
m_handler->Disconnect();
m_connected = false;
if (IsActivated())
{
SlotId onDisconnectSlotId = ReceiveScriptEventProperty::GetOnDisconnectedSlotId(this);
SignalOutput(onDisconnectSlotId);
}
}
void ReceiveScriptEvent::Disconnect(bool queueDisconnect)
{
if (m_connected && m_handler)
{
if (queueDisconnect)
{
AZ::SystemTickBus::QueueFunction(
[this]()
{
CompleteDisconnection();
}
);
}
else
{
CompleteDisconnection();
}
}
}
}
const Internal::ScriptEventEntry* ReceiveScriptEvent::FindEventWithSlot(const Slot& slot) const
{
@@ -771,51 +590,6 @@ namespace ScriptCanvas
return true;
}
void ReceiveScriptEvent::OnInputSignal(const SlotId& slotId)
{
SlotId connectSlot = ReceiveScriptEventProperty::GetConnectSlotId(this);
if (connectSlot == slotId)
{
const Datum* busIdDatum = FindDatum(GetSlotId(c_busIdName));
if (IsIDRequired() && (!busIdDatum || busIdDatum->Empty()))
{
SlotId failureSlot = ReceiveScriptEventProperty::GetOnFailureSlotId(this);
SignalOutput(failureSlot);
SCRIPTCANVAS_REPORT_ERROR((*this), "In order to connect this node, a valid BusId must be provided.");
return;
}
else
{
Connect();
SlotId onConnectSlotId = ReceiveScriptEventProperty::GetOnConnectedSlotId(this);
SignalOutput(onConnectSlotId);
return;
}
}
SlotId disconnectSlot = ReceiveScriptEventProperty::GetDisconnectSlotId(this);
if (disconnectSlot == slotId)
{
Disconnect();
return;
}
}
void ReceiveScriptEvent::OnInputChanged(const Datum&, const SlotId&)
{
/*
if (GetExecutionType() == ExecutionType::Runtime
&& m_autoConnectToGraphOwner
&& slotId == FindSlotIdForDescriptor(c_busIdName, SlotDescriptors::DataIn()))
{
Disconnect(false);
Connect();
}
*/
}
bool ReceiveScriptEvent::IsOutOfDate(const VersionData& graphVersion) const
{
AZ_UNUSED(graphVersion);
@@ -87,16 +87,9 @@ namespace ScriptCanvas
private:
void Connect();
void Disconnect(bool queueDisconnect = true);
void CompleteDisconnection();
bool CreateEbus();
bool SetupHandler();
void OnInputSignal(const SlotId& slotId) override;
void OnInputChanged(const Datum& input, const SlotId& slotId) override;
AZ::BehaviorEBusHandler* m_handler = nullptr;
AZ::BehaviorEBus* m_ebus = nullptr;
AZStd::recursive_mutex m_mutex; // post-serialization
@@ -105,9 +98,6 @@ namespace ScriptCanvas
void InitializeEvent(AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> asset, int eventIndex, SlotIdMapping& populationMapping);
static void OnEventGenericHook(void* userData, const char* eventName, int eventIndex, AZ::BehaviorValueParameter* result, int numParameters, AZ::BehaviorValueParameter* parameters);
void OnEvent(const char* eventName, const int eventIndex, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters);
bool IsEventConnected(const Internal::ScriptEventEntry& entry) const;
Internal::ScriptEventEntry ConfigureEbusEntry(const ScriptEvents::Method& methodDefinition, const AZ::BehaviorEBusHandler::BusForwarderEvent& event, SlotIdMapping& populationMapping);
@@ -74,28 +74,6 @@ namespace ScriptCanvas
}
}
}
void Repeater::OnInputSignal(const SlotId&)
{
m_repetionCount = aznumeric_cast<int>(RepeaterProperty::GetRepetitions(this));
if (m_repetionCount > 0)
{
StartTimer();
}
}
void Repeater::OnTimeElapsed()
{
m_repetionCount--;
SignalOutput(RepeaterProperty::GetActionSlotId(this), ScriptCanvas::ExecuteMode::UntilNodeIsFoundInStack);
if (m_repetionCount == 0)
{
StopTimer();
SignalOutput(RepeaterProperty::GetCompleteSlotId(this));
}
}
}
}
}
@@ -17,6 +17,7 @@ namespace ScriptCanvas
namespace Core
{
//! A node that repeats an execution signal over the specified time
//! Deprecated for nodeable version
class Repeater
: public ScriptCanvas::Nodes::Internal::BaseTimerNode
{
@@ -27,18 +28,11 @@ namespace ScriptCanvas
void OnInit() override;
void OnInputSignal(const SlotId& slotId) override;
void OnTimeElapsed();
const char* GetTimeSlotFormat() const override { return "Delay (%s)"; }
const char* GetBaseTimeSlotName() const override { return "Interval"; }
const char* GetBaseTimeSlotToolTip() const override { return "The Interval between repetitions"; }
protected:
bool AllowInstantResponse() const override { return true; }
int m_repetionCount;
};
}
@@ -10,8 +10,6 @@
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/Utils.h>
#include <AzCore/Component/TickBus.h>
#include <ScriptCanvas/Execution/RuntimeBus.h>
#include <AzCore/Asset/AssetManager.h>
#include <ScriptEvents/ScriptEventsAsset.h>
@@ -106,9 +106,7 @@ namespace ScriptCanvas
AZStd::pair<AZ::Data::Asset<ScriptEvents::ScriptEventsAsset>, bool> IsAssetOutOfDate() const;
virtual void Initialize(const AZ::Data::AssetId assetId);
virtual void Initialize(const AZ::Data::AssetId assetId);
protected:
@@ -28,64 +28,6 @@ namespace ScriptCanvas
ScriptEvents::ScriptEventNotificationBus::Handler::BusDisconnect();
}
void SendScriptEvent::OnInputSignal(const SlotId&)
{
if (!m_method)
{
if (!m_asset.IsReady())
{
m_asset = AZ::Data::AssetManager::Instance().GetAsset<ScriptEvents::ScriptEventsAsset>(m_scriptEventAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
}
CreateSender(m_asset);
}
if (!m_method)
{
AZStd::string error = AZStd::string::format("Script Event sender node called with no initialized method (%s::%s)!", m_busName.c_str(), m_eventName.c_str());
SCRIPTCANVAS_REPORT_ERROR((*this), error.c_str());
}
if (m_method)
{
Node::DatumVector inputDatums = GatherDatumsForDescriptor(SlotDescriptors::DataIn());
if (m_method->GetNumArguments() != inputDatums.size())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "The Script Event %s number of parameters %d do not correspond to the number of slots %zu in the Script Canvas node (%s). Make sure the node is updated in the Script Canvas graph.", m_method->m_name.c_str(), m_method->GetNumArguments(), inputDatums.size(), GetNodeName().c_str());
return;
}
AZStd::array<AZ::BehaviorValueParameter, BehaviorContextMethodHelper::MaxCount> params;
AZ::BehaviorValueParameter* paramFirst(params.begin());
AZ::BehaviorValueParameter* paramIter = paramFirst;
{
// all input should have been pushed into this node already
int argIndex(0);
for (const Datum* datum : inputDatums)
{
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> inputParameter = datum->ToBehaviorValueParameter(*m_method->GetArgument(argIndex));
if (!inputParameter.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "BehaviorContext method input problem at parameter index %d: %s", argIndex, inputParameter.GetError().data());
return;
}
paramIter->Set(inputParameter.GetValue());
++paramIter;
++argIndex;
}
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::ScriptEvents::OnInputSignal::Call %s::%s", m_busName.c_str(), m_eventName.c_str());
{
BehaviorContextMethodHelper::Call(*this, m_method, paramFirst, paramIter, m_resultSlotID);
}
}
}
SignalOutput(GetSlotId("Out"));
}
ScriptCanvas::EBusBusId SendScriptEvent::GetBusId() const
{
return m_busId;
@@ -155,11 +97,6 @@ namespace ScriptCanvas
AZ::Outcome<void, AZStd::string> IsExposable(const AZ::BehaviorMethod& method)
{
if (method.GetNumArguments() > BehaviorContextMethodHelper::MaxCount)
{
return AZ::Failure(AZStd::string("Too many arguments for a Script Canvas method"));
}
for (size_t argIndex(0), sentinel(method.GetNumArguments()); argIndex != sentinel; ++argIndex)
{
if (const AZ::BehaviorParameter* argument = method.GetArgument(argIndex))
@@ -79,11 +79,7 @@ namespace ScriptCanvas
bool IsConfigured() const { return m_method != nullptr; }
void ConfigureMethod(AZ::BehaviorMethod& method);
bool RegisterScriptEvent(AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> asset);
void OnInputSignal(const SlotId&) override;
void AddInputSlot(size_t slotIndex, size_t argIndex, const AZStd::string_view argName, const AZStd::string_view tooltip, AZ::BehaviorMethod* method, const AZ::BehaviorParameter* argument, AZ::Uuid slotKey, SlotIdMapping& populationMapping);
void OnRegistered(const ScriptEvents::ScriptEvent&) override;
SlotId m_resultSlotID;
@@ -59,47 +59,6 @@ namespace ScriptCanvas
}
}
void SetVariableNode::OnInputSignal(const SlotId& slotID)
{
if (slotID == GetSlotId(GetInputSlotName()))
{
const Datum* sourceDatum = FindDatum(m_variableDataInSlotId);
if (sourceDatum && m_variableView.IsValid())
{
m_variableView.AssignToDatum((*sourceDatum));
SC_EXECUTION_TRACE_VARIABLE_CHANGE((m_variableId), (CreateVariableChange((*m_variableView.GetDatum()), m_variableId)));
}
Slot* resultSlot = GetSlot(m_variableDataOutSlotId);
if (resultSlot && m_variableView.IsValid())
{
const Datum* variableDatum = m_variableView.GetDatum();
PushOutput((*variableDatum), *resultSlot);
// Push the data for each property slot out as well
for (auto&& propertyAccount : m_propertyAccounts)
{
Slot* propertySlot = GetSlot(propertyAccount.m_propertySlotId);
if (propertySlot && propertyAccount.m_getterFunction)
{
auto outputOutcome = propertyAccount.m_getterFunction((*variableDatum));
if (!outputOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), outputOutcome.TakeError().data());
return;
}
PushOutput(outputOutcome.TakeValue(), *propertySlot);
}
}
}
SignalOutput(GetSlotId(GetOutputSlotName()));
}
}
VariableId SetVariableNode::GetVariableIdRead(const Slot*) const
{
return m_variableId;
@@ -283,7 +242,8 @@ namespace ScriptCanvas
ScriptCanvas::Data::Type baseType = ScriptCanvas::Data::Type::Invalid();
VariableRequestBus::EventResult(baseType, GetScopedVariableId(), &VariableRequests::GetType);
const AZStd::unordered_map<VariableId, GraphVariable>* variableMap = GetRuntimeBus()->GetVariables();
const GraphVariableMapping* variableMap = nullptr;
GraphRequestBus::EventResult(variableMap, *GraphNotificationBus::GetCurrentBusId(), &GraphRequests::GetVariables);
if (variableMap && baseType.IsValid())
{
@@ -319,12 +279,6 @@ namespace ScriptCanvas
VariableNodeNotificationBus::Event(GetEntityId(), &VariableNodeNotifications::OnVariableRemovedFromNode, removedVariableId);
}
AnnotateNodeSignal SetVariableNode::CreateAnnotationData()
{
AZ::EntityId assetNodeId = GetRuntimeBus()->FindAssetNodeIdByRuntimeNodeId(GetEntityId());
return AnnotateNodeSignal(CreateGraphInfo(GetOwningScriptCanvasId(), GetGraphIdentifier()), AnnotateNodeSignal::AnnotationLevel::Info, m_variableName, AZ::NamedEntityId(assetNodeId, GetNodeName()));
}
void SetVariableNode::AddPropertySlots(const Data::Type& type)
{
Data::GetterContainer getterFunctions = Data::ExplodeToGetters(type);
@@ -67,8 +67,7 @@ namespace ScriptCanvas
void OnInit() override;
void OnPostActivate() override;
void OnInputSignal(const SlotId&) override;
void AddSlots();
void RemoveSlots();
void AddPropertySlots(const Data::Type& type);
@@ -86,8 +85,6 @@ namespace ScriptCanvas
void OnVariableRemoved() override;
////
AnnotateNodeSignal CreateAnnotationData();
VariableId m_variableId;
SlotId m_variableDataInSlotId;
@@ -1,25 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Start.h"
#include <ScriptCanvas/Core/GraphBus.h>
#include <ScriptCanvas/Grammar/Primitives.h>
namespace ScriptCanvas
{
namespace Nodes
{
namespace Core
{
void Start::OnInputSignal(const SlotId&)
{
SignalOutput(StartProperty::GetOutSlotId(this));
}
}
}
}
@@ -25,11 +25,6 @@ namespace ScriptCanvas
public:
SCRIPTCANVAS_NODE(Start);
void OnInputSignal(const SlotId&) override;
};
}
}
@@ -52,11 +52,6 @@ namespace ScriptCanvas
//////////////////////////////////////////////////////////////////////////
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<bool>() && *rhs.GetAs<bool>());
}
void InitializeBooleanExpression() override
{
{
@@ -60,12 +60,6 @@ namespace ScriptCanvas
RegisterExtension(visualExtensions);
}
}
void Any::OnInputSignal([[maybe_unused]] const SlotId& slotId)
{
const SlotId outSlotId = AnyProperty::GetOutSlotId(this);
SignalOutput(outSlotId);
}
SlotId Any::HandleExtension(AZ::Crc32 extensionId)
{
@@ -44,8 +44,6 @@ namespace ScriptCanvas
void OnInit() override;
void ConfigureVisualExtensions() override;
void OnInputSignal(const SlotId& slot) override;
SlotId HandleExtension(AZ::Crc32 extensionId) override;
bool CanDeleteSlot(const SlotId& slotId) const override;
@@ -54,9 +52,7 @@ namespace ScriptCanvas
////
/// Translation
bool IsNoOp() const override;
bool IsNoOp() const override;
AZ::Outcome<DependencyReport, void> GetDependencies() const override;
@@ -69,9 +65,7 @@ namespace ScriptCanvas
AZ::Crc32 GetInputExtensionId() const { return AZ_CRC("Output", 0xccde149e); }
private:
AZStd::string GenerateInputName(int counter);
SlotId AddInputSlot();
void FixupStateNames();
};
@@ -98,26 +98,6 @@ namespace ScriptCanvas
return AddSlot(executionConfiguration);
}
void Cycle::OnInputSignal(const SlotId& slot)
{
if (slot != CycleProperty::GetInSlotId(this))
{
return;
}
if (!m_orderedOutputSlots.empty())
{
const SlotId& slotId = m_orderedOutputSlots[m_executionSlot];
SignalOutput(slotId);
if (++m_executionSlot >= m_orderedOutputSlots.size())
{
m_executionSlot = 0;
}
}
}
void Cycle::OnSlotRemoved([[maybe_unused]] const SlotId& slotId)
{
FixupStateNames();
@@ -43,13 +43,9 @@ namespace ScriptCanvas
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& executionSlot, CombinedSlotType targetSlotType, const Slot* /*executionChildSlot*/) const override;
protected:
AZStd::string GetDisplayGroup() const { return "OutputGroup"; }
void OnInputSignal(const SlotId& slot) override;
void OnSlotRemoved(const SlotId& slotId) override;
private:
@@ -1,37 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Indexer.h"
namespace ScriptCanvas
{
namespace Nodes
{
namespace Logic
{
void Indexer::OnInputSignal(const SlotId& slotId)
{
auto slotIndex = FindSlotIndex(slotId);
if (slotIndex < 0)
{
AZ_Warning("Script Canvas", false, "Could not find slot with id %s", slotId.ToString().c_str());
return;
}
const Datum output(slotIndex);
const SlotId outSlotId = IndexerProperty::GetOutSlotId(this);
if (auto outSlot = GetSlot(outSlotId))
{
PushOutput(output, *outSlot);
}
SignalOutput(outSlotId);
}
}
}
}
@@ -21,16 +21,8 @@ namespace ScriptCanvas
class Indexer
: public Node
{
public:
SCRIPTCANVAS_NODE(Indexer);
Indexer() = default;
protected:
void OnInputSignal(const SlotId& slot) override;
};
}
}
@@ -61,13 +61,6 @@ namespace ScriptCanvas
AddSlot(slotConfiguration);
}
}
void IsNull::OnInputSignal(const SlotId&)
{
const bool isNull = FindDatum(GetSlotId("Reference"))->Empty();
PushOutput(Datum(isNull), *GetSlot(GetSlotId("Is Null")));
SignalOutput(isNull ? IsNullProperty::GetTrueSlotId(this) : IsNullProperty::GetFalseSlotId(this));
}
}
}
}
@@ -34,8 +34,6 @@ namespace ScriptCanvas
bool IsIfBranchPrefacedWithBooleanExpression() const override;
protected:
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot&, CombinedSlotType targetSlotType, const Slot*) const override
{
@@ -43,9 +41,6 @@ namespace ScriptCanvas
}
void OnInit() override;
void OnInputSignal(const SlotId&) override;
};
}
}
@@ -1,42 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Multiplexer.h"
namespace ScriptCanvas
{
namespace Nodes
{
namespace Logic
{
Multiplexer::Multiplexer()
{}
void Multiplexer::OnInputSignal(const SlotId& slotId)
{
auto slotIndex = FindSlotIndex(slotId);
if (!slotIndex)
{
AZ_Warning("Script Canvas", false, "Could not find slot with Id %s", slotId.ToString().c_str());
return;
}
// These are generated from CodeGen, they essentially
// check if there's anything connected on the slot and
// they assign the local member with the value, otherwise
// they use the default property value.
const AZ::s64 selectedIndex = MultiplexerProperty::GetIndex(this);
if (selectedIndex == slotIndex)
{
const SlotId outSlotId = MultiplexerProperty::GetOutSlotId(this);
SignalOutput(outSlotId);
}
}
}
}
}
@@ -26,12 +26,6 @@ namespace ScriptCanvas
SCRIPTCANVAS_NODE(Multiplexer);
Multiplexer();
protected:
void OnInputSignal(const SlotId& slot) override;
};
}
}
@@ -50,11 +50,6 @@ namespace ScriptCanvas
//////////////////////////////////////////////////////////////////////////
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<bool>() || *rhs.GetAs<bool>());
}
void InitializeBooleanExpression() override
{
{
@@ -107,50 +107,6 @@ namespace ScriptCanvas
}
}
void Sequencer::OnInputSignal(const SlotId& slot)
{
m_selectedIndex = SequencerProperty::GetIndex(this);
m_order = SequencerProperty::GetOrder(this);
const SlotId inSlot = SequencerProperty::GetInSlotId(this);
const SlotId nextSlot = SequencerProperty::GetNextSlotId(this);
if (slot == inSlot)
{
m_currentIndex = m_selectedIndex;
}
else if (slot == nextSlot)
{
int step = m_order == Order::Forward ? 1 : -1;
m_outputIsValid = false;
int startIndex = m_currentIndex;
while (!m_outputIsValid)
{
m_currentIndex = (m_currentIndex + step + NUMBER_OF_OUTPUTS) % NUMBER_OF_OUTPUTS;
SlotId outSlotId = GetCurrentSlotId();
Slot* outSlot = GetSlot(outSlotId);
if (outSlot)
{
m_outputIsValid = !GetConnectedNodes(*outSlot).empty();
}
//Avoid infinite loop when none of the outputs or only the current output connects to other nodes.
if (m_currentIndex == startIndex)
{
m_outputIsValid = false;
break;
}
}
}
if (m_outputIsValid)
{
SlotId outSlotId = GetCurrentSlotId();
SignalOutput(outSlotId);
}
}
SlotId Sequencer::GetCurrentSlotId() const
{
AZStd::string slotName = "Out" + AZStd::to_string(m_currentIndex);
@@ -43,10 +43,6 @@ namespace ScriptCanvas
int m_order;
int m_selectedIndex;
protected:
void OnInputSignal(const SlotId& slot) override;
private:
int m_currentIndex;
bool m_outputIsValid;
@@ -71,31 +71,6 @@ namespace ScriptCanvas
return AddSlot(executionConfiguration);
}
void TargetedSequencer::OnInputSignal(const SlotId& slot)
{
if (slot != TargetedSequencerProperty::GetInSlotId(this))
{
return;
}
int targetIndex = TargetedSequencerProperty::GetIndex(this);
if (targetIndex < 0
|| targetIndex >= m_numOutputs)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Switch node was given an out of bound index.");
return;
}
AZStd::string slotName = GenerateOutputName(targetIndex);
SlotId outSlotId = GetSlotId(slotName.c_str());
if (outSlotId.IsValid())
{
SignalOutput(outSlotId);
}
}
void TargetedSequencer::OnSlotRemoved([[maybe_unused]] const SlotId& slotId)
{
FixupStateNames();
@@ -54,7 +54,6 @@ namespace ScriptCanvas
AZStd::string GetDisplayGroup() const { return "OutputGroup"; }
void OnInputSignal(const SlotId& slot) override;
void OnSlotRemoved(const SlotId& slotId) override;
private:
@@ -131,63 +131,6 @@ namespace ScriptCanvas
return isValid;
}
void WeightedRandomSequencer::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = WeightedRandomSequencerProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
int runningTotal = 0;
AZStd::vector< WeightedStruct > weightedStructs;
weightedStructs.reserve(m_weightedPairings.size());
for (const WeightedPairing& weightedPairing : m_weightedPairings)
{
const Datum* datum = FindDatum(weightedPairing.m_weightSlotId);
if (datum)
{
WeightedStruct weightedStruct;
weightedStruct.m_executionSlotId = weightedPairing.m_executionSlotId;
if (datum->GetType().IS_A(ScriptCanvas::Data::Type::Number()))
{
int weight = aznumeric_cast<int>((*datum->GetAs<Data::NumberType>()));
runningTotal += weight;
weightedStruct.m_totalWeight = runningTotal;
}
weightedStructs.emplace_back(weightedStruct);
}
}
// We have no weights. So just trigger the first execution output
// Weighted pairings is controlled to never be empty.
if (runningTotal == 0)
{
if (!m_weightedPairings.empty())
{
SignalOutput(m_weightedPairings.front().m_executionSlotId);
}
return;
}
int weightedResult = MathNodeUtilities::GetRandomIntegral<int>(1, runningTotal);
for (const WeightedStruct& weightedStruct : weightedStructs)
{
if (weightedResult <= weightedStruct.m_totalWeight)
{
SignalOutput(weightedStruct.m_executionSlotId);
break;
}
}
}
}
SlotId WeightedRandomSequencer::HandleExtension(AZ::Crc32 extensionId)
{
auto weightedPairing = AddWeightedPair();
@@ -22,9 +22,7 @@ namespace ScriptCanvas
class WeightedRandomSequencer
: public Node
{
public:
SCRIPTCANVAS_NODE(WeightedRandomSequencer);
static void ReflectDataTypes(AZ::ReflectContext* reflectContext);
@@ -42,11 +40,7 @@ namespace ScriptCanvas
bool OnValidateNode(ValidationResults& validationResults);
void OnInputSignal(const SlotId& slot);
SlotId HandleExtension(AZ::Crc32 extensionId) override;
SlotId HandleExtension(AZ::Crc32 extensionId) override;
bool CanDeleteSlot(const SlotId& slotId) const override;
@@ -51,21 +51,6 @@ namespace ScriptCanvas
nodeConfig.m_type = AZ::Uuid("DC17E19F-3829-410D-9A0B-AD60C6066DAA");
return nodeConfig;
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
const Data::NumberType lhsValue = *lhs.GetAs<Data::NumberType>();
const Data::NumberType rhsValue = *rhs.GetAs<Data::NumberType>();
if (AZ::IsClose(rhsValue, 0.0, 0.0001))
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Divide by zero");
return Datum();
}
return Datum(lhsValue / rhsValue);
}
};
}
@@ -50,12 +50,6 @@ namespace ScriptCanvas
nodeConfig.m_type = AZ::Uuid("E9BB45A1-AE96-47B0-B2BF-2927D420A28C");
return nodeConfig;
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<Data::NumberType>() * *rhs.GetAs<Data::NumberType>());
}
};
}
@@ -50,12 +50,6 @@ namespace ScriptCanvas
nodeConfig.m_type = AZ::Uuid("D0615D0A-027F-47F6-A02B-E35DAF22F431");
return nodeConfig;
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<Data::NumberType>() - *rhs.GetAs<Data::NumberType>());
}
};
}
@@ -52,12 +52,6 @@ namespace ScriptCanvas
nodeConfig.m_type = AZ::Uuid("C1B42FEC-0545-4511-9FAC-11E0387FEDF0");
return nodeConfig;
}
protected:
Datum Evaluate(const Datum& lhs, const Datum& rhs) override
{
return Datum(*lhs.GetAs<Data::NumberType>() + *rhs.GetAs<Data::NumberType>());
}
};
}
}
@@ -91,70 +91,6 @@ namespace ScriptCanvas
}
}
}
void OperatorAt::KeyNotFound(const Datum* containerDatum)
{
Datum defaultDatum;
AZStd::vector<AZ::Uuid> types = ScriptCanvas::Data::GetContainedTypes(GetSourceAZType());
int index = Data::IsMapContainerType(containerDatum->GetType()) ? 1 : 0;
Data::Type type = Data::FromAZType(types[index]);
defaultDatum.SetType(type);
PushOutput(defaultDatum, *GetSlot(*m_outputSlots.begin()));
SignalOutput(GetSlotId("Key Not Found"));
}
void OperatorAt::InvokeOperator()
{
Slot* inputSlot = GetFirstInputSourceSlot();
if (inputSlot)
{
SlotId sourceSlotId = inputSlot->GetId();
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
const Datum* inputKeyDatum = FindDatum(*m_inputSlots.begin());
AZ::Outcome<Datum, AZStd::string> valueOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(*containerDatum, "At", *inputKeyDatum);
if (!valueOutcome.IsSuccess())
{
KeyNotFound(containerDatum);
return;
}
if (Data::IsVectorContainerType(containerDatum->GetType()))
{
PushOutput(valueOutcome.TakeValue(), *GetSlot(*m_outputSlots.begin()));
SignalOutput(GetSlotId("Out"));
}
else if (Data::IsSetContainerType(containerDatum->GetType()) || Data::IsMapContainerType(containerDatum->GetType()))
{
Datum keyDatum = valueOutcome.TakeValue();
if (keyDatum.Empty())
{
KeyNotFound(containerDatum);
}
else
{
PushOutput(keyDatum, *GetSlot(*m_outputSlots.begin()));
SignalOutput(GetSlotId("Out"));
}
}
}
}
}
void OperatorAt::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -36,9 +36,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
void KeyNotFound(const Datum* containerDatum);
};
}
@@ -48,43 +48,6 @@ namespace ScriptCanvas
}
}
void OperatorBack::InvokeOperator()
{
const SlotSet& slotSets = GetSourceSlots();
if (!slotSets.empty())
{
SlotId sourceSlotId = (*slotSets.begin());
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
const Datum* inputKeyDatum = FindDatum(*m_inputSlots.begin());
AZ::Outcome<Datum, AZStd::string> valueOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(*containerDatum, "Back", *inputKeyDatum);
if (!valueOutcome.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to call Back on container: %s", valueOutcome.GetError().c_str());
return;
}
if (Data::IsVectorContainerType(containerDatum->GetType()))
{
PushOutput(valueOutcome.TakeValue(), *GetSlot(*m_outputSlots.begin()));
}
}
}
SignalOutput(GetSlotId("Out"));
}
void OperatorBack::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -35,7 +35,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
};
@@ -67,36 +67,6 @@ namespace ScriptCanvas
}
////
}
void OperatorClear::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId != inSlotId)
{
return;
}
SlotId sourceSlotId = OperatorClearProperty::GetSourceSlotId(this);
if (const Datum* containerDatum = FindDatum(sourceSlotId))
{
if (Datum::IsValidDatum(containerDatum))
{
AZ::Outcome<Datum, AZStd::string> clearOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(*containerDatum, "Clear");
if (!clearOutcome.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to call Clear on container: %s", clearOutcome.GetError().c_str());
return;
}
// Push the source container as an output to support chaining
PushOutput(*containerDatum, *OperatorClearProperty::GetContainerSlot(this));
}
}
SignalOutput(GetSlotId("Out"));
}
}
}
}
@@ -41,10 +41,6 @@ namespace ScriptCanvas
OperatorClear() = default;
void OnInit() override;
protected:
void OnInputSignal(const SlotId& slotId) override;
};
}
@@ -70,49 +70,6 @@ namespace ScriptCanvas
}
////
}
void OperatorEmpty::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorEmptyProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
SlotId sourceSlotId = OperatorEmptyProperty::GetSourceSlotId(this);
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
// Is the container empty?
auto emptyOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(*containerDatum, "Empty");
if (!emptyOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to call Empty on container: %s", emptyOutcome.GetError().c_str());
return;
}
Datum emptyResult = emptyOutcome.TakeValue();
bool isEmpty = *emptyResult.GetAs<bool>();
PushOutput(Datum(isEmpty), *GetSlot(OperatorEmptyProperty::GetIsEmptySlotId(this)));
if (isEmpty)
{
SignalOutput(OperatorEmptyProperty::GetTrueSlotId(this));
}
else
{
SignalOutput(OperatorEmptyProperty::GetFalseSlotId(this));
}
}
else
{
PushOutput(Datum(true), *GetSlot(OperatorEmptyProperty::GetIsEmptySlotId(this)));
SignalOutput(OperatorEmptyProperty::GetFalseSlotId(this));
}
SignalOutput(OperatorEmptyProperty::GetOutSlotId(this));
}
}
}
}
}
@@ -21,22 +21,15 @@ namespace ScriptCanvas
class OperatorEmpty : public Node
{
public:
SCRIPTCANVAS_NODE(OperatorEmpty);
void CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map<SlotId, AZStd::vector<SlotId>>& outSlotIdMap) const override;
static bool OperatorEmptyVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
OperatorEmpty() = default;
// Node...
void OnInit() override;
////
void OnInputSignal(const SlotId& slotId) override;
};
}
}
@@ -95,47 +95,6 @@ namespace ScriptCanvas
}
}
void OperatorErase::InvokeOperator()
{
Slot* inputSlot = GetFirstInputSourceSlot();
Slot* outputSlot = GetFirstOutputSourceSlot();
if (inputSlot && outputSlot)
{
SlotId sourceSlotId = inputSlot->GetId();
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
const Datum* inputKeyDatum = FindDatum(*m_inputSlots.begin());
AZ::Outcome<Datum, AZStd::string> valueOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(*containerDatum, "Erase", *inputKeyDatum);
if (valueOutcome.IsSuccess())
{
// Push the source container as an output to support chaining
PushOutput(*containerDatum, (*outputSlot));
auto outcomeInnerResult = valueOutcome.GetValue().GetAs< AZ::Outcome<void, void>>();
if (outcomeInnerResult && !outcomeInnerResult->IsSuccess())
{
SignalOutput(GetSlotId("Element Not Found"));
return;
}
}
}
}
SignalOutput(GetSlotId("Out"));
}
void OperatorErase::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -39,8 +39,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
private:
bool m_missedElementNotFound = false;
@@ -46,43 +46,6 @@ namespace ScriptCanvas
}
}
void OperatorFront::InvokeOperator()
{
const SlotSet& slotSets = GetSourceSlots();
if (!slotSets.empty())
{
SlotId sourceSlotId = (*slotSets.begin());
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
const Datum* inputKeyDatum = FindDatum(*m_inputSlots.begin());
AZ::Outcome<Datum, AZStd::string> valueOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(*containerDatum, "Front", *inputKeyDatum);
if (!valueOutcome.IsSuccess())
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to call Front on container: %s", valueOutcome.GetError().c_str());
return;
}
if (Data::IsVectorContainerType(containerDatum->GetType()))
{
PushOutput(valueOutcome.TakeValue(), *GetSlot(*m_outputSlots.begin()));
}
}
}
SignalOutput(GetSlotId("Out"));
}
void OperatorFront::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -35,7 +35,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
};
@@ -84,108 +84,6 @@ namespace ScriptCanvas
}
}
void OperatorInsert::InvokeOperator()
{
Slot* inputSlot = GetFirstInputSourceSlot();
Slot* outputSlot = GetFirstOutputSourceSlot();
if (inputSlot && outputSlot)
{
SlotId sourceSlotId = inputSlot->GetId();
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
AZ::BehaviorMethod* method = GetOperatorMethod("Insert");
AZ_Assert(method, "The contract must have failed because you should not be able to invoke an operator for a type that does not have the method");
AZStd::array<AZ::BehaviorValueParameter, BehaviorContextMethodHelper::MaxCount> params;
AZ::BehaviorValueParameter* paramFirst(params.begin());
AZ::BehaviorValueParameter* paramIter = paramFirst;
if (Data::IsVectorContainerType(GetSourceAZType()))
{
// Container
auto behaviorParameter = method->GetArgument(0);
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> param0 = containerDatum->ToBehaviorValueParameter(*behaviorParameter);
paramIter->Set(param0.GetValue());
++paramIter;
// Get the size of the container
auto sizeOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(*containerDatum, "Size");
if (!sizeOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get size of container: %s", sizeOutcome.GetError().c_str());
return;
}
auto inputSlotIterator = m_inputSlots.begin();
// Index
behaviorParameter = method->GetArgument(1);
const Datum* indexDatum = FindDatum(*inputSlotIterator);
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> param2 = indexDatum->ToBehaviorValueParameter(*behaviorParameter);
paramIter->Set(param2.GetValue());
++paramIter;
// Value to insert
behaviorParameter = method->GetArgument(2);
++inputSlotIterator;
const Datum* inputDatum = FindDatum(*inputSlotIterator);
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> param1 = inputDatum->ToBehaviorValueParameter(*behaviorParameter);
paramIter->Set(param1.GetValue());
++paramIter;
}
else if (Data::IsMapContainerType(GetSourceAZType()))
{
auto inputSlotIterator = m_inputSlots.begin();
const Datum* keyDatum = FindDatum(*inputSlotIterator++);
const Datum* valueDatum = FindDatum(*inputSlotIterator);
if (keyDatum && valueDatum)
{
// Container
const AZ::BehaviorParameter* behaviorParameter = method->GetArgument(0);
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> param0 = containerDatum->ToBehaviorValueParameter(*behaviorParameter);
paramIter->Set(param0.GetValue());
++paramIter;
// Key
behaviorParameter = method->GetArgument(1);
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> param1 = keyDatum->ToBehaviorValueParameter(*behaviorParameter);
paramIter->Set(param1.GetValue());
++paramIter;
// Value to insert
behaviorParameter = method->GetArgument(2);
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> param2 = valueDatum->ToBehaviorValueParameter(*behaviorParameter);
paramIter->Set(param2.GetValue());
++paramIter;
}
}
AZStd::vector<SlotId> resultSlotIDs;
resultSlotIDs.push_back();
BehaviorContextMethodHelper::Call(*this, false, method, paramFirst, paramIter, resultSlotIDs);
// Push the source container as an output to support chaining
PushOutput(*containerDatum, (*outputSlot));
}
}
SignalOutput(GetSlotId("Out"));
}
void OperatorInsert::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -33,9 +33,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
};
}
}
@@ -42,73 +42,6 @@ namespace ScriptCanvas
m_inputSlots.insert(AddSlot(slotConfiguration));
}
}
void OperatorPushBack::InvokeOperator()
{
Slot* inputSlot = GetFirstInputSourceSlot();
Slot* outputSlot = GetFirstOutputSourceSlot();
if (inputSlot && outputSlot)
{
const Datum* containerDatum = FindDatum(inputSlot->GetId());
if (Datum::IsValidDatum(containerDatum))
{
AZ::BehaviorMethod* method = GetOperatorMethod("PushBack");
AZ_Assert(method, "The contract must have failed because you should not be able to invoke an operator for a type that does not have the method");
AZStd::array<AZ::BehaviorValueParameter, BehaviorContextMethodHelper::MaxCount> params;
AZ::BehaviorValueParameter* paramFirst(params.begin());
AZ::BehaviorValueParameter* paramIter = paramFirst;
if (Data::IsVectorContainerType(GetSourceAZType()))
{
// Container
auto behaviorParameter = method->GetArgument(0);
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> param0 = containerDatum->ToBehaviorValueParameter(*behaviorParameter);
paramIter->Set(param0.GetValue());
++paramIter;
const auto& inputSlotIterator = m_inputSlots.begin();
// Value to push
behaviorParameter = method->GetArgument(1);
const Datum* inputDatum = FindDatum(*inputSlotIterator);
AZ_Assert(inputDatum, "Unable to GetInput for Input slot Id");
if (inputDatum)
{
AZ::Outcome<AZ::BehaviorValueParameter, AZStd::string> param1 = inputDatum->ToBehaviorValueParameter(*behaviorParameter);
paramIter->Set(param1.GetValue());
++paramIter;
}
}
else if (Data::IsMapContainerType(GetSourceAZType()))
{
SCRIPTCANVAS_REPORT_ERROR((*this), "PushBack is not a supported operation on maps");
return;
}
AZStd::vector<SlotId> resultSlotIDs;
resultSlotIDs.push_back();
BehaviorContextMethodHelper::Call(*this, false, method, paramFirst, paramIter, resultSlotIDs);
PushOutput(*containerDatum, (*outputSlot));
}
}
SignalOutput(GetSlotId("Out"));
}
void OperatorPushBack::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorBaseProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
InvokeOperator();
}
}
}
}
}
@@ -32,9 +32,6 @@ namespace ScriptCanvas
void ConfigureContracts(SourceType sourceType, AZStd::vector<ContractDescriptor>& contractDescs) override;
void OnSourceTypeChanged() override;
void OnInputSignal(const SlotId& slotId) override;
void InvokeOperator();
};
}
}
@@ -85,42 +85,6 @@ namespace ScriptCanvas
}
////
}
void OperatorSize::OnInputSignal(const SlotId& slotId)
{
const SlotId inSlotId = OperatorSizeProperty::GetInSlotId(this);
if (slotId == inSlotId)
{
SlotId sourceSlotId = OperatorSizeProperty::GetSourceSlotId(this);
SlotId sizeSlotId = OperatorSizeProperty::GetSizeSlotId(this);
const Datum* containerDatum = FindDatum(sourceSlotId);
if (Datum::IsValidDatum(containerDatum))
{
// Get the size of the container
auto sizeOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(*containerDatum, "Size");
if (!sizeOutcome)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get size of container: %s", sizeOutcome.GetError().c_str());
return;
}
// Index
Datum sizeResult = sizeOutcome.TakeValue();
PushOutput(sizeResult, *GetSlot(sizeSlotId));
}
else
{
Datum zero(0);
PushOutput(zero, *GetSlot(sizeSlotId));
}
SignalOutput(OperatorSizeProperty::GetOutSlotId(this));
}
}
}
}
}
@@ -33,9 +33,6 @@ namespace ScriptCanvas
// Node...
void OnInit() override;
////
void OnInputSignal(const SlotId& slotId) override;
};
}
}
@@ -55,68 +55,6 @@ namespace ScriptCanvas
}
}
void OperatorArithmetic::OnInputSignal([[maybe_unused]] const SlotId& slotId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas);
if (!m_scrapedInputs)
{
m_scrapedInputs = true;
AZStd::vector< Slot* > groupedSlots = GetSlotsWithDynamicGroup(GetArithmeticDynamicTypeGroup());
SlotId fallbackId;
for (Slot* groupedSlot : groupedSlots)
{
if (groupedSlot->IsInput())
{
SlotId groupedSlotId = groupedSlot->GetId();
if (!fallbackId.IsValid())
{
fallbackId = groupedSlotId;
}
if ((groupedSlot->IsVariableReference() && groupedSlot->GetVariableReference().IsValid()) || IsConnected(groupedSlotId) || IsValidArithmeticSlot(groupedSlotId))
{
const Datum* inputDatum = groupedSlot->FindDatum();
if (inputDatum && inputDatum->GetType().IsValid() && inputDatum->GetType().GetType() != Data::eType::BehaviorContextObject)
{
m_applicableInputs.emplace_back(inputDatum);
}
}
}
else if (groupedSlot->IsOutput())
{
m_resultSlot = groupedSlot;
}
m_outSlot = GetSlotByName("Out")->GetId();
}
// If none of our inputs are valid input slots. Just use the first one we found to fall into a default use case.
if (m_applicableInputs.empty())
{
const Datum* inputDatum = FindDatum(fallbackId);
if (inputDatum && inputDatum->GetType().IsValid())
{
m_applicableInputs.emplace_back(inputDatum);
}
}
if (!m_applicableInputs.empty())
{
const Datum* datum = m_applicableInputs.front();
m_result.SetType(datum->GetType());
}
}
InvokeOperator();
}
void OperatorArithmetic::OnConfigured()
{
auto slotList = GetSlotsWithDynamicGroup(GetArithmeticDynamicTypeGroup());
@@ -85,8 +85,7 @@ namespace ScriptCanvas
// Node
void OnSlotDisplayTypeChanged(const SlotId& slotId, const Data::Type& dataType) override final;
void OnDynamicGroupDisplayTypeChanged(const AZ::Crc32& dynamicGroup, const Data::Type& dataType) override final;
void OnInputSignal(const SlotId& slotId) override;
void OnConfigured() override;
void OnInit() override;
void OnActivate() override;
@@ -104,98 +104,6 @@ namespace ScriptCanvas
}
}
void OperatorDivideByNumber::OnInputSignal(const SlotId& slotId)
{
if (slotId != OperatorDivideByNumberProperty::GetInSlotId(this))
{
return;
}
Data::Type type = GetDisplayType(AZ::Crc32("DivideGroup"));
if (!type.IsValid())
{
return;
}
const Datum* operand = FindDatum(m_operandId);
if (operand == nullptr)
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Operand is nullptr");
return;
}
const float divisorValue = aznumeric_cast<float>(OperatorDivideByNumberProperty::GetDivisor(this));
if (AZ::IsClose(divisorValue, 0.f, std::numeric_limits<float>::epsilon()))
{
SCRIPTCANVAS_REPORT_ERROR((*this), "Division by zero");
return;
}
Datum result;
switch (type.GetType())
{
case Data::eType::Number:
{
const Data::NumberType* number = operand->GetAs<Data::NumberType>();
Data::NumberType resultValue = (*number) / divisorValue;
result = Datum(resultValue);
}
break;
case Data::eType::Vector2:
{
const Data::Vector2Type* vector = operand->GetAs<Data::Vector2Type>();
AZ::Vector2 resultValue = (*vector) / divisorValue;
result = Datum(resultValue);
}
break;
case Data::eType::Vector3:
{
const Data::Vector3Type* vector = operand->GetAs<Data::Vector3Type>();
AZ::Vector3 resultValue = (*vector) / divisorValue;
result = Datum(resultValue);
}
break;
case Data::eType::Vector4:
{
const Data::Vector4Type* vector = operand->GetAs<Data::Vector4Type>();
AZ::Vector4 resultValue = (*vector) / divisorValue;
result = Datum(resultValue);
}
break;
case Data::eType::Quaternion:
{
const Data::QuaternionType* quaternion = operand->GetAs<Data::QuaternionType>();
Data::QuaternionType resultValue = (*quaternion) / divisorValue;
result = Datum(resultValue);
}
break;
case Data::eType::Matrix3x3:
{
const Data::Matrix3x3Type* matrix = operand->GetAs<Data::Matrix3x3Type>();
Data::Matrix3x3Type resultValue = (*matrix) / divisorValue;
result = Datum(resultValue);
}
break;
case Data::eType::Color:
{
const Data::ColorType *color = operand->GetAs<Data::ColorType>();
Data::ColorType resultValue = (*color) / divisorValue;
result = Datum(resultValue);
}
break;
default:
result = Datum();
AZ_Error("Script Canvas", false, "Divide by Number does not support the provided data type.");
break;
}
PushOutput(result, (*OperatorDivideByNumberProperty::GetResultSlot(this)));
SignalOutput(OperatorDivideByNumberProperty::GetOutSlotId(this));
}
}
}
}
@@ -42,7 +42,6 @@ namespace ScriptCanvas
// Nodes...
void OnInit() override;
void OnInputSignal(const SlotId& slotId) override;
////
protected:
@@ -70,58 +70,6 @@ namespace ScriptCanvas
ConfigureSlots();
}
}
void OperatorLength::OnInputSignal(const SlotId& slotId)
{
if (slotId != OperatorLengthProperty::GetInSlotId(this))
{
return;
}
Data::Type type = GetDisplayType(AZ::Crc32("SourceGroup"));
if (!type.IsValid())
{
return;
}
Datum result;
const Datum* operand = FindDatum(OperatorLengthProperty::GetSourceSlotId(this));
switch (type.GetType())
{
case Data::eType::Vector2:
{
const AZ::Vector2* vector = operand->GetAs<AZ::Vector2>();
result = Datum(vector->GetLength());
}
break;
case Data::eType::Vector3:
{
const AZ::Vector3* vector = operand->GetAs<AZ::Vector3>();
result = Datum(vector->GetLength());
}
break;
case Data::eType::Vector4:
{
const AZ::Vector4* vector = operand->GetAs<AZ::Vector4>();
result = Datum(vector->GetLength());
}
break;
case Data::eType::Quaternion:
{
const AZ::Quaternion* vector = operand->GetAs<AZ::Quaternion>();
result = Datum(vector->GetLength());
}
break;
default:
AZ_Assert(false, "Length operator not defined for type: %s", Data::ToAZType(type).ToString<AZStd::string>().c_str());
break;
}
PushOutput(result, (*OperatorLengthProperty::GetLengthSlot(this)));
SignalOutput(OperatorLengthProperty::GetOutSlotId(this));
}
}
}
}
@@ -38,10 +38,7 @@ namespace ScriptCanvas
OperatorLength() = default;
~OperatorLength() = default;
// Node...
void OnInit() override;
void OnInputSignal(const SlotId& slotId) override;
////
};
}
@@ -51,133 +51,10 @@ namespace ScriptCanvas
////////
}
void LerpBetween::OnDeactivate()
{
AZ::SystemTickBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
}
void LerpBetween::OnConfigured()
{
SetupInternalSlotReferences();
}
void LerpBetween::OnSystemTick()
{
// Ping pong between the system and the normal tick bus for a consistent starting point for the lerp
AZ::SystemTickBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusConnect();
}
void LerpBetween::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
{
bool lerpComplete = false;
m_counter += deltaTime;
if (m_counter >= m_duration)
{
lerpComplete = true;
m_counter = m_duration;
}
float percent = m_counter/m_duration;
SignalLerpStep(percent);
}
void LerpBetween::OnInputSignal(const SlotId& slotId)
{
if (slotId == LerpBetweenProperty::GetCancelSlotId(this))
{
CancelLerp();
}
else if (slotId == LerpBetweenProperty::GetInSlotId(this))
{
CancelLerp();
AZ::SystemTickBus::Handler::BusConnect();
float speedOnlyTime = 0.0;
float maxDuration = 0.0;
const Datum* durationDatum = FindDatum(m_maximumTimeSlotId);
const Datum* speedDatum = FindDatum(m_speedSlotId);
if (durationDatum)
{
maxDuration = static_cast<float>((*durationDatum->GetAs<Data::NumberType>()));
}
Data::Type displayType = GetDisplayType(AZ::Crc32("LerpGroup"));
if (displayType == Data::Type::Number())
{
SetupStartStop<Data::NumberType>(displayType);
if (!m_differenceDatum.GetType().IsValid())
{
return;
}
Data::NumberType difference = (*m_differenceDatum.GetAs<Data::NumberType>());
Data::NumberType speed = (*speedDatum->GetAs<Data::NumberType>());
if (AZ::IsClose(speed, 0.0, Data::ToleranceEpsilon()))
{
speedOnlyTime = -1.0f;
}
else
{
speedOnlyTime = fabsf(static_cast<float>(difference)/static_cast<float>(speed));
}
}
else if (displayType == Data::Type::Vector2())
{
SetupStartStop<Data::Vector2Type>(displayType);
speedOnlyTime = CalculateVectorSpeedTime<Data::Vector2Type>(speedDatum);
}
else if (displayType == Data::Type::Vector3())
{
SetupStartStop<Data::Vector3Type>(displayType);
speedOnlyTime = CalculateVectorSpeedTime<Data::Vector3Type>(speedDatum);
}
else if (displayType == Data::Type::Vector4())
{
SetupStartStop<Data::Vector4Type>(displayType);
speedOnlyTime = CalculateVectorSpeedTime<Data::Vector4Type>(speedDatum);
}
m_counter = 0;
if (speedOnlyTime >= 0.0f && maxDuration >= 0.0f)
{
m_duration = AZStd::min(speedOnlyTime, maxDuration);
}
else if (speedOnlyTime >= 0.0f)
{
m_duration = speedOnlyTime;
}
else if (maxDuration >= 0.0f)
{
m_duration = maxDuration;
}
else
{
AZ_Error("ScriptCanvas", false, "Lerp Between not given a valid speed or duration to perofrm the lerp at. Defaulting to 1 second duration");
m_duration = 1.0;
}
if (AZ::IsClose(m_duration, 0.0f, AZ::Constants::FloatEpsilon))
{
CancelLerp();
SignalLerpStep(1.0f);
}
SignalOutput(LerpBetweenProperty::GetOutSlotId(this));
}
}
}
void LerpBetween::SetupInternalSlotReferences()
{
@@ -189,52 +66,7 @@ namespace ScriptCanvas
m_stepSlotId = LerpBetweenProperty::GetStepSlotId(this);
m_percentSlotId = LerpBetweenProperty::GetPercentSlotId(this);
}
void LerpBetween::CancelLerp()
{
AZ::SystemTickBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
}
void LerpBetween::SignalLerpStep(float percent)
{
Data::Type displayType = GetDisplayType(AZ::Crc32("LerpGroup"));
Datum stepDatum(displayType, Datum::eOriginality::Original);
stepDatum.SetToDefaultValueOfType();
if (displayType == Data::Type::Number())
{
CalculateLerpStep<Data::NumberType>(percent, stepDatum);
}
else if (displayType == Data::Type::Vector2())
{
CalculateLerpStep<Data::Vector2Type>(percent, stepDatum);
}
else if (displayType == Data::Type::Vector3())
{
CalculateLerpStep<Data::Vector3Type>(percent, stepDatum);
}
else if (displayType == Data::Type::Vector4())
{
CalculateLerpStep<Data::Vector4Type>(percent, stepDatum);
}
if (AZ::IsClose(percent, 1.0f, AZ::Constants::FloatEpsilon))
{
SignalOutput(LerpBetweenProperty::GetLerpCompleteSlotId(this));
AZ::TickBus::Handler::BusDisconnect();
}
Datum percentDatum(ScriptCanvas::Data::Type::Number(), Datum::eOriginality::Original);
percentDatum.Set<Data::NumberType>(percent);
PushOutput(percentDatum, *GetSlot(m_percentSlotId));
PushOutput(stepDatum, *GetSlot(m_stepSlotId));
SignalOutput(LerpBetweenProperty::GetTickSlotId(this));
}
bool LerpBetween::IsGroupConnected() const
{
bool hasConnections = false;
@@ -27,8 +27,6 @@ namespace ScriptCanvas
//! Deprecated: see NodeableNodeOverloadedLerp
class LerpBetween
: public Node
, public AZ::SystemTickBus::Handler
, public AZ::TickBus::Handler
{
public:
@@ -54,98 +52,14 @@ namespace ScriptCanvas
~LerpBetween() override = default;
void OnInit() override;
void OnDeactivate() override;
void OnConfigured() override;
// SystemTickBus...
void OnSystemTick() override;
////
// TickBus...
void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
////
// Node...
void OnInputSignal(const SlotId& slotId) override;
////
private:
void SetupInternalSlotReferences();
void CancelLerp();
void SignalLerpStep(float percent);
bool IsGroupConnected() const;
bool IsInGroup(const SlotId& slotId) const;
template<typename DataType>
void CalculateLerpStep(float percent, Datum& stepDatum)
{
const DataType* startValue = m_startDatum.GetAs<DataType>();
const DataType* differenceValue = m_differenceDatum.GetAs<DataType>();
if (startValue == nullptr || differenceValue == nullptr)
{
return;
}
DataType stepValue = (*startValue) + (*differenceValue) * percent;
stepDatum.Set<DataType>(stepValue);
}
template<typename DataType>
void SetupStartStop(Data::Type displayType)
{
const Datum* startDatum = FindDatum(m_startSlotId);
const Datum* endDatum = FindDatum(m_stopSlotId);
m_startDatum = (*startDatum);
m_differenceDatum = Datum(displayType, Datum::eOriginality::Original);
const DataType* startValue = startDatum->GetAs<DataType>();
const DataType* endValue = endDatum->GetAs<DataType>();
if (startValue == nullptr || endValue == nullptr)
{
m_differenceDatum.SetToDefaultValueOfType();
}
else
{
DataType difference = (*endValue) - (*startValue);
m_differenceDatum.Set<DataType>(difference);
}
}
template<typename DataType>
float CalculateVectorSpeedTime(const Datum* speedDatum)
{
const DataType* dataType = speedDatum->GetAs<DataType>();
float speedLength = 0.0f;
if (dataType)
{
speedLength = dataType->GetLength();
}
if (AZ::IsClose(speedLength, 0.0f, AZ::Constants::FloatEpsilon))
{
return -1.0;
}
float differenceLength = 0.0;
const DataType* differenceValue = m_differenceDatum.GetAs<DataType>();
if (differenceValue)
{
differenceLength = differenceValue->GetLength();
}
return fabsf(static_cast<float>(differenceLength/speedLength));
}
AZStd::unordered_set< SlotId > m_groupedSlotIds;
float m_duration;
@@ -121,13 +121,6 @@ namespace ScriptCanvas
virtual void OnSourceConnected([[maybe_unused]] const SlotId& slotId) {}
virtual void OnSourceDisconnected([[maybe_unused]] const SlotId& slotId) {}
//! Implements the operator's behavior, the vector of Datums represents the list of operands.
virtual void Evaluate(const OperatorOperands& operands, Datum& result)
{
AZ_UNUSED(operands);
AZ_UNUSED(result);
}
private:
OperatorConfiguration m_operatorConfiguration;
@@ -180,32 +173,6 @@ namespace ScriptCanvas
}
}
};
// Base class for an small helper object that wraps the function to invoke
class OperationHelper
{
public:
Datum operator()(const AZStd::vector<Datum>& operands, Datum& result)
{
AZStd::vector<Datum>::const_iterator operand = operands.begin();
result = *operand;
for (++operand; operand != operands.end(); ++operand)
{
result = Operator(result, *operand);
}
return result;
}
protected:
virtual Datum Operator(const Datum&, const Datum&) = 0;
};
// Helper macro to invoke an operator function for a specialized type
#define CallOperatorFunction(Operator, DataType, Type) \
if (DataType == Data::FromAZType(azrtti_typeid<Type>())) { Operator<Type> operation; operation(operands, result); }
}
}
}
@@ -0,0 +1,3 @@
{
"CurrentProjectSetting": "No Configurations"
}
@@ -0,0 +1,6 @@
{
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
}

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