merge stabilization/2106 into development

Signed-off-by: hultonha <hultonha@amazon.co.uk>
This commit is contained in:
hultonha
2021-07-06 17:34:04 +01:00
377 changed files with 6549 additions and 9214 deletions
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -15,17 +15,28 @@ namespace ScriptCanvasRuntimeAssetCpp
{
AddDependencies = 3,
ChangeScriptRequirementToAsset,
// add your entry above
// add description above
Current
};
enum class RuntimeDataOverridesVersion : unsigned int
{
Initial = 0,
AddRuntimeAsset,
// add description above
Current,
};
enum class FunctionRuntimeDataVersion
{
MergeBackEnd2dotZero,
AddSubgraphInterface,
RemoveLegacyData,
RemoveConnectionToRuntimeData,
// add your entry above
// add description above
Current
};
}
@@ -87,9 +98,9 @@ namespace ScriptCanvas
{
return data.m_input.GetConstructorParameterCount() != 0
|| AZStd::any_of(data.m_requiredAssets.begin(), data.m_requiredAssets.end(), [](const AZ::Data::Asset<RuntimeAsset>& asset)
{
return RequiresDependencyConstructionParametersRecurse(asset.Get()->m_runtimeData);
});
{
return RequiresDependencyConstructionParametersRecurse(asset.Get()->m_runtimeData);
});
}
bool RuntimeData::RequiresStaticInitialization() const
@@ -97,6 +108,80 @@ namespace ScriptCanvas
return !m_cloneSources.empty();
}
bool RuntimeDataOverrides::IsPreloadBehaviorEnforced(const RuntimeDataOverrides& overrides)
{
if (overrides.m_runtimeAsset.GetAutoLoadBehavior() != AZ::Data::AssetLoadBehavior::PreLoad)
{
return false;
}
for (auto& dependency : overrides.m_dependencies)
{
if (!IsPreloadBehaviorEnforced(dependency))
{
return false;
}
}
return true;
}
void RuntimeDataOverrides::EnforcePreloadBehavior()
{
m_runtimeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad);
for (auto& dependency : m_dependencies)
{
dependency.EnforcePreloadBehavior();
}
}
void RuntimeDataOverrides::Reflect(AZ::ReflectContext* context)
{
RuntimeVariable::Reflect(context);
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<RuntimeDataOverrides>()
->Version(static_cast<unsigned int>(ScriptCanvasRuntimeAssetCpp::RuntimeDataOverridesVersion::Current))
->Field("runtimeAsset", &RuntimeDataOverrides::m_runtimeAsset)
->Field("variables", &RuntimeDataOverrides::m_variables)
->Field("variableIndices", &RuntimeDataOverrides::m_variableIndices)
->Field("entityIds", &RuntimeDataOverrides::m_entityIds)
->Field("dependencies", &RuntimeDataOverrides::m_dependencies)
;
}
}
RuntimeVariable::RuntimeVariable(const AZStd::any& source)
: value(source)
{
}
RuntimeVariable::RuntimeVariable(AZStd::any&& source)
: value(AZStd::move(source))
{
}
void RuntimeVariable::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<RuntimeVariable>()
->Field("value", &RuntimeVariable::value)
;
if (auto editContext = serializeContext->GetEditContext())
{
editContext->Class<RuntimeVariable>("RuntimeVariable", "RuntimeVariable")
->DataElement(AZ::Edit::UIHandlers::Default, &RuntimeVariable::value, "value", "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, true)
;
}
}
}
////////////////////////
// SubgraphInterfaceData
@@ -118,7 +203,7 @@ namespace ScriptCanvas
{
*this = AZStd::move(other);
}
SubgraphInterfaceData& SubgraphInterfaceData::operator=(SubgraphInterfaceData&& other)
{
if (this != &other)
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -10,6 +10,7 @@
#include <AzCore/Script/ScriptAsset.h>
#include <ScriptCanvas/Asset/AssetDescription.h>
#include <ScriptCanvas/Core/Core.h>
#include <ScriptCanvas/Core/SubgraphInterface.h>
#include <ScriptCanvas/Core/GraphData.h>
#include <ScriptCanvas/Grammar/DebugMap.h>
@@ -21,6 +22,7 @@
namespace ScriptCanvas
{
class RuntimeAsset;
struct RuntimeVariable;
class RuntimeAssetDescription : public AssetDescription
{
@@ -41,7 +43,7 @@ namespace ScriptCanvas
"Script Canvas Runtime",
"Script Canvas Runtime",
"Icons/ScriptCanvas/Viewport/ScriptCanvas.png",
AZ::Color(1.0f,0.0f,0.0f,1.0f),
AZ::Color(1.0f, 0.0f, 0.0f, 1.0f),
false
)
{}
@@ -82,6 +84,24 @@ namespace ScriptCanvas
bool static RequiresDependencyConstructionParametersRecurse(const RuntimeData& data);
};
struct RuntimeDataOverrides
{
AZ_TYPE_INFO(RuntimeDataOverrides, "{CE3C0AE6-4EBA-43B2-B2D5-7AC24A194E63}");
AZ_CLASS_ALLOCATOR(RuntimeDataOverrides, AZ::SystemAllocator, 0);
static bool IsPreloadBehaviorEnforced(const RuntimeDataOverrides& overrides);
static void Reflect(AZ::ReflectContext* reflectContext);
AZ::Data::Asset<RuntimeAsset> m_runtimeAsset;
AZStd::vector<RuntimeVariable> m_variables;
AZStd::vector<bool> m_variableIndices;
AZStd::vector<AZ::EntityId> m_entityIds;
AZStd::vector<RuntimeDataOverrides> m_dependencies;
void EnforcePreloadBehavior();
};
class RuntimeAssetBase
: public AZ::Data::AssetData
{
@@ -94,7 +114,6 @@ namespace ScriptCanvas
{
}
};
template <typename DataType>
class RuntimeAssetTyped
@@ -165,7 +184,7 @@ namespace ScriptCanvas
"Script Canvas Function Interface",
"Script Canvas Function Interface",
"Icons/ScriptCanvas/Viewport/ScriptCanvas_Function.png",
AZ::Color(1.0f,0.0f,0.0f,1.0f),
AZ::Color(1.0f, 0.0f, 0.0f, 1.0f),
false
)
{}
@@ -207,6 +226,6 @@ namespace ScriptCanvas
static const char* GetFileExtension() { return "scriptcanvas_fn_compiled"; }
static const char* GetFileFilter() { return "*.scriptcanvas_fn_compiled"; }
friend class SubgraphInterfaceAssetHandler;
friend class SubgraphInterfaceAssetHandler;
};
}
@@ -1,12 +1,12 @@
/*
* 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 <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/RTTI/AttributeReader.h>
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/Serialization/SerializeContext.h>
@@ -17,6 +17,33 @@
namespace ScriptCanvas
{
ScopedAuxiliaryEntityHandler::ScopedAuxiliaryEntityHandler(AZ::Entity* buildEntity)
: m_buildEntity(buildEntity)
, m_wasAdded(false)
{
if (AZ::Interface<AZ::ComponentApplicationRequests>::Get() != nullptr)
{
AZ::Interface<AZ::ComponentApplicationRequests>::Get()->RemoveEntity(buildEntity);
}
if (buildEntity->GetState() == AZ::Entity::State::Constructed)
{
buildEntity->Init();
m_wasAdded = true;
}
}
ScopedAuxiliaryEntityHandler::~ScopedAuxiliaryEntityHandler()
{
if (!m_wasAdded)
{
if (AZ::Interface<AZ::ComponentApplicationRequests>::Get() != nullptr)
{
AZ::Interface<AZ::ComponentApplicationRequests>::Get()->AddEntity(m_buildEntity);
}
}
}
bool IsNamespacePathEqual(const NamespacePath& lhs, const NamespacePath& rhs)
{
if (lhs.size() != rhs.size())
@@ -128,4 +155,3 @@ namespace ScriptCanvas
runtimeVersion = RuntimeVersion::Current;
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -15,6 +15,7 @@
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/any.h>
#include <AzCore/std/hash.h>
#include <AzCore/Component/EntityUtils.h>
#include <AzCore/Component/NamedEntityId.h>
@@ -26,7 +27,7 @@ namespace AZ
{
class Entity;
class ReflectContext;
template<typename t_Attribute, typename t_Container>
bool ReadAttribute(t_Attribute& resultOut, AttributeId id, const t_Container& attributes)
{
@@ -41,7 +42,7 @@ namespace ScriptCanvas
// The actual value in each location initialized to GraphOwnerId is populated with the owning entity at editor-time, Asset Processor-time, or runtime, as soon as the owning entity is known.
using GraphOwnerIdType = AZ::EntityId;
static const GraphOwnerIdType GraphOwnerId = AZ::EntityId(0xacedc0de);
// A place holder identifier for unique runtime graph on Entity that is running more than one instance of the same graph.
// This allows multiple instances of the same graph to be addressed individually on the same entity.
// The actual value in each location initialized to UniqueId is populated at run-time.
@@ -52,7 +53,7 @@ namespace ScriptCanvas
constexpr const char* k_OnVariableWriteEventName = "OnVariableValueChanged";
constexpr const char* k_OnVariableWriteEbusName = "VariableNotification";
class Node;
class Edge;
@@ -195,7 +196,7 @@ namespace ScriptCanvas
using PropertyFields = AZStd::vector<AZStd::pair<AZStd::string_view, SlotId>>;
using NamedActiveEntityId = AZ::NamedEntityId;
using NamedActiveEntityId = AZ::NamedEntityId;
using NamedNodeId = NamedId<AZ::EntityId>;
using NamedSlotId = NamedId<SlotId>;
@@ -204,7 +205,26 @@ namespace ScriptCanvas
using EBusBusId = AZ::Crc32;
using ScriptCanvasId = AZ::EntityId;
enum class AzEventIdentifier : size_t {};
struct RuntimeVariable
{
AZ_TYPE_INFO(RuntimeVariable, "{6E969359-5AF5-4ECA-BE89-A96AB30A624E}");
AZ_CLASS_ALLOCATOR(RuntimeVariable, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext);
AZStd::any value;
RuntimeVariable() = default;
RuntimeVariable(const RuntimeVariable&) = default;
RuntimeVariable(RuntimeVariable&&) = default;
explicit RuntimeVariable(const AZStd::any& source);
explicit RuntimeVariable(AZStd::any&& source);
RuntimeVariable& operator=(const RuntimeVariable&) = default;
RuntimeVariable& operator=(RuntimeVariable&&) = default;
};
struct NamespacePathHasher
{
AZ_FORCE_INLINE size_t operator()(const NamespacePath& path) const
@@ -245,6 +265,17 @@ namespace ScriptCanvas
};
using ScriptCanvasSettingsRequestBus = AZ::EBus<ScriptCanvasSettingsRequests>;
class ScopedAuxiliaryEntityHandler
{
public:
ScopedAuxiliaryEntityHandler(AZ::Entity* buildEntity);
~ScopedAuxiliaryEntityHandler();
private:
bool m_wasAdded = false;
AZ::Entity* m_buildEntity = nullptr;
};
}
namespace AZStd
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -9,8 +9,8 @@
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/std/any.h>
#include <AzCore/std/string/string_view.h>
#include <ScriptCanvas/Core/Core.h>
#include <ScriptCanvas/Data/Data.h>
#include <ScriptCanvas/Data/DataTrait.h>
#include <ScriptCanvas/Data/BehaviorContextObject.h>
@@ -59,7 +59,7 @@ namespace ScriptCanvas
Datum(BehaviorContextResultTag, const AZ::BehaviorParameter& resultType);
Datum(const AZStd::string& behaviorClassName, eOriginality originality);
Datum(const AZ::BehaviorValueParameter& value);
void ReconfigureDatumTo(Datum&& object);
void ReconfigureDatumTo(const Datum& object);
@@ -204,18 +204,18 @@ namespace ScriptCanvas
{
static_assert(!AZStd::is_pointer<t_Value>::value, "no pointer types in the Datum::GetAsHelper<t_Value, false>");
if (datum.m_storage.empty())
if (datum.m_storage.value.empty())
{
// rare, but can be caused by removals or problems with reflection to BehaviorContext, so must be checked
return nullptr;
}
else if (datum.m_type.GetType() == Data::eType::BehaviorContextObject)
{
return (*AZStd::any_cast<BehaviorContextObjectPtr>(&datum.m_storage))->CastConst<t_Value>();
return (*AZStd::any_cast<BehaviorContextObjectPtr>(&datum.m_storage.value))->CastConst<t_Value>();
}
else
{
return AZStd::any_cast<const t_Value>(&datum.m_storage);
return AZStd::any_cast<const t_Value>(&datum.m_storage.value);
}
}
};
@@ -253,12 +253,12 @@ namespace ScriptCanvas
// eOriginality records the graph source of the object
eOriginality m_originality = eOriginality::Copy;
// storage for the datum, regardless of ScriptCanvas::Data::Type
AZStd::any m_storage;
RuntimeVariable m_storage;
// This contains the editor label for m_storage.
// This contains the editor label for m_storage.value.
AZStd::string m_datumLabel;
// This contains the editor visibility for m_storage.
// This contains the editor visibility for m_storage.value.
AZ::Crc32 m_visibility{ AZ::Edit::PropertyVisibility::ShowChildrenOnly };
// storage for implicit conversions, when needed
AZStd::any m_conversionStorage;
@@ -304,7 +304,7 @@ namespace ScriptCanvas
bool InitializeCRC(const void* source);
bool InitializeEntityID(const void* source);
bool InitializeNamedEntityID(const void* source);
bool InitializeMatrix3x3(const void* source);
@@ -384,7 +384,7 @@ namespace ScriptCanvas
bool Datum::Empty() const
{
return m_storage.empty() || GetValueAddress() == nullptr;
return m_storage.value.empty() || GetValueAddress() == nullptr;
}
template<typename t_Value>
@@ -492,7 +492,7 @@ namespace ScriptCanvas
{
if (Data::IsValueType(m_type))
{
m_storage = value;
m_storage.value = value;
return true;
}
else
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -136,10 +136,7 @@ namespace ScriptCanvas
{
if (nodeEntity)
{
if (nodeEntity->GetState() == AZ::Entity::State::Constructed)
{
nodeEntity->Init();
}
ScriptCanvas::ScopedAuxiliaryEntityHandler entityHandler(nodeEntity);
if (auto* node = AZ::EntityUtils::FindFirstDerivedComponent<Node>(nodeEntity))
{
@@ -155,10 +152,7 @@ namespace ScriptCanvas
{
if (connectionEntity)
{
if (connectionEntity->GetState() == AZ::Entity::State::Constructed)
{
connectionEntity->Init();
}
ScriptCanvas::ScopedAuxiliaryEntityHandler entityHandler(connectionEntity);
}
}
@@ -169,7 +163,7 @@ namespace ScriptCanvas
{
if (m_isFunctionGraph)
{
return true;
return true;
}
return false;
@@ -418,7 +412,7 @@ namespace ScriptCanvas
void Graph::ValidateVariables(ValidationResults& validationResults)
{
const VariableData* variableData = GetVariableData();
if (!variableData)
{
return;
@@ -440,7 +434,7 @@ namespace ScriptCanvas
{
errorDescription = AZStd::string::format("Variable %s has an invalid type %s.", GetVariableName(variableId).data(), variableType.GetAZType().ToString<AZStd::string>().c_str());
}
}
}
else if (variableType == Data::Type::Invalid())
{
errorDescription = AZStd::string::format("Variable %s has an invalid type.", GetVariableName(variableId).data());
@@ -502,7 +496,7 @@ namespace ScriptCanvas
{
m_graphData.m_nodes.emplace(nodeEntity);
m_nodeMapping[nodeId] = node;
node->SetOwningScriptCanvasId(m_scriptCanvasId);
node->Configure();
GraphNotificationBus::Event(m_scriptCanvasId, &GraphNotifications::OnNodeAdded, nodeId);
@@ -523,17 +517,17 @@ namespace ScriptCanvas
if (node)
{
auto entry = m_graphData.m_nodes.find(node->GetEntity());
if (entry != m_graphData.m_nodes.end())
{
m_nodeMapping.erase(nodeId);
m_graphData.m_nodes.erase(entry);
GraphNotificationBus::Event(GetScriptCanvasId(), &GraphNotifications::OnNodeRemoved, nodeId);
if (entry != m_graphData.m_nodes.end())
{
m_nodeMapping.erase(nodeId);
m_graphData.m_nodes.erase(entry);
GraphNotificationBus::Event(GetScriptCanvasId(), &GraphNotifications::OnNodeRemoved, nodeId);
RemoveDependentAsset(nodeId);
return true;
RemoveDependentAsset(nodeId);
return true;
}
}
}
}
return false;
}
@@ -1036,17 +1030,17 @@ namespace ScriptCanvas
}
}
// for (auto connectionId : removableConnections)
// {
// DisconnectById(connectionId);
// }
// for (auto connectionId : removableConnections)
// {
// DisconnectById(connectionId);
// }
if (!removableConnections.empty())
{
// RefreshConnectionValidity(warnOnRemoval);
}
}
void Graph::OnEntityActivated(const AZ::EntityId&)
{
}
@@ -1075,7 +1069,7 @@ namespace ScriptCanvas
AZ::Data::AssetManager::Instance().GetAsset<ScriptEvents::ScriptEventsAsset>(scriptEventNode->GetAssetId(), AZ::Data::AssetLoadBehavior::Default);
}
}
m_batchAddingData = false;
GraphNotificationBus::Event(GetScriptCanvasId(), &GraphNotifications::OnBatchAddComplete);
@@ -79,6 +79,7 @@ namespace ScriptCanvas
behaviorContext->Class<Nodeable>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
->Attribute(AZ::ScriptCanvasAttributes::VariableCreationForbidden, AZ::AttributeIsValid::IfPresent)
->Attribute(AZ::Script::Attributes::UseClassIndexAllowNil, AZ::AttributeIsValid::IfPresent)
->Constructor<ExecutionStateWeakPtr>()
->Method("Deactivate", &Nodeable::Deactivate)
->Method("InitializeExecutionState", &Nodeable::InitializeExecutionState)
@@ -756,10 +756,9 @@ namespace ScriptCanvas
{
auto runtimeComponent = (*graphIter);
if (graphIdentifier.m_assetId.m_guid == runtimeComponent->GetAsset().GetId().m_guid)
if (graphIdentifier.m_assetId.m_guid == runtimeComponent->GetRuntimeDataOverrides().m_runtimeAsset.GetId().m_guid)
{
// TODO: Gate on ComponentId
// \todo chcurran restore this functionality
// runtimeComponent->SetIsGraphObserved(observedState);
runtimeComponents.erase(graphIter);
break;
@@ -1,12 +1,13 @@
/*
* 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 <AzCore/Component/EntityUtils.h>
#include <AzCore/Script/ScriptSystemBus.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Entity/EntityContextBus.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/Nodeable.h>
@@ -19,13 +20,13 @@
namespace ExecutionContextCpp
{
void TypeCopy(AZ::BehaviorValueParameter& lhs, const AZ::BehaviorValueParameter& rhs)
void CopyTypeInformationOnly(AZ::BehaviorValueParameter& lhs, const AZ::BehaviorValueParameter& rhs)
{
lhs.m_typeId = rhs.m_typeId;
lhs.m_azRtti = rhs.m_azRtti;
}
void ValueCopy(AZ::BehaviorValueParameter& lhs, const AZ::BehaviorValueParameter& rhs)
void CopyTypeAndValueSource(AZ::BehaviorValueParameter& lhs, const AZ::BehaviorValueParameter& rhs)
{
lhs.m_typeId = rhs.m_typeId;
lhs.m_azRtti = rhs.m_azRtti;
@@ -37,97 +38,72 @@ namespace ScriptCanvas
{
namespace Execution
{
ActivationData::ActivationData(const RuntimeComponent& component, ActivationInputArray& storage)
: entityId(component.GetEntityId())
, variableOverrides(component.GetVariableOverrides())
, runtimeData(component.GetAsset()->GetData())
ActivationData::ActivationData(const RuntimeDataOverrides& variableOverrides, ActivationInputArray& storage)
: variableOverrides(variableOverrides)
, runtimeData(variableOverrides.m_runtimeAsset->GetData())
, storage(storage)
{}
ActivationData::ActivationData(const AZ::EntityId entityId, const VariableData& variableOverrides, const RuntimeData& runtimeData, ActivationInputArray& storage)
: entityId(entityId)
, variableOverrides(variableOverrides)
, runtimeData(runtimeData)
, storage(storage)
{}
const void* ActivationData::GetVariableSource(size_t index, size_t& overrideIndexTracker) const
{
if (variableOverrides.m_variableIndices[index])
{
return AZStd::any_cast<void>(&variableOverrides.m_variables[overrideIndexTracker++].value);
}
else
{
return runtimeData.m_input.m_variables[index].second.GetAsDanger();
}
}
ActivationInputRange Context::CreateActivateInputRange(ActivationData& activationData)
ActivationInputRange Context::CreateActivateInputRange(ActivationData& activationData, [[maybe_unused]] const AZ::EntityId& forSliceSupportOnly)
{
const RuntimeData& runtimeData = activationData.runtimeData;
ActivationInputRange rangeOut = runtimeData.m_activationInputRange;
rangeOut.inputs = activationData.storage.begin();
AZ_Assert(rangeOut.totalCount <= activationData.storage.size(), "Too many initial arguments for activation. "
"Consider increasing size, source of ActivationInputArray, or breaking up the source graph");
// nodeables
// nodeables - until the optimization is required, every instance gets their own copy
{
auto sourceVariableIter = runtimeData.m_activationInputRange.inputs;
const auto sourceVariableSentinel = runtimeData.m_activationInputRange.inputs + runtimeData.m_activationInputRange.nodeableCount;
auto destVariableIter = rangeOut.inputs;
for (; sourceVariableIter != sourceVariableSentinel; ++sourceVariableIter, ++destVariableIter)
{
ExecutionContextCpp::ValueCopy(*destVariableIter, *sourceVariableIter);
ExecutionContextCpp::CopyTypeAndValueSource(*destVariableIter, *sourceVariableIter);
}
}
// (possibly overridden) variables
// (possibly overridden) variables, only the overrides are saved in on the component, otherwise they are taken from the runtime asset
{
auto sourceVariableIter = runtimeData.m_activationInputRange.inputs + runtimeData.m_activationInputRange.nodeableCount;
auto destVariableIter = rangeOut.inputs + runtimeData.m_activationInputRange.nodeableCount;
for (auto& idDatumPair : runtimeData.m_input.m_variables)
size_t overrideIndexTracker = 0;
const size_t sentinel = runtimeData.m_input.m_variables.size();
for (size_t index = 0; index != sentinel; ++index, ++destVariableIter, ++sourceVariableIter)
{
ExecutionContextCpp::TypeCopy(*destVariableIter, *sourceVariableIter);
auto variableOverride = activationData.variableOverrides.FindVariable(idDatumPair.first);
const Datum* datum = variableOverride ? variableOverride->GetDatum() : &idDatumPair.second;
destVariableIter->m_value = const_cast<void*>(datum->GetAsDanger());
++destVariableIter;
++sourceVariableIter;
ExecutionContextCpp::CopyTypeInformationOnly(*destVariableIter, *sourceVariableIter);
destVariableIter->m_value = const_cast<void*>(activationData.GetVariableSource(index, overrideIndexTracker));
}
}
// (must always be re-mapped) EntityId
if (!runtimeData.m_input.m_entityIds.empty())
// (always overridden) EntityIds
{
AZ::SliceComponent::EntityIdToEntityIdMap loadedEntityIdMap;
AzFramework::EntityContextId owningContextId = AzFramework::EntityContextId::CreateNull();
AzFramework::EntityIdContextQueryBus::EventResult(owningContextId, activationData.entityId, &AzFramework::EntityIdContextQueries::GetOwningContextId);
if (!owningContextId.IsNull())
{
AzFramework::SliceEntityOwnershipServiceRequestBus::EventResult(loadedEntityIdMap, owningContextId, &AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetLoadedEntityIdMap);
}
AZ::BehaviorValueParameter* destVariableIter = rangeOut.inputs
+ runtimeData.m_activationInputRange.nodeableCount
+ runtimeData.m_activationInputRange.variableCount;
const auto entityIdTypeId = azrtti_typeid<Data::EntityIDType>();
for (auto& idEntityPair : runtimeData.m_input.m_entityIds)
for (auto& entityId : activationData.variableOverrides.m_entityIds)
{
destVariableIter->m_typeId = entityIdTypeId;
destVariableIter->m_value = destVariableIter->m_tempData.allocate(sizeof(Data::EntityIDType), AZStd::alignment_of<Data::EntityIDType>::value, 0);
auto entityIdValuePtr = reinterpret_cast<AZStd::decay_t<Data::EntityIDType>*>(destVariableIter->m_value);
if (auto variableOverride = activationData.variableOverrides.FindVariable(idEntityPair.first))
{
*entityIdValuePtr = *variableOverride->GetDatum()->GetAs<Data::EntityIDType>();
}
else
{
auto iter = loadedEntityIdMap.find(idEntityPair.second);
if (iter != loadedEntityIdMap.end())
{
*entityIdValuePtr = iter->second;
}
else
{
*entityIdValuePtr = Data::EntityIDType();
}
}
*entityIdValuePtr = entityId;
++destVariableIter;
}
}
@@ -156,7 +132,7 @@ namespace ScriptCanvas
for (auto& idDatumPair : runtimeData.m_input.m_variables)
{
const Datum* datum = &idDatumPair.second;
const Datum* datum = &idDatumPair.second;
AZ::BehaviorValueParameter bvp;
bvp.m_typeId = datum->GetType().GetAZType();
const auto classIter(behaviorContext.m_typeToClassMap.find(bvp.m_typeId));
@@ -214,6 +190,6 @@ namespace ScriptCanvas
Execution::InterpretedUnloadData(runtimeData);
}
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -12,9 +12,9 @@
namespace ScriptCanvas
{
class RuntimeComponent;
class VariableData;
struct RuntimeData;
struct RuntimeDataOverrides;
namespace Execution
{
@@ -22,15 +22,15 @@ namespace ScriptCanvas
struct ActivationData
{
ActivationData(const RuntimeComponent& component, ActivationInputArray& storage);
ActivationData(const AZ::EntityId entityId, const VariableData& variableOverrides, const RuntimeData& runtimeData, ActivationInputArray& storage);
const AZ::EntityId entityId;
const VariableData& variableOverrides;
const RuntimeDataOverrides& variableOverrides;
const RuntimeData& runtimeData;
ActivationInputArray& storage;
ActivationData(const RuntimeDataOverrides& variableOverrides, ActivationInputArray& storage);
const void* GetVariableSource(size_t index, size_t& overrideIndexTracker) const;
};
struct ActivationInputRange
{
AZ::BehaviorValueParameter* inputs = nullptr;
@@ -47,7 +47,7 @@ namespace ScriptCanvas
AZ_TYPE_INFO(Context, "{2C137581-19F4-42EB-8BF3-14DBFBC02D8D}");
AZ_CLASS_ALLOCATOR(Context, AZ::SystemAllocator, 0);
static ActivationInputRange CreateActivateInputRange(ActivationData& activationData);
static ActivationInputRange CreateActivateInputRange(ActivationData& activationData, const AZ::EntityId& forSliceSupportOnly);
static void InitializeActivationData(RuntimeData& runtimeData);
static void UnloadData(RuntimeData& runtimeData);
@@ -56,5 +56,5 @@ namespace ScriptCanvas
static void IntializeStaticCloners(RuntimeData& runtimeData, AZ::BehaviorContext& behaviorContext);
};
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -27,34 +27,34 @@ namespace ScriptCanvas
ExecutionState::ExecutionState(const ExecutionStateConfig& config)
: m_component(&config.component)
{}
ExecutionStatePtr ExecutionState::Create(const ExecutionStateConfig& config)
{
Grammar::ExecutionStateSelection selection = config.runtimeData.m_input.m_executionSelection;
switch (selection)
{
case Grammar::InterpretedPure:
case Grammar::ExecutionStateSelection::InterpretedPure:
return AZStd::make_shared<ExecutionStateInterpretedPure>(config);
case Grammar::InterpretedPureOnGraphStart:
case Grammar::ExecutionStateSelection::InterpretedPureOnGraphStart:
return AZStd::make_shared<ExecutionStateInterpretedPureOnGraphStart>(config);
case Grammar::InterpretedObject:
case Grammar::ExecutionStateSelection::InterpretedObject:
return AZStd::make_shared<ExecutionStateInterpretedPerActivation>(config);
case Grammar::InterpretedObjectOnGraphStart:
case Grammar::ExecutionStateSelection::InterpretedObjectOnGraphStart:
return AZStd::make_shared<ExecutionStateInterpretedPerActivationOnGraphStart>(config);
default:
AZ_Assert(false, "Unsupported ScriptCanvas execution selection");
return nullptr;
}
}
AZ::Data::AssetId ExecutionState::GetAssetId() const
{
return m_component->GetAsset().GetId();
return m_component->GetRuntimeDataOverrides().m_runtimeAsset.GetId();
}
AZ::EntityId ExecutionState::GetEntityId() const
@@ -82,9 +82,9 @@ namespace ScriptCanvas
return m_component->GetScriptCanvasId();
}
const VariableData& ExecutionState::GetVariableOverrides() const
const RuntimeDataOverrides& ExecutionState::GetRuntimeDataOverrides() const
{
return m_component->GetVariableOverrides();
return m_component->GetRuntimeDataOverrides();
}
void ExecutionState::Reflect(AZ::ReflectContext* reflectContext)
@@ -92,10 +92,12 @@ namespace ScriptCanvas
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
{
behaviorContext->Class<ExecutionState>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
->Attribute(AZ::ScriptCanvasAttributes::VariableCreationForbidden, AZ::AttributeIsValid::IfPresent)
->Method("GetEntityId", &ExecutionState::GetEntityId)
->Method("GetScriptCanvasId", &ExecutionState::GetScriptCanvasId)
->Method("ToString", &ExecutionState::ToString)
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
;
}
@@ -116,7 +118,7 @@ namespace ScriptCanvas
{
return shared_from_this();
}
AZStd::string ExecutionState::ToString() const
{
return AZStd::string::format("ExecutionState[%p]", this);
@@ -132,4 +134,4 @@ namespace ScriptCanvas
return ExecutionStateWeakConstPtr(this);
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -37,7 +37,7 @@ namespace ScriptCanvas
ExecutionStateConfig(AZ::Data::Asset<RuntimeAsset> asset, RuntimeComponent& component);
};
class ExecutionState
: public AZStd::enable_shared_from_this<ExecutionState>
{
@@ -50,7 +50,7 @@ namespace ScriptCanvas
static void Reflect(AZ::ReflectContext* reflectContext);
const RuntimeComponent* m_component = nullptr;
ExecutionState(const ExecutionStateConfig& config);
virtual ~ExecutionState() = default;
@@ -71,7 +71,7 @@ namespace ScriptCanvas
AZ::EntityId GetScriptCanvasId() const;
const VariableData& GetVariableOverrides() const;
const RuntimeDataOverrides& GetRuntimeDataOverrides() const;
virtual void Initialize() = 0;
@@ -88,4 +88,4 @@ namespace ScriptCanvas
ExecutionStateWeakConstPtr WeakFromThisConst() const;
};
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -176,7 +176,7 @@ namespace ExecutionInterpretedAPICpp
// Lua:
AZStd::pair<void*, AZ::BehaviorContext*> multipleResults = ScriptCanvas::BehaviorContextUtils::ConstructTupleGetContext(typeId);
AZ_Assert(multipleResults.first, "failure to construct a tuple by typeid from behavior context");
AZ::BehaviorValueParameter parameter;
AZ::BehaviorValueParameter parameter;
parameter.m_value = multipleResults.first;
parameter.m_typeId = typeId;
AZ::StackPush(lua, multipleResults.second, parameter);
@@ -253,7 +253,7 @@ namespace ScriptCanvas
break;
}
}
void SetInterpretedExecutionModeDebug()
{
AZ::ScriptContext* scriptContext{};
@@ -314,7 +314,7 @@ namespace ScriptCanvas
{
using namespace ExecutionInterpretedAPICpp;
static_assert(sizeof(AZ::Uuid) == k_UuidSize, "size of uuid has changed");
AZStd::string fastString;
fastString.resize(k_StringFastSize);
char* fastDigit = fastString.begin();
@@ -338,7 +338,7 @@ namespace ScriptCanvas
AZ_Assert(string, "string argument must not be null");
AZ_Assert(strlen(string) == k_StringFastSize, "invalid length of string, fast format must be: 0123456789ABCDEF0123456789ABCDEF");
const char* current = string;
AZ::Uuid id;
auto data = id.begin();
auto sentinel = id.end();
@@ -358,8 +358,7 @@ namespace ScriptCanvas
++current;
*data = (value0 << 4) | value1;
}
while ((++data) != sentinel);
} while ((++data) != sentinel);
return id;
}
@@ -370,7 +369,6 @@ namespace ScriptCanvas
/**
Here is the function in Lua for easier reading
function OverrideNodeableMetatable(userdata, class_mt)
local proxy = setmetatable({}, class_mt) -- class_mt from the user graph definition
local instance_mt = {
@@ -388,18 +386,16 @@ namespace ScriptCanvas
--]]
return setmetatable(userdata instance_mt) -- can't be done from Lua
end
--[[
userdata to Nodeable before:
getmetatable(userdata).__index == Nodeable
userdata to Nodeable after:
local override_mt = getmetatable(userdata)
local proxy = override_mt.__index
local SubGraph = getmetatable(proxy).__index
getmetatable(SubGraph.__index) == Nodeable)
--]]
*/
// \note: all other metamethods ignored for now
@@ -504,7 +500,7 @@ namespace ScriptCanvas
AZ_Assert(argsCount >= 2, "CallExecutionOut: Error in compiled Lua file, not enough arguments");
AZ_Assert(lua_isuserdata(lua, 1), "CallExecutionOut: Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)");
AZ_Assert(lua_isnumber(lua, 2), "CallExecutionOut: Error in compiled lua file, 2nd argument to SetExecutionOut is not a number");
Nodeable* nodeable = AZ::ScriptValue<Nodeable*>::StackRead(lua, 1);
Nodeable* nodeable = AZ::ScriptValue<Nodeable*>::StackRead(lua, 1);
size_t index = aznumeric_caster(lua_tointeger(lua, 2));
nodeable->CallOut(index, nullptr, nullptr, argsCount - 2);
// Lua: results...
@@ -568,7 +564,7 @@ namespace ScriptCanvas
{
const int handlerIndex = lua_gettop(lua) - argCount;
lua_pushcfunction(lua, &ExecutionInterpretedAPICpp::ErrorHandler);
lua_insert(lua, handlerIndex);
lua_insert(lua, handlerIndex);
int result = lua_pcall(lua, argCount, returnValueCount, handlerIndex);
lua_remove(lua, handlerIndex);
return result;
@@ -581,7 +577,7 @@ namespace ScriptCanvas
AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)");
AZ_Assert(lua_isnumber(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOut is not a number");
AZ_Assert(lua_isfunction(lua, -1), "Error in compiled lua file, 3rd argument to SetExecutionOut is not a function (lambda need to get around atypically routed arguments)");
AZ_Assert(lua_isfunction(lua, -1), "Error in compiled lua file, 3rd argument to SetExecutionOut is not a function (lambda need to get around atypically routed arguments)");
Nodeable* nodeable = AZ::ScriptValue<Nodeable*>::StackRead(lua, -3);
AZ_Assert(nodeable, "Failed to read nodeable");
size_t index = aznumeric_caster(lua_tointeger(lua, -2));
@@ -680,9 +676,9 @@ namespace ScriptCanvas
struct DependencyConstructionPack
{
ExecutionStateInterpreted* executionState;
AZStd::vector<AZ::Data::Asset<RuntimeAsset>>* dependentAssets;
const size_t dependentAssetsIndex;
RuntimeData& runtimeData;
AZStd::vector<RuntimeDataOverrides>* dependencies;
const size_t dependenciesIndex;
RuntimeDataOverrides& runtimeOverrides;
};
DependencyConstructionPack UnpackDependencyConstructionArgsSanitize(lua_State* lua)
@@ -690,27 +686,26 @@ namespace ScriptCanvas
auto executionState = AZ::ScriptValue<ExecutionStateInterpreted*>::StackRead(lua, 1);
AZ_Assert(executionState, "Error in compiled lua file, 1st argument to UnpackDependencyArgs is not an ExecutionStateInterpreted");
AZ_Assert(lua_islightuserdata(lua, 2), "Error in compiled lua file, 2nd argument to UnpackDependencyArgs is not userdata (AZStd::vector<AZ::Data::Asset<RuntimeAsset>>*), but a :%s", lua_typename(lua, 2));
auto dependentAssets = reinterpret_cast<AZStd::vector<AZ::Data::Asset<RuntimeAsset>>*>(lua_touserdata(lua, 2));
auto dependentOverrides = reinterpret_cast<AZStd::vector<RuntimeDataOverrides>*>(lua_touserdata(lua, 2));
AZ_Assert(lua_isinteger(lua, 3), "Error in compiled Lua file, 3rd argument to UnpackDependencyArgs is not a number");
const size_t dependentAssetsIndex = aznumeric_caster(lua_tointeger(lua, 3));
return DependencyConstructionPack{ executionState, dependentAssets, dependentAssetsIndex, (*dependentAssets)[dependentAssetsIndex].Get()->m_runtimeData };
const size_t dependencyIndex = aznumeric_caster(lua_tointeger(lua, 3));
return DependencyConstructionPack{ executionState, dependentOverrides, dependencyIndex, (*dependentOverrides)[dependencyIndex] };
}
int Unpack(lua_State* lua, DependencyConstructionPack& args)
{
ActivationInputArray storage;
ActivationData data(args.executionState->GetEntityId(), args.executionState->GetVariableOverrides(), args.runtimeData, storage);
ActivationInputRange range = Execution::Context::CreateActivateInputRange(data);
ActivationData data(args.runtimeOverrides, storage);
ActivationInputRange range = Execution::Context::CreateActivateInputRange(data, args.executionState->GetEntityId());
PushActivationArgs(lua, range.inputs, range.totalCount);
return range.totalCount;
}
int UnpackDependencyConstructionArgs(lua_State* lua)
{
// Lua: executionState, dependentAssets, dependentAssetsIndex
// Lua: executionState, dependent overrides, index into dependent overrides
DependencyConstructionPack pack = UnpackDependencyConstructionArgsSanitize(lua);
lua_pushlightuserdata(lua, const_cast<void*>(reinterpret_cast<const void*>(&pack.runtimeData.m_requiredAssets)));
lua_pushlightuserdata(lua, const_cast<void*>(reinterpret_cast<const void*>(&pack.runtimeOverrides.m_dependencies)));
return 1 + Unpack(lua, pack);
}
@@ -720,6 +715,5 @@ namespace ScriptCanvas
DependencyConstructionPack constructionArgs = UnpackDependencyConstructionArgsSanitize(lua);
return Unpack(lua, constructionArgs);
}
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -20,6 +20,7 @@ namespace ExecutionStateInterpretedCpp
AZ::Data::Asset<RuntimeAsset> GetSubgraphAssetForDebug(const AZ::Data::AssetId& id)
{
// #functions2 this may have to be made recursive
auto asset = AZ::Data::AssetManager::Instance().GetAsset<SubgraphInterfaceAsset>(id, AZ::Data::AssetLoadBehavior::PreLoad);
asset.BlockUntilLoadComplete();
return asset;
@@ -32,7 +33,7 @@ namespace ScriptCanvas
: ExecutionState(config)
, m_interpretedAsset(config.runtimeData.m_script)
{}
void ExecutionStateInterpreted::ClearLuaRegistryIndex()
{
m_luaRegistryIndex = LUA_NOREF;
@@ -40,8 +41,8 @@ namespace ScriptCanvas
const Grammar::DebugExecution* ExecutionStateInterpreted::GetDebugSymbolIn(size_t index) const
{
return index < m_component->GetAssetData().m_debugMap.m_ins.size()
? &(m_component->GetAssetData().m_debugMap.m_ins[index])
return index < m_component->GetRuntimeAssetData().m_debugMap.m_ins.size()
? &(m_component->GetRuntimeAssetData().m_debugMap.m_ins[index])
: nullptr;
}
@@ -55,8 +56,8 @@ namespace ScriptCanvas
const Grammar::DebugExecution* ExecutionStateInterpreted::GetDebugSymbolOut(size_t index) const
{
return index < m_component->GetAssetData().m_debugMap.m_outs.size()
? &(m_component->GetAssetData().m_debugMap.m_outs[index])
return index < m_component->GetRuntimeAssetData().m_debugMap.m_outs.size()
? &(m_component->GetRuntimeAssetData().m_debugMap.m_outs[index])
: nullptr;
}
@@ -70,8 +71,8 @@ namespace ScriptCanvas
const Grammar::DebugExecution* ExecutionStateInterpreted::GetDebugSymbolReturn(size_t index) const
{
return index < m_component->GetAssetData().m_debugMap.m_returns.size()
? &(m_component->GetAssetData().m_debugMap.m_returns[index])
return index < m_component->GetRuntimeAssetData().m_debugMap.m_returns.size()
? &(m_component->GetRuntimeAssetData().m_debugMap.m_returns[index])
: nullptr;
}
@@ -85,8 +86,8 @@ namespace ScriptCanvas
const Grammar::DebugDataSource* ExecutionStateInterpreted::GetDebugSymbolVariableChange(size_t index) const
{
return index < m_component->GetAssetData().m_debugMap.m_variables.size()
? &(m_component->GetAssetData().m_debugMap.m_variables[index])
return index < m_component->GetRuntimeAssetData().m_debugMap.m_variables.size()
? &(m_component->GetRuntimeAssetData().m_debugMap.m_variables[index])
: nullptr;
}
@@ -131,6 +132,8 @@ namespace ScriptCanvas
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
{
behaviorContext->Class<ExecutionStateInterpreted>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
->Attribute(AZ::ScriptCanvasAttributes::VariableCreationForbidden, AZ::AttributeIsValid::IfPresent)
;
}
}
@@ -148,5 +151,4 @@ namespace ScriptCanvas
luaL_unref(m_luaState, LUA_REGISTRYINDEX, m_luaRegistryIndex);
m_luaRegistryIndex = LUA_NOREF;
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -19,7 +19,7 @@ namespace ScriptCanvas
ExecutionStateInterpretedPerActivation::ExecutionStateInterpretedPerActivation(const ExecutionStateConfig& config)
: ExecutionStateInterpreted(config)
{}
ExecutionStateInterpretedPerActivation::~ExecutionStateInterpretedPerActivation()
{
if (m_deactivationRequired)
@@ -45,15 +45,15 @@ namespace ScriptCanvas
AZ::Internal::LuaClassToStack(lua, this, azrtti_typeid<ExecutionStateInterpretedPerActivation>(), AZ::ObjectToLua::ByReference, AZ::AcquisitionOnPush::None);
// Lua: graph_VM, graph_VM['new'], userdata<ExecutionState>
Execution::ActivationInputArray storage;
Execution::ActivationData data(*m_component, storage);
Execution::ActivationInputRange range = Execution::Context::CreateActivateInputRange(data);
Execution::ActivationData data(m_component->GetRuntimeDataOverrides(), storage);
Execution::ActivationInputRange range = Execution::Context::CreateActivateInputRange(data, m_component->GetEntityId());
if (range.requiresDependencyConstructionParameters)
{
lua_pushlightuserdata(lua, const_cast<void*>(reinterpret_cast<const void*>(&data.runtimeData.m_requiredAssets)));
// Lua: graph_VM, graph_VM['new'], userdata<ExecutionState>, dependencies
lua_pushlightuserdata(lua, const_cast<void*>(reinterpret_cast<const void*>(&data.variableOverrides.m_dependencies)));
// Lua: graph_VM, graph_VM['new'], userdata<ExecutionState>, runtimeDataOverrides
Execution::PushActivationArgs(lua, range.inputs, range.totalCount);
// Lua: graph_VM, graph_VM['new'], userdata<ExecutionState>, dependencies, args...
// Lua: graph_VM, graph_VM['new'], userdata<ExecutionState>, runtimeDataOverrides, args...
AZ::Internal::LuaSafeCall(lua, aznumeric_caster(2 + range.totalCount), 1);
}
else
@@ -139,5 +139,4 @@ namespace ScriptCanvas
;
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -21,7 +21,7 @@ namespace ScriptCanvas
void ExecutionStateInterpretedPure::Execute()
{}
void ExecutionStateInterpretedPure::Initialize()
{}
@@ -52,8 +52,8 @@ namespace ScriptCanvas
AZ::Internal::LuaClassToStack(lua, this, azrtti_typeid<ExecutionStateInterpretedPureOnGraphStart>(), AZ::ObjectToLua::ByReference, AZ::AcquisitionOnPush::None);
// Lua: graph_VM, graph_VM['k_OnGraphStartFunctionName'], userdata<ExecutionState>
Execution::ActivationInputArray storage;
Execution::ActivationData data(*m_component, storage);
Execution::ActivationInputRange range = Execution::Context::CreateActivateInputRange(data);
Execution::ActivationData data(m_component->GetRuntimeDataOverrides(), storage);
Execution::ActivationInputRange range = Execution::Context::CreateActivateInputRange(data, m_component->GetEntityId());
Execution::PushActivationArgs(lua, range.inputs, range.totalCount);
// Lua: graph_VM, graph_VM['k_OnGraphStartFunctionName'], userdata<ExecutionState>, args...
const int result = Execution::InterpretedSafeCall(lua, aznumeric_caster(1 + range.totalCount), 0);
@@ -78,4 +78,4 @@ namespace ScriptCanvas
;
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -24,9 +24,12 @@
namespace RuntimeComponentCpp
{
enum Version
enum class RuntimeComponentVersion : unsigned int
{
ForceAssetPreloads = 5,
AddRuntimeDataOverrides,
PrefabSupport,
RemoveRuntimeAsset,
// add description above
Current,
@@ -40,17 +43,11 @@ namespace ScriptCanvas
return GraphInfo(scriptCanvasId, graphIdentifier);
}
DatumValue CreateDatumValue(ScriptCanvasId /*scriptCanvasId*/, const GraphVariable& variable)
DatumValue CreateDatumValue([[maybe_unused]] ScriptCanvasId scriptCanvasId, const GraphVariable& variable)
{
return DatumValue::Create(GraphVariable((*variable.GetDatum()), variable.GetVariableId()));
}
RuntimeComponent::RuntimeComponent(AZ::Data::Asset<RuntimeAsset> runtimeAsset)
: m_runtimeAsset(runtimeAsset)
{
m_runtimeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad);
}
void RuntimeComponent::Activate()
{
InitializeExecution();
@@ -66,18 +63,13 @@ namespace ScriptCanvas
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::Execute (%s)", m_runtimeAsset.GetId().ToString<AZStd::string>().c_str());
AZ_Assert(m_executionState, "RuntimeComponent::Execute called without an execution state");
SC_EXECUTION_TRACE_GRAPH_ACTIVATED(CreateActivationInfo());
SCRIPT_CANVAS_PERFORMANCE_SCOPE_EXECUTION(m_executionState->GetScriptCanvasId(), m_runtimeAsset.GetId());
SCRIPT_CANVAS_PERFORMANCE_SCOPE_EXECUTION(m_executionState->GetScriptCanvasId(), m_runtimeOverrides.m_runtimeAsset.GetId());
m_executionState->Execute();
}
const AZ::Data::Asset<RuntimeAsset>& RuntimeComponent::GetAsset() const
const RuntimeData& RuntimeComponent::GetRuntimeAssetData() const
{
return m_runtimeAsset;
}
const RuntimeData& RuntimeComponent::GetAssetData() const
{
return m_runtimeAsset->GetData();
return m_runtimeOverrides.m_runtimeAsset->GetData();
}
ExecutionMode RuntimeComponent::GetExecutionMode() const
@@ -87,7 +79,7 @@ namespace ScriptCanvas
GraphIdentifier RuntimeComponent::GetGraphIdentifier() const
{
return GraphIdentifier(AZ::Data::AssetId(m_runtimeAsset.GetId().m_guid, 0), 0);
return GraphIdentifier(AZ::Data::AssetId(m_runtimeOverrides.m_runtimeAsset.GetId().m_guid, 0), 0);
}
AZ::EntityId RuntimeComponent::GetScriptCanvasId() const
@@ -95,37 +87,43 @@ namespace ScriptCanvas
return m_scriptCanvasId;
}
const VariableData& RuntimeComponent::GetVariableOverrides() const
const RuntimeDataOverrides& RuntimeComponent::GetRuntimeDataOverrides() const
{
return m_variableOverrides;
return m_runtimeOverrides;
}
void RuntimeComponent::SetRuntimeDataOverrides(const RuntimeDataOverrides& overrideData)
{
m_runtimeOverrides = overrideData;
m_runtimeOverrides.EnforcePreloadBehavior();
}
void RuntimeComponent::Init()
{
m_scriptCanvasId = AZ::Entity::MakeId();
AZ_Assert(m_runtimeAsset.GetAutoLoadBehavior() == AZ::Data::AssetLoadBehavior::PreLoad, "RuntimeComponent::m_runtimeAsset Auto load behavior MUST be set to AZ::Data::AssetLoadBehavior::PreLoad");
AZ_Assert(RuntimeDataOverrides::IsPreloadBehaviorEnforced(m_runtimeOverrides), "RuntimeComponent::m_runtimeAsset Auto load behavior MUST be set to AZ::Data::AssetLoadBehavior::PreLoad");
}
void RuntimeComponent::InitializeExecution()
{
#if defined(SCRIPT_CANVAS_RUNTIME_ASSET_CHECK)
if (!m_runtimeAsset.Get())
if (!m_runtimeOverrides.m_runtimeAsset.Get())
{
AZ_Error("ScriptCanvas", false, "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeAsset.GetId().ToString<AZStd::string>().data());
AZ_Error("ScriptCanvas", false, "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeOverrides.m_runtimeAsset.GetId().ToString<AZStd::string>().data());
return;
}
#else
AZ_Assert(m_runtimeAsset.Get(), "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeAsset.GetId().ToString<AZStd::string>().data());
AZ_Assert(m_runtimeAsset.Get(), "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeOverrides.m_runtimeAsset.GetId().ToString<AZStd::string>().data());
#endif
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::InitializeExecution (%s)", m_runtimeAsset.GetId().ToString<AZStd::string>().c_str());
SCRIPT_CANVAS_PERFORMANCE_SCOPE_INITIALIZATION(m_scriptCanvasId, m_runtimeAsset.GetId());
m_executionState = ExecutionState::Create(ExecutionStateConfig(m_runtimeAsset, *this));
SCRIPT_CANVAS_PERFORMANCE_SCOPE_INITIALIZATION(m_scriptCanvasId, m_runtimeOverrides.m_runtimeAsset.GetId());
m_executionState = ExecutionState::Create(ExecutionStateConfig(m_runtimeOverrides.m_runtimeAsset, *this));
#if defined(SCRIPT_CANVAS_RUNTIME_ASSET_CHECK)
if (!m_executionState)
{
AZ_Error("ScriptCanvas", false, "RuntimeComponent::m_runtimeAsset AssetId: %s failed to create an execution state, possibly due to missing dependent asset, script will not run", m_runtimeAsset.GetId().ToString<AZStd::string>().data());
AZ_Error("ScriptCanvas", false, "RuntimeComponent::m_runtimeAsset AssetId: %s failed to create an execution state, possibly due to missing dependent asset, script will not run", m_runtimeOverrides.m_runtimeAsset.GetId().ToString<AZStd::string>().data());
return;
}
#else
@@ -135,7 +133,7 @@ namespace ScriptCanvas
AZ::EntityBus::Handler::BusConnect(GetEntityId());
m_executionState->Initialize();
}
void RuntimeComponent::OnEntityActivated(const AZ::EntityId&)
{
Execute();
@@ -151,24 +149,18 @@ namespace ScriptCanvas
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<RuntimeComponent, AZ::Component>()
->Version(RuntimeComponentCpp::Version::Current, &RuntimeComponent::VersionConverter)
->Field("m_runtimeAsset", &RuntimeComponent::m_runtimeAsset)
->Field("m_variableOverrides", &RuntimeComponent::m_variableOverrides)
->Version(static_cast<unsigned int>(RuntimeComponentCpp::RuntimeComponentVersion::Current), &RuntimeComponent::VersionConverter)
->Field("runtimeOverrides", &RuntimeComponent::m_runtimeOverrides)
;
}
}
void RuntimeComponent::SetVariableOverrides(const VariableData& overrideData)
{
m_variableOverrides = overrideData;
}
void RuntimeComponent::StopExecution()
{
if (m_executionState)
{
m_executionState->StopExecution();
SCRIPT_CANVAS_PERFORMANCE_FINALIZE_TIMER(GetScriptCanvasId(), m_runtimeAsset.GetId());
SCRIPT_CANVAS_PERFORMANCE_FINALIZE_TIMER(GetScriptCanvasId(), m_runtimeOverrides.m_runtimeAsset.GetId());
SC_EXECUTION_TRACE_GRAPH_DEACTIVATED(CreateActivationInfo());
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -17,9 +17,6 @@
#include <ScriptCanvas/Execution/ExecutionStateDeclarations.h>
#include <ScriptCanvas/Grammar/PrimitivesDeclarations.h>
#include "RuntimeComponent.h"
namespace ScriptCanvas
{
using VariableIdMap = AZStd::unordered_map<VariableId, VariableId>;
@@ -45,11 +42,8 @@ namespace ScriptCanvas
RuntimeComponent() = default;
RuntimeComponent(AZ::Data::Asset<RuntimeAsset> runtimeAsset);
const AZ::Data::Asset<RuntimeAsset>& GetAsset() const;
const RuntimeData& GetAssetData() const;
// used to provide debug symbols, usually coming in the form of Node/Slot/Variable IDs
const RuntimeData& GetRuntimeAssetData() const;
GraphIdentifier GetGraphIdentifier() const;
@@ -57,9 +51,9 @@ namespace ScriptCanvas
AZ::EntityId GetScriptCanvasId() const;
const VariableData& GetVariableOverrides() const;
const RuntimeDataOverrides& GetRuntimeDataOverrides() const;
void SetVariableOverrides(const VariableData& overrideData);
void SetRuntimeDataOverrides(const RuntimeDataOverrides& overrideData);
protected:
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
@@ -94,15 +88,8 @@ namespace ScriptCanvas
void StopExecution();
private:
AZ::Data::Asset<RuntimeAsset> m_runtimeAsset;
ExecutionStatePtr m_executionState;
AZ::EntityId m_scriptCanvasId;
//! Per instance variable data overrides for the runtime asset
//! This is serialized when building this component from the EditorScriptCanvasComponent
// \todo remove the names from this data, and make it more lightweight
// it only needs variable id and value
// move the other information to the runtime system component
VariableData m_variableOverrides;
RuntimeDataOverrides m_runtimeOverrides;
};
}
@@ -1,12 +1,13 @@
/*
* 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 <AzCore/std/containers/unordered_map.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <Builder/ScriptCanvasBuilder.h>
#include <ScriptCanvas/Core/Datum.h>
#include <ScriptCanvas/Core/EBusHandler.h>
#include <ScriptCanvas/Core/Graph.h>
@@ -41,11 +42,11 @@ namespace AbstractCodeModelCpp
using namespace ScriptCanvas::Grammar;
AZStd::unordered_set< const Nodes::Core::FunctionDefinitionNode*> Intersection
( const AZStd::unordered_multimap<const Nodes::Core::FunctionDefinitionNode*, ExecutionTreePtr>& lhs
(const AZStd::unordered_multimap<const Nodes::Core::FunctionDefinitionNode*, ExecutionTreePtr>& lhs
, const AZStd::unordered_set< const Nodes::Core::FunctionDefinitionNode*>& rhs)
{
AZStd::unordered_set< const Nodes::Core::FunctionDefinitionNode*> intersection;
for (auto candidate : lhs)
{
if (rhs.contains(candidate.first))
@@ -147,7 +148,7 @@ namespace ScriptCanvas
}
}
m_functions.clear();
m_userInsThatRequireTopology.clear();
m_userOutsThatRequireTopology.clear();
@@ -239,7 +240,7 @@ namespace ScriptCanvas
// #functions2 slot<->variable consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering
m_sourceVariableByDatum.insert(AZStd::make_pair(datum, &variablePair.second));
}
}
for (auto& sourceVariable : sortedVariables)
@@ -424,7 +425,7 @@ namespace ScriptCanvas
}
void AbstractCodeModel::AddExecutionMapIn
( UserInParseTopologyResult /*result*/
(UserInParseTopologyResult /*result*/
, ExecutionTreeConstPtr root
, const AZStd::vector<ExecutionTreeConstPtr>& outCalls
, AZStd::string_view defaultOutName
@@ -441,10 +442,10 @@ namespace ScriptCanvas
for (auto& input : functionInput)
{
in.inputs.push_back
({ GetOriginalVariableName(input.second->m_source, nodelingIn)
, input.second->m_source->m_name
, input.second->m_source->m_datum
, input.second->m_source->m_sourceVariableId });
({ GetOriginalVariableName(input.second->m_source, nodelingIn)
, input.second->m_source->m_name
, input.second->m_source->m_datum
, input.second->m_source->m_sourceVariableId });
}
if (!root->HasExplicitUserOutCalls())
@@ -473,10 +474,10 @@ namespace ScriptCanvas
{
const auto& returnValueVariable = root->GetReturnValue(returnValueIndex).second->m_source;
out.outputs.push_back
({ GetOriginalVariableName(returnValueVariable, *uniqueNodelingsOut.begin())
, returnValueVariable->m_name
, returnValueVariable->m_datum.GetType()
, returnValueVariable->m_sourceVariableId });
({ GetOriginalVariableName(returnValueVariable, *uniqueNodelingsOut.begin())
, returnValueVariable->m_name
, returnValueVariable->m_datum.GetType()
, returnValueVariable->m_sourceVariableId });
}
in.outs.push_back(AZStd::move(out));
@@ -505,15 +506,15 @@ namespace ScriptCanvas
SetDisplayAndParsedName(out, defaultOutName);
out.sourceID = defaultOutId;
}
for (size_t inputIndex = 0; inputIndex < outCall->GetInputCount(); ++inputIndex)
{
const auto& returnValueVariable = outCall->GetInput(inputIndex).m_value;
out.outputs.push_back
({ GetOriginalVariableName(returnValueVariable, outCallID.m_node)
, returnValueVariable->m_name
, returnValueVariable->m_datum.GetType()
, returnValueVariable->m_sourceVariableId });
({ GetOriginalVariableName(returnValueVariable, outCallID.m_node)
, returnValueVariable->m_name
, returnValueVariable->m_datum.GetType()
, returnValueVariable->m_sourceVariableId });
}
AZStd::const_pointer_cast<ExecutionTree>(outCall)->SetOutCallIndex(m_outIndexCount);
@@ -543,20 +544,20 @@ namespace ScriptCanvas
{
const auto& inputVariable = outCall->GetInput(inputIndex).m_value;
out.outputs.push_back
({ GetOriginalVariableName(inputVariable, &nodeling)
, inputVariable->m_name
, inputVariable->m_datum.GetType()
, inputVariable->m_sourceVariableId });
({ GetOriginalVariableName(inputVariable, &nodeling)
, inputVariable->m_name
, inputVariable->m_datum.GetType()
, inputVariable->m_sourceVariableId });
}
for (size_t returnValueIndex = 0; returnValueIndex < outCall->GetReturnValueCount(); ++returnValueIndex)
{
const auto& returnValueVariable = outCall->GetReturnValue(returnValueIndex).second->m_source;
out.outputs.push_back
({ GetOriginalVariableName(returnValueVariable, &nodeling)
, returnValueVariable->m_name
, returnValueVariable->m_datum.GetType()
, returnValueVariable->m_sourceVariableId });
({ GetOriginalVariableName(returnValueVariable, &nodeling)
, returnValueVariable->m_name
, returnValueVariable->m_datum.GetType()
, returnValueVariable->m_sourceVariableId });
}
AZStd::const_pointer_cast<ExecutionTree>(outCall)->SetOutCallIndex(m_outIndexCount);
@@ -697,7 +698,7 @@ namespace ScriptCanvas
}
AZStd::string AbstractCodeModel::CheckUniqueInterfaceNames
( AZStd::string_view candidate
(AZStd::string_view candidate
, AZStd::string_view defaultName
, AZStd::unordered_set<AZStd::string>& uniqueNames
, const AZStd::unordered_set<const ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>& nodelingsOut)
@@ -755,7 +756,7 @@ namespace ScriptCanvas
}
AZStd::vector<Grammar::VariableConstPtr> AbstractCodeModel::CombineVariableLists
( const AZStd::vector<Nodeable*>& constructionNodeables
(const AZStd::vector<Nodeable*>& constructionNodeables
, const AZStd::vector<AZStd::pair<VariableId, Datum>>& constructionInputVariables
, const AZStd::vector<AZStd::pair<VariableId, Data::EntityIDType>>& entityIds) const
{
@@ -766,12 +767,12 @@ namespace ScriptCanvas
const void* nodeableAsVoidPtr = nodeable;
auto iter = AZStd::find_if
( m_nodeablesByNode.begin()
(m_nodeablesByNode.begin()
, m_nodeablesByNode.end()
, [&](const auto& candidate)
{
return candidate.second->m_nodeable->m_datum.GetAsDanger() == nodeableAsVoidPtr;
});
, [&](const auto& candidate)
{
return candidate.second->m_nodeable->m_datum.GetAsDanger() == nodeableAsVoidPtr;
});
if (iter != m_nodeablesByNode.end())
{
@@ -784,7 +785,7 @@ namespace ScriptCanvas
for (const auto& variable : entityIds)
{
auto iter = AZStd::find_if( m_variables.begin(), m_variables.end(), [&](const auto& candidate) {
auto iter = AZStd::find_if(m_variables.begin(), m_variables.end(), [&](const auto& candidate) {
if (candidate->m_datum.GetType() == Data::Type::EntityID())
{
bool isVariableIdMatch = candidate->m_sourceVariableId == variable.first;
@@ -836,7 +837,7 @@ namespace ScriptCanvas
{
ExecutionTreePtr child = AZStd::make_shared<ExecutionTree>();
child->SetParent(parent);
child->SetId({node, slot});
child->SetId({ node, slot });
child->SetScope(parent ? parent->ModScope() : m_graphScope);
return child;
}
@@ -944,7 +945,7 @@ namespace ScriptCanvas
AddError(node.GetEntityId(), nullptr, ParseErrors::EventNodeConnectCallMalformed);
return false;
}
auto azEventNode = azrtti_cast<const ScriptCanvas::Nodes::Core::AzEventHandler*>(&node);
if (!azEventNode)
{
@@ -1081,7 +1082,7 @@ namespace ScriptCanvas
{
// Node output is input data to a function definition
OutputAssignmentPtr output = CreateOutput(execution, outputSlot, {}, "input");
if (auto variable = FindReferencedVariableChecked(execution, outputSlot))
{
output->m_assignments.push_back(variable);
@@ -1222,11 +1223,11 @@ namespace ScriptCanvas
if (m_uniqueInNames.contains(displayName))
{
AddError
( nodeling->GetEntityId()
(nodeling->GetEntityId()
, nullptr
, AZStd::string::format
( "%s is the name of multiple In Nodelings in a subgraph,\n"
"this will result in a difficult or impossible to use Function Node when used in another graph", displayName.data()));
"this will result in a difficult or impossible to use Function Node when used in another graph", displayName.c_str()));
return;
}
else
@@ -1258,8 +1259,8 @@ namespace ScriptCanvas
AddError(nodeling->GetEntityId()
, nullptr
, AZStd::string::format
( "%s is the name of multiple In Nodelings in a subgraph,\n"
"this will result in a difficult or impossible to use Function Node when used in another graph", displayName.data()));
("%s is the name of multiple In Nodelings in a subgraph,\n"
"this will result in a difficult or impossible to use Function Node when used in another graph", displayName.data()));
}
else
{
@@ -1355,7 +1356,7 @@ namespace ScriptCanvas
{
AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format
( "Execution cycle detected (see connections to %s-%s. Use a looping node like While or For"
, node.GetDebugName().data(), outSlot.GetName().data()).data()));
, node.GetDebugName().c_str(), outSlot.GetName().c_str()).c_str()));
return true;
}
@@ -1368,12 +1369,12 @@ namespace ScriptCanvas
AbstractCodeModel::ReturnValueConnections AbstractCodeModel::FindAssignments(ExecutionTreeConstPtr execution, const Slot& output)
{
ReturnValueConnections connections;
if (auto variable = FindReferencedVariableChecked(execution, output))
{
connections.m_returnValuesOrReferences.push_back(variable);
}
auto connectedNodes = execution->GetId().m_node->GetConnectedNodes(output);
bool isAtLeastOneReturnValueFound = false;
@@ -1477,7 +1478,7 @@ namespace ScriptCanvas
return slot && candidate.second == slot;
});
return iter != scriptCanvasNodesConnectedToInput.end() ? *iter : EndpointResolved{nullptr, nullptr};
return iter != scriptCanvasNodesConnectedToInput.end() ? *iter : EndpointResolved{ nullptr, nullptr };
};
for (size_t childIndex = 0; childIndex < outputSource->GetChildrenCount(); ++childIndex)
@@ -1543,8 +1544,8 @@ namespace ScriptCanvas
for (const auto& otherConnections : scriptCanvasNodesConnectedToInput)
{
if (otherConnections.first == outputSCNode
&& otherConnections.second != outputSlot
&& InSimultaneousDataPath(*outputSCNode, *otherConnections.second, *outputSlot))
&& otherConnections.second != outputSlot
&& InSimultaneousDataPath(*outputSCNode, *otherConnections.second, *outputSlot))
{
AddError(executionWithInput->GetId().m_node->GetEntityId(), executionWithInput, ParseErrors::MultipleSimulaneousInputValues);
}
@@ -1570,7 +1571,7 @@ namespace ScriptCanvas
VariableConstPtr AbstractCodeModel::FindVariable(const AZ::EntityId& sourceNodeId) const
{
auto resultIter = AZStd::find_if
( m_variables.begin()
(m_variables.begin()
, m_variables.end()
, [&sourceNodeId](const VariableConstPtr& candidate) { return candidate->m_nodeableNodeId == sourceNodeId; });
@@ -1580,7 +1581,7 @@ namespace ScriptCanvas
VariableConstPtr AbstractCodeModel::FindVariable(const VariableId& sourceVariableId) const
{
auto resultIter = AZStd::find_if
( m_variables.begin()
(m_variables.begin()
, m_variables.end()
, [&sourceVariableId](const VariableConstPtr& candidate) { return candidate->m_sourceVariableId == sourceVariableId; });
@@ -1591,7 +1592,7 @@ namespace ScriptCanvas
{
if (IsUserNodeable(variable))
{
auto iter = AZStd::find_if(m_nodeablesByNode.begin(), m_nodeablesByNode.end(), [&variable](auto& candidate){ return candidate.second->m_nodeable == variable; });
auto iter = AZStd::find_if(m_nodeablesByNode.begin(), m_nodeablesByNode.end(), [&variable](auto& candidate) { return candidate.second->m_nodeable == variable; });
if (iter != m_nodeablesByNode.end())
{
return iter->second->m_simpleName;
@@ -1604,7 +1605,7 @@ namespace ScriptCanvas
const AZStd::pair<VariableConstPtr, AZStd::string>* AbstractCodeModel::FindStaticVariable(VariableConstPtr variable) const
{
auto iter = AZStd::find_if
( m_staticVariableNames.begin()
(m_staticVariableNames.begin()
, m_staticVariableNames.end()
, [&](const auto& candidate) { return candidate.first == variable; });
@@ -1622,7 +1623,7 @@ namespace ScriptCanvas
else
{
const_cast<AbstractCodeModel*>(this)->AddError(execution, aznew ParseError(slot.GetNodeId(), AZStd::string::format
( "Failed to find member variable for Variable Reference in slot: %s Id: %s"
("Failed to find member variable for Variable Reference in slot: %s Id: %s"
, slot.GetName().data()
, slot.GetVariableReference().ToString().data())));
}
@@ -1965,7 +1966,7 @@ namespace ScriptCanvas
return {};
}
AZStd::sys_time_t AbstractCodeModel::GetParseDuration() const
{
return m_parseDuration;
@@ -2091,7 +2092,7 @@ namespace ScriptCanvas
{
const AZStd::vector<const Slot*>& slots = outcome.GetValue();
if (AZStd::find(slots.begin(), slots.end(), &reference) != slots.end()
&& AZStd::find(slots.begin(), slots.end(), &candidate) != slots.end())
&& AZStd::find(slots.begin(), slots.end(), &candidate) != slots.end())
{
return true;
}
@@ -2165,7 +2166,7 @@ namespace ScriptCanvas
if (m_start)
{
roots.push_back(m_start);
roots.push_back(m_start);
}
for (auto& nodeableParse : m_nodeablesByNode)
@@ -2237,7 +2238,7 @@ namespace ScriptCanvas
{
ExecutionTreePtr child = CreateChild(parent, node, outSlot);
child->SetScope(AZStd::make_shared<Scope>());
child->ModScope()->m_parent = parent ? parent->ModScope(): m_graphScope;
child->ModScope()->m_parent = parent ? parent->ModScope() : m_graphScope;
return child;
}
@@ -2258,12 +2259,16 @@ namespace ScriptCanvas
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
AddAllVariablesPreParse();
if (!IsErrorFree())
{
return;
}
// parse basic editor nodes as they may add implicit variables
for (auto& nodeEntity : m_source.m_graphData->m_nodes)
{
if (nodeEntity)
@@ -2296,18 +2301,27 @@ namespace ScriptCanvas
return;
}
// parse the implicit variables added by ebus handling syntax sugar
ParseAutoConnectedEBusHandlerVariables();
// all possible data is available, now parse execution, starting with "main", currently keyed to RuntimeComponent::Activate
Parse(m_startNodes);
// parse any function introduced by nodes other than On Graph Start/"main"
for (auto node : m_possibleExecutionRoots)
{
ParseExecutionTreeRoots(*node);
}
// parse functions introduced by variable change events
ParseVariableHandling();
// parse all user function and function object signatures
ParseUserFunctionTopology();
ParseConstructionInputVariables();
// culls unused variables, and determine whether the the graph defines an object or static functionality
ParseExecutionCharacteristics();
// now that variables have been culled, determined what data needs to be initialized by an external source
ParseConstructionInputVariables();
// now that externally initialized data has been identified, associate local, static initializers with individual functions
ParseFunctionLocalStaticUseage();
// The Order Matters: end
// from here on, nothing more needs to happen during simple parsing
// for example, in the editor, to get validation on syntax based effects for the view
@@ -2315,7 +2329,10 @@ namespace ScriptCanvas
if (IsErrorFree())
{
// the graph could have used several user graphs which required construction, and maybe multiple instances of the same user asset
// this will create indices for those nodes to be able to pass in the proper entry in the construction argument tree at translation and runtime
ParseDependenciesAssetIndicies();
// protect all names against keyword collision and language naming violations
ConvertNamesToIdentifiers();
if (m_source.m_addDebugInfo)
@@ -2334,7 +2351,7 @@ namespace ScriptCanvas
AddError(nullptr, ValidationConstPtr(aznew InactiveGraph()));
}
}
else
else
{
MarkParseStop();
@@ -2629,9 +2646,9 @@ namespace ScriptCanvas
// create a variable declaration
ExecutionTreePtr variableConstruction = CreateChild(inPreviouslyExecutedScopeResult.m_mostParent->ModParent(), nullptr, nullptr);
variableConstruction->AddInput({ nullptr , newInputResultOfAssignment, DebugDataSource::FromInternal()});
variableConstruction->AddInput({ nullptr , newInputResultOfAssignment, DebugDataSource::FromInternal() });
variableConstruction->SetSymbol(Symbol::VariableDeclaration);
// splice the variable declaration right before the most parent for loop is executed
auto positionOutcome = mostForLoopParent->RemoveChild(inPreviouslyExecutedScopeResult.m_mostParent);
if (!positionOutcome.IsSuccess())
@@ -2701,7 +2718,7 @@ namespace ScriptCanvas
case VariableConstructionRequirement::InputVariable:
{
auto variableID = variable->m_sourceVariableId.IsValid() ? variable->m_sourceVariableId : VariableId::MakeVariableId();
auto variableID = variable->m_sourceVariableId.IsValid() ? variable->m_sourceVariableId : MakeParserGeneratedId(m_generatedIdCount++);
inputVariableIds.push_back(variableID);
inputVariablesById.insert({ variableID, variable });
// sort revealed a datum copy issue: type is not preserved, workaround below
@@ -2755,7 +2772,7 @@ namespace ScriptCanvas
{
auto& localStatics = ModStaticVariablesNames(staticVariable->m_source);
auto iter = AZStd::find_if
( localStatics.begin()
(localStatics.begin()
, localStatics.end()
, [&](const auto& candidate) { return candidate.first == staticVariable; });
@@ -2834,16 +2851,16 @@ namespace ScriptCanvas
{
switch (execution->GetSymbol())
{
// nothing required
// nothing required
case Symbol::PlaceHolderDuringParsing:
break;
// out and return value information
// out and return value information
case Symbol::FunctionDefinition:
AddDebugInformationFunctionDefinition(execution);
break;
// add in out everything
// add in out everything
case Symbol::ForEach:
case Symbol::FunctionCall:
case Symbol::OperatorAddition:
@@ -2857,7 +2874,7 @@ namespace ScriptCanvas
AddDebugInformationOut(execution);
break;
// add in but not out
// add in but not out
case Symbol::Break:
case Symbol::LogicalAND:
case Symbol::LogicalNOT:
@@ -2871,8 +2888,8 @@ namespace ScriptCanvas
AddDebugInformationIn(execution);
break;
// add in-debug-info if the if condition is NOT prefixed with logic or comparison expression (which will have the in-debug-info)
// add out-debug-info in all cases including including empty cases
// add in-debug-info if the if condition is NOT prefixed with logic or comparison expression (which will have the in-debug-info)
// add out-debug-info in all cases including including empty cases
case Symbol::IfCondition:
if (!(execution->GetId().m_node->IsIfBranchPrefacedWithBooleanExpression()))
{
@@ -2900,7 +2917,7 @@ namespace ScriptCanvas
if (dependencies.userSubgraphs.find(m_source.m_namespacePath) != dependencies.userSubgraphs.end())
{
AZStd::string circularDependency = AZStd::string::format
( ParseErrors::CircularDependencyFormat
(ParseErrors::CircularDependencyFormat
, m_source.m_name.data()
, node.GetDebugName().data()
, m_source.m_name.data());
@@ -2908,6 +2925,7 @@ namespace ScriptCanvas
AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), circularDependency));
}
// #functions2 make this use an identifier for the node, for property window display and easier find/replace updates
// this part must NOT recurse, the dependency tree should remain a tree and not be flattened
m_orderedDependencies.source.MergeWith(dependencies);
}
@@ -2950,11 +2968,32 @@ namespace ScriptCanvas
{
if (!input->m_sourceVariableId.IsValid() && IsEntityIdThatRequiresRuntimeRemap(input))
{
input->m_sourceVariableId = VariableId::MakeVariableId();
input->m_sourceVariableId = MakeParserGeneratedId(m_generatedIdCount++);
input->m_source = nullptr;
// promote to member variable for at this stage, optimizations on data flow will occur later
input->m_isMember = true;
input->m_name = m_graphScope->AddVariableName(input->m_name);
AZStd::string entityVariableName;
if (slotAndVariable.m_slot)
{
if (execution->GetId().m_node)
{
entityVariableName.append(execution->GetId().m_node->GetNodeName());
entityVariableName.append(".");
entityVariableName.append(slotAndVariable.m_slot->GetName());
}
else
{
entityVariableName.append(slotAndVariable.m_slot->GetName());
}
}
else
{
entityVariableName = input->m_name;
}
input->m_name = m_graphScope->AddVariableName(entityVariableName);
AddVariable(input);
}
}
@@ -3020,11 +3059,11 @@ namespace ScriptCanvas
CullUnusedVariables();
if (allRootsArePure
&& m_ebusHandlingByNode.empty()
&& m_eventHandlingByNode.empty()
&& m_nodeablesByNode.empty()
&& m_variableWriteHandlingByVariable.empty()
&& m_subgraphInterface.IsParsedPure())
&& m_ebusHandlingByNode.empty()
&& m_eventHandlingByNode.empty()
&& m_nodeablesByNode.empty()
&& m_variableWriteHandlingByVariable.empty()
&& m_subgraphInterface.IsParsedPure())
{
if (m_start)
{
@@ -3077,7 +3116,7 @@ namespace ScriptCanvas
void AbstractCodeModel::ParseExecutionLoop(ExecutionTreePtr executionLoop)
{
AddDebugInfiniteLoopDetectionInLoop(executionLoop);
auto loopSlot = executionLoop->GetId().m_node->GetSlot(executionLoop->GetId().m_node->GetLoopSlotId());
AZ_Assert(loopSlot, "Node did not return a valid loop slot");
ExecutionTreePtr executionLoopBody = OpenScope(executionLoop, executionLoop->GetId().m_node, loopSlot);
@@ -3255,7 +3294,7 @@ namespace ScriptCanvas
}
else if (numConnections == 1)
{
ParseExecutionFunctionRecurse(execution, execution->ModChild(0), outSlot, executionOutNodes[0]);
ParseExecutionFunctionRecurse(execution, execution->ModChild(0), outSlot, executionOutNodes[0]);
}
else
{
@@ -3762,7 +3801,7 @@ namespace ScriptCanvas
trueValue->m_source = once;
trueValue->m_datum = Datum(Data::BooleanType(true));
once->AddInput({ nullptr, trueValue, DebugDataSource::FromInternal() });
ExecutionTreePtr onReset = CreateChild(once, once->GetId().m_node, onceResetSlot);
onReset->SetSymbol(Symbol::PlaceHolderDuringParsing);
onReset->MarkInputOutputPreprocessed();
@@ -3849,7 +3888,7 @@ namespace ScriptCanvas
executionSwitch->SetSymbol(Symbol::Switch);
ParseExecutionSequentialChildren(executionSwitch);
}
// the execution will already have its function definition defined, this will create the body of that function
void AbstractCodeModel::ParseExecutionTreeBody(ExecutionTreePtr execution, const Slot& outSlot)
{
@@ -4112,7 +4151,7 @@ namespace ScriptCanvas
{
auto& userFunctionNode = *userFunctionIter->first;
auto outSlots = userFunctionNode.GetSlotsByType(CombinedSlotType::ExecutionOut);
if (outSlots.empty() || !outSlots.front())
{
AddError(userFunctionNode.GetEntityId(), nullptr, ScriptCanvas::ParseErrors::NoOutSlotInFunctionDefinitionStart);
@@ -4167,6 +4206,32 @@ namespace ScriptCanvas
ParseExecutionLoop(execution);
}
void AbstractCodeModel::ParseFunctionLocalStaticUseage()
{
for (auto execution : ModAllExecutionRoots())
{
if (auto localVariables = GetLocalVariables(execution))
{
for (auto variable : *localVariables)
{
if (const AZStd::pair<VariableConstPtr, AZStd::string>* pair = FindStaticVariable(variable))
{
auto& localStatics = ModStaticVariablesNames(execution);
auto iter = AZStd::find_if
( localStatics.begin()
, localStatics.end()
, [&](const auto& candidate) { return candidate.first == variable; });
if (iter == localStatics.end())
{
localStatics.push_back(*pair);
}
}
}
}
}
}
void AbstractCodeModel::ParseImplicitVariables(const Node& node)
{
if (IsCycle(node))
@@ -4179,7 +4244,7 @@ namespace ScriptCanvas
auto onceControl = AddMemberVariable(Datum(Data::BooleanType(true)), "onceControl");
m_controlVariablesBySourceNode.insert({ &node, onceControl });
}
else
else
{
const auto nodelingType = CheckNodelingType(node);
if (nodelingType != NodelingType::None)
@@ -4208,7 +4273,7 @@ namespace ScriptCanvas
{
const VariableId assignedFromId = execution->GetId().m_node->GetVariableIdRead(execution->GetId().m_slot);
auto variableRead = assignedFromId.IsValid() ? FindVariable(assignedFromId) : nullptr;
if (variableRead)
{
// nullptr is acceptable here
@@ -4314,7 +4379,7 @@ namespace ScriptCanvas
for (auto sourceNodeAndSlot : nodes)
{
AddError(nullptr, aznew ScopedDataConnectionEvent
( execution->GetNodeId()
(execution->GetNodeId()
, targetNode
, targetSlot
, *sourceNodeAndSlot.first
@@ -4324,7 +4389,7 @@ namespace ScriptCanvas
}
}
}
bool AbstractCodeModel::ParseInputThisPointer(ExecutionTreePtr execution)
{
auto node = execution->GetId().m_node;
@@ -4364,7 +4429,7 @@ namespace ScriptCanvas
{
auto node2 = execution->GetId().m_node;
AddError(execution, aznew ParseError(node2->GetEntityId(), AZStd::string::format
( "Failed to find member variable for Node: %s Id: %s"
("Failed to find member variable for Node: %s Id: %s"
, node2->GetNodeName().data()
, node2->GetEntityId().ToString().data()).data()));
}
@@ -4394,7 +4459,7 @@ namespace ScriptCanvas
{
auto node2 = execution->GetId().m_node;
AddError(execution, aznew ParseError(node2->GetEntityId(), AZStd::string::format
( "Failed to find member variable for Node: %s Id: %s"
("Failed to find member variable for Node: %s Id: %s"
, node2->GetNodeName().data()
, node2->GetEntityId().ToString().data()).data()));
}
@@ -4451,10 +4516,10 @@ namespace ScriptCanvas
}
ExecutionChild* executionChildInParent = &parent->ModChild(indexInParentCall);
const size_t executionInputCount = execution->GetInputCount();
const size_t thisInputOffset = execution->InputHasThisPointer() ? 1 : 0;
// the original index has ALL the input from the slots on the node
// create multiple calls with separate function call nodes, but ONLY take the inputs required
// as indicated by the function call info
@@ -4811,7 +4876,7 @@ namespace ScriptCanvas
}
}
}
void AbstractCodeModel::ParseReturnValue(ExecutionTreePtr execution, const Slot& returnValueSlot)
{
if (auto variable = FindReferencedVariableChecked(execution, returnValueSlot))
@@ -4862,9 +4927,9 @@ namespace ScriptCanvas
{
ParseUserIn(iter.second, iter.first);
}
m_userInsThatRequireTopology.clear();
ParseUserOuts();
auto parseOutcome = m_subgraphInterface.Parse();
@@ -4920,7 +4985,7 @@ namespace ScriptCanvas
AddError(root, aznew Internal::ParseError(AZ::EntityId(), "In Nodeling didn't parse properly, there were still leaves without nodelings in the execution tree."));
return;
}
}
}
auto& outCallsChecked = listenerCheck.GetOutCalls();
if (!result.addSingleOutToMap && outCallsChecked.empty())
@@ -4968,8 +5033,8 @@ namespace ScriptCanvas
}
if ((!root->HasExplicitUserOutCalls())
&& root->GetReturnValueCount() > 0
&& branches > 1)
&& root->GetReturnValueCount() > 0
&& branches > 1)
{
AddError(root->GetNodeId(), root, ScriptCanvas::ParseErrors::TooManyBranchesForReturn);
return;
@@ -5005,7 +5070,7 @@ namespace ScriptCanvas
AZStd::pair<const Slot*, ReturnValueConstPtr> returnValue = execution->GetReturnValue(execution->GetReturnValueCount() - 1);
AZStd::const_pointer_cast<ReturnValue>(returnValue.second)->m_isNewValue = true;
}
}
}
}
}
@@ -5029,7 +5094,7 @@ namespace ScriptCanvas
result.addExplicitOutCalls = nodelingsOutCount > 1;
result.isSimpleFunction = !result.addExplicitOutCalls;
}
else
else
{
// user explicitly defined at least 1 Out and there are execution leaves without Outs, so we provide an Out to any missing ones
result.addSingleOutToMap = true;
@@ -5037,7 +5102,7 @@ namespace ScriptCanvas
result.addExplicitOutCalls = true;
result.isSimpleFunction = false;
}
return result;
}
@@ -5058,41 +5123,41 @@ namespace ScriptCanvas
void AbstractCodeModel::ParseUserLatentData(ExecutionTreePtr execution)
{
if (execution->IsOnLatentPath())
{
if (execution->GetChildrenCount() == 0)
{
execution->AddChild({ nullptr, {}, nullptr });
}
auto& executionChild = execution->ModChild(0);
// inputs are return values expected from the latent out call
for (auto& returnValue : FindUserLatentReturnValues(execution))
{
// if there are return values, we can continue execution after
// the nodeling out that is in the path (disable the contract)
// and we must make sure there's ONLY ONE
// and no immediate ins
auto outputAssignment = CreateOutputAssignment(returnValue);
executionChild.m_output.push_back({ nullptr, outputAssignment });
}
auto methodRoot = execution->ModRoot();
// outputs are inputs to the latent out call
for (auto& inputValue : FindUserLatentOutput(execution))
{
inputValue->m_source = methodRoot;
execution->AddInput({ nullptr, inputValue, DebugDataSource::FromVariable(SlotId{}, inputValue->m_datum.GetType(), inputValue->m_sourceVariableId) });
}
methodRoot->CopyInput(execution, ExecutionTree::RemapVariableSource::No);
}
else
{
AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), "immediate execution parsed data in latent thread"));
}
if (execution->IsOnLatentPath())
{
if (execution->GetChildrenCount() == 0)
{
execution->AddChild({ nullptr, {}, nullptr });
}
auto& executionChild = execution->ModChild(0);
// inputs are return values expected from the latent out call
for (auto& returnValue : FindUserLatentReturnValues(execution))
{
// if there are return values, we can continue execution after
// the nodeling out that is in the path (disable the contract)
// and we must make sure there's ONLY ONE
// and no immediate ins
auto outputAssignment = CreateOutputAssignment(returnValue);
executionChild.m_output.push_back({ nullptr, outputAssignment });
}
auto methodRoot = execution->ModRoot();
// outputs are inputs to the latent out call
for (auto& inputValue : FindUserLatentOutput(execution))
{
inputValue->m_source = methodRoot;
execution->AddInput({ nullptr, inputValue, DebugDataSource::FromVariable(SlotId{}, inputValue->m_datum.GetType(), inputValue->m_sourceVariableId) });
}
methodRoot->CopyInput(execution, ExecutionTree::RemapVariableSource::No);
}
else
{
AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), "immediate execution parsed data in latent thread"));
}
}
void AbstractCodeModel::ParseUserOutCall(ExecutionTreePtr execution)
@@ -5164,7 +5229,7 @@ namespace ScriptCanvas
if (!IsConnectedToUserIn(nodeling))
{
const auto report = AZStd::string::format
( "Nodeling Out (%s) not connected to Nodeling In, functionality cannot be executed", nodeling->GetDisplayName().data());
("Nodeling Out (%s) not connected to Nodeling In, functionality cannot be executed", nodeling->GetDisplayName().data());
AddError(nullptr, aznew Internal::ParseError(nodeling->GetEntityId(), report));
}
@@ -5172,7 +5237,7 @@ namespace ScriptCanvas
else
{
const auto report = AZStd::string::format
("null nodeling in immediate out list");
("null nodeling in immediate out list");
AddError(nullptr, aznew Internal::ParseError(nodeling->GetEntityId(), report));
}
@@ -5210,27 +5275,8 @@ namespace ScriptCanvas
TraverseTree(execution, listener);
const auto& usage = listener.GetUsedVariables();
const bool usesOnlyLocalVariables = usage.memberVariables.empty() && usage.implicitMemberVariables.empty();
m_variableUse.localVariables.insert(usage.localVariables.begin(), usage.localVariables.end());
m_variableUse.memberVariables.insert(usage.memberVariables.begin(), usage.memberVariables.end());
for (auto variable : m_variableUse.localVariables)
{
if (const AZStd::pair<VariableConstPtr, AZStd::string>* pair = FindStaticVariable(variable))
{
auto& localStatics = ModStaticVariablesNames(execution);
auto iter = AZStd::find_if
(localStatics.begin()
, localStatics.end()
, [&](const auto& candidate) { return candidate.first == variable; });
if (iter == localStatics.end())
{
localStatics.push_back(*pair);
}
}
}
m_variableUseByExecution.emplace(execution, listener.MoveUsedVariables());
return (!usage.usesExternallyInitializedVariables) && usesOnlyLocalVariables && listener.IsPure();
}
@@ -5285,7 +5331,7 @@ namespace ScriptCanvas
RemoveFromTree(noOpChild);
}
}
void AbstractCodeModel::RemoveFromTree(ExecutionTreePtr execution)
{
if (!execution->GetParent())
@@ -5304,7 +5350,7 @@ namespace ScriptCanvas
{
AddError(execution->GetNodeId(), execution, ScriptCanvas::ParseErrors::RequiredOutputRemoved);
}
if (childCount != 0)
{
if (childCount > 1)
@@ -5332,7 +5378,7 @@ namespace ScriptCanvas
execution->Clear();
}
AZ::Outcome<AZStd::pair<size_t, ExecutionChild>> AbstractCodeModel::RemoveChild(const ExecutionTreePtr& execution, const ExecutionTreeConstPtr& child)
{
return execution->RemoveChild(child);
@@ -5342,7 +5388,5 @@ namespace ScriptCanvas
{
return type == Data::eType::BehaviorContextObject;
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -71,7 +71,7 @@ namespace ScriptCanvas
AZStd::optional<AZStd::pair<size_t, Grammar::DependencyInfo>> CheckUserNodeableDependencyConstructionIndex(VariableConstPtr nodeable) const;
AZStd::vector<VariableConstPtr> CombineVariableLists
( const AZStd::vector<Nodeable*>& constructionNodeables
(const AZStd::vector<Nodeable*>& constructionNodeables
, const AZStd::vector<AZStd::pair<VariableId, Datum>>& constructionInputVariableIds
, const AZStd::vector<AZStd::pair<VariableId, Data::EntityIDType>>& entityIds) const;
@@ -120,7 +120,7 @@ namespace ScriptCanvas
const ParsedRuntimeInputs& GetRuntimeInputs() const;
const Source& GetSource() const;
const AZStd::string& GetSourceString() const;
ExecutionTreeConstPtr GetStart() const;
@@ -150,21 +150,19 @@ namespace ScriptCanvas
bool IsUserNodeable(VariableConstPtr variable) const;
bool HasUserNodeableDependenciesInVariables() const;
template<typename T>
AZStd::vector<Grammar::VariableConstPtr> ToVariableList(const AZStd::vector<AZStd::pair<VariableId, T>>& source) const;
private:
//////////////////////////////////////////////////////////////////////////
// Internal parsing
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Internal parsing
//////////////////////////////////////////////////////////////////////////
struct ReturnValueConnections
{
bool m_hasOtherConnections = false;
AZStd::vector<VariableConstPtr> m_returnValuesOrReferences;
};
void AddAllVariablesPreParse();
void AddAllVariablesPreParse_LegacyFunctions();
@@ -210,7 +208,7 @@ namespace ScriptCanvas
bool CheckCreateRoot(const Node& node);
AZStd::string CheckUniqueInterfaceNames
( AZStd::string_view candidate
(AZStd::string_view candidate
, AZStd::string_view defaultName
, AZStd::unordered_set<AZStd::string>& uniqueNames
, const AZStd::unordered_set<const ScriptCanvas::Nodes::Core::FunctionDefinitionNode*>& nodelingsOut);
@@ -340,7 +338,7 @@ namespace ScriptCanvas
void ParseExecutionLogicalExpression(ExecutionTreePtr execution, Symbol symbol);
void ParseExecutionLoop(ExecutionTreePtr execution);
void ParseExecutionMultipleOutSyntaxSugar(ExecutionTreePtr execution, const EndpointsResolved& executionOutNodes, const AZStd::vector<const Slot*>& outSlots);
void ParseExecutionMultipleOutSyntaxSugarOfSequencNode(ExecutionTreePtr sequence);
@@ -368,6 +366,8 @@ namespace ScriptCanvas
void ParseExecutionWhileLoop(ExecutionTreePtr execution);
void ParseFunctionLocalStaticUseage();
void ParseImplicitVariables(const Node& node);
void ParseInputData(ExecutionTreePtr execution);
@@ -428,7 +428,7 @@ namespace ScriptCanvas
void PruneNoOpChildren(const ExecutionTreePtr& execution);
AZ::Outcome<AZStd::pair<size_t, ExecutionChild>> RemoveChild(const ExecutionTreePtr& execution, const ExecutionTreeConstPtr& child);
void RemoveFromTree(ExecutionTreePtr execution);
struct ConnectionInPreviouslyExecutedScope
@@ -473,7 +473,7 @@ namespace ScriptCanvas
}
void AddExecutionMapIn
( UserInParseTopologyResult result
(UserInParseTopologyResult result
, ExecutionTreeConstPtr root
, const AZStd::vector<ExecutionTreeConstPtr>& outCalls
, AZStd::string_view defaultOutName
@@ -505,6 +505,7 @@ namespace ScriptCanvas
static UserInParseTopologyResult ParseUserInTolopology(size_t nodelingsOutCount, size_t leavesWithoutNodelingsCount);
size_t m_outIndexCount = 0;
size_t m_generatedIdCount = 0;
ExecutionTreePtr m_start;
AZStd::vector<const Nodes::Core::Start*> m_startNodes;
ScopePtr m_graphScope;
@@ -513,7 +514,7 @@ namespace ScriptCanvas
AZStd::unordered_set<VariableConstPtr> m_userNodeables;
AZStd::unordered_map<VariableConstPtr, DependencyInfo> m_dependencyByVariable;
AZStd::vector<VariableConstPtr> m_variables;
AZStd::vector<const Node*> m_possibleExecutionRoots;
@@ -621,7 +622,7 @@ namespace ScriptCanvas
for (const auto& variable : source)
{
auto iter = AZStd::find_if
( m_variables.begin()
(m_variables.begin()
, m_variables.end()
, [&](const auto& candidate) { return candidate->m_sourceVariableId == variable.first; });
@@ -633,7 +634,5 @@ namespace ScriptCanvas
return variables;
}
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -47,6 +47,10 @@ namespace ParsingUtilitiesCpp
using namespace ScriptCanvas;
using namespace ScriptCanvas::Grammar;
const AZ::u64 k_parserGeneratedMask = 0x7FC0616C94E7465F;
const size_t k_maskIndex = 0;
const size_t k_countIndex = 1;
class PrettyPrinter
: public ExecutionTreeTraversalListener
{
@@ -85,7 +89,7 @@ namespace ParsingUtilitiesCpp
{
m_result += AZStd::string::format(" # children: %zu", childCount);
}
if (m_marker == execution)
{
m_result += " <<<< MARKER <<<< ";
@@ -97,7 +101,7 @@ namespace ParsingUtilitiesCpp
m_result += "\n";
}
void EvaluateRoot(ExecutionTreeConstPtr node, const Slot* )
void EvaluateRoot(ExecutionTreeConstPtr node, const Slot*)
{
m_result += "\nRoot:\n";
}
@@ -356,7 +360,7 @@ namespace ScriptCanvas
else if (nodeling->IsExecutionExit())
{
return NodelingType::Out;
}
}
}
return NodelingType::None;
@@ -785,7 +789,7 @@ namespace ScriptCanvas
{
return execution->GetInputCount() > index
&& ((execution->GetInput(index).m_value->m_datum.GetAs<Data::NamedEntityIDType>() && *execution->GetInput(index).m_value->m_datum.GetAs<Data::NamedEntityIDType>() == GraphOwnerId && !execution->GetInput(index).m_value->m_isExposedToConstruction)
|| (execution->GetInput(index).m_value->m_datum.GetAs<Data::EntityIDType>() && *execution->GetInput(index).m_value->m_datum.GetAs<Data::EntityIDType>() == GraphOwnerId && !execution->GetInput(index).m_value->m_isExposedToConstruction));
|| (execution->GetInput(index).m_value->m_datum.GetAs<Data::EntityIDType>() && *execution->GetInput(index).m_value->m_datum.GetAs<Data::EntityIDType>() == GraphOwnerId && !execution->GetInput(index).m_value->m_isExposedToConstruction));
}
bool IsIsNull(const ExecutionTreeConstPtr& execution)
@@ -855,7 +859,7 @@ namespace ScriptCanvas
return true;
}
}
return IsMidSequence(parent);
}
@@ -1001,10 +1005,16 @@ namespace ScriptCanvas
return true;
}
bool IsParserGeneratedId(const ScriptCanvas::VariableId& id)
{
using namespace ParsingUtilitiesCpp;
return reinterpret_cast<const AZ::u64*>(id.m_id.data)[k_maskIndex] == k_parserGeneratedMask;
}
bool IsPropertyExtractionSlot(const ExecutionTreeConstPtr& execution, const Slot* outputSlot)
{
auto iter = AZStd::find_if
( execution->GetPropertyExtractionSources().begin()
(execution->GetPropertyExtractionSources().begin()
, execution->GetPropertyExtractionSources().end()
, [&](const auto& iter) { return iter.first == outputSlot; });
@@ -1052,9 +1062,9 @@ namespace ScriptCanvas
bool IsSequenceNode(const ExecutionTreeConstPtr& execution)
{
return (IsSequenceNode(execution->GetId().m_node)
&& execution->GetId().m_slot->GetType() == CombinedSlotType::ExecutionIn);
&& execution->GetId().m_slot->GetType() == CombinedSlotType::ExecutionIn);
}
bool IsSwitchStatement(const ExecutionTreeConstPtr& execution)
{
return execution->GetId().m_node->IsSwitchStatement()
@@ -1120,6 +1130,16 @@ namespace ScriptCanvas
return AZStd::string::format("%s%s", k_memberNamePrefix, name.data());
}
VariableId MakeParserGeneratedId(size_t count)
{
using namespace ParsingUtilitiesCpp;
AZ::Uuid parserGenerated;
reinterpret_cast<AZ::u64*>(parserGenerated.data)[k_maskIndex] = k_parserGeneratedMask;
reinterpret_cast<AZ::u64*>(parserGenerated.data)[k_countIndex] = count;
return ScriptCanvas::VariableId(parserGenerated);
}
VariableConstructionRequirement ParseConstructionRequirement(VariableConstPtr variable)
{
if (IsEntityIdThatRequiresRuntimeRemap(variable))
@@ -1216,7 +1236,7 @@ namespace ScriptCanvas
result += AZStd::string::format("Variable: %s, Type: %s, Scope: %s, \n"
, variable->m_name.data()
, Data::GetName(variable->m_datum.GetType()).data()
, variable->m_isMember ? "Member" : "Local" );
, variable->m_isMember ? "Member" : "Local");
}
auto roots = model.GetAllExecutionRoots();
@@ -1261,11 +1281,11 @@ namespace ScriptCanvas
bool RequiresRuntimeRemap(const AZ::EntityId& entityId)
{
return entityId.IsValid()
return entityId.IsValid()
&& entityId != UniqueId
&& entityId != GraphOwnerId;
}
AZStd::string SlotNameToIndexString(const Slot& slot)
{
auto indexString = slot.GetName();
@@ -1445,5 +1465,5 @@ namespace ScriptCanvas
}
}
}
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -113,7 +113,7 @@ namespace ScriptCanvas
bool IsInfiniteSelfEntityActivationLoop(const AbstractCodeModel& model, ExecutionTreeConstPtr execution);
bool IsInfiniteSelfEntityActivationLoopRecurse(const AbstractCodeModel& model, ExecutionTreeConstPtr execution);
bool IsInfiniteVariableWriteHandlingLoop(const AbstractCodeModel& model, VariableWriteHandlingPtr variableHandling, ExecutionTreeConstPtr execution, bool isConnected);
bool IsInLoop(const ExecutionTreeConstPtr& execution);
@@ -144,6 +144,8 @@ namespace ScriptCanvas
bool IsOnSelfEntityActivated(const AbstractCodeModel& model, ExecutionTreeConstPtr execution);
bool IsParserGeneratedId(const VariableId& id);
bool IsPropertyExtractionSlot(const ExecutionTreeConstPtr& execution, const Slot* outputSlot);
bool IsPropertyExtractionNode(const ExecutionTreeConstPtr& execution);
@@ -178,6 +180,8 @@ namespace ScriptCanvas
bool IsWrittenMathExpression(const ExecutionTreeConstPtr& execution);
VariableId MakeParserGeneratedId(size_t count);
AZStd::string MakeMemberVariableName(AZStd::string_view name);
VariableConstructionRequirement ParseConstructionRequirement(Grammar::VariableConstPtr value);
@@ -203,6 +207,5 @@ namespace ScriptCanvas
void TraverseTree(const AbstractCodeModel& execution, ExecutionTreeTraversalListener& listener);
void TraverseTree(const ExecutionTreeConstPtr& execution, ExecutionTreeTraversalListener& listener);
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -99,9 +99,9 @@ namespace ScriptCanvas
m_inputs.clear();
m_outputs.clear();
}
bool FunctionPrototype::IsVoid() const
{
{
return m_outputs.empty();
}
@@ -200,24 +200,23 @@ namespace ScriptCanvas
baseName.append(suffix);
return AddVariableName(baseName);
}
AZ::s32 Scope::AddNameCount(AZStd::string_view name)
{
AZ::s32 count = -1;
ScopePtr ns = shared_from_this();
do
{
auto iter = ns->m_baseNameToCount.find(name);
if (iter != ns->m_baseNameToCount.end())
{
// a basename has been found in current or parent scope, get the latest count
count = iter->second;
break;
}
}
while ((ns = AZStd::const_pointer_cast<Scope>(ns->m_parent)));
} while ((ns = AZStd::const_pointer_cast<Scope>(ns->m_parent)));
auto iter = m_baseNameToCount.find(name);
if (iter == m_baseNameToCount.end())
@@ -235,7 +234,7 @@ namespace ScriptCanvas
const VariableData Source::k_emptyVardata{};
Source::Source
( const Graph& graph
(const Graph& graph
, const AZ::Data::AssetId& id
, const GraphData& graphData
, const VariableData& variableData
@@ -277,8 +276,8 @@ namespace ScriptCanvas
AzFramework::StringFunc::Path::StripExtension(namespacePath);
return AZ::Success(Source
( *request.graph
, request.assetId
(*request.graph
, request.scriptAssetId
, *graphData
, *sourceVariableData
, name
@@ -294,23 +293,23 @@ namespace ScriptCanvas
}
Variable::Variable(Datum&& datum)
: m_datum(datum)
: m_datum(datum)
{}
Variable::Variable(const Datum& datum, const AZStd::string& name, TraitsFlags traitsFlags)
: m_datum(datum)
, m_name(name)
, m_isConst(traitsFlags & TraitsFlags::Const)
, m_isMember(traitsFlags & TraitsFlags::Member)
, m_isConst(traitsFlags& TraitsFlags::Const)
, m_isMember(traitsFlags& TraitsFlags::Member)
{}
Variable::Variable(Datum&& datum, AZStd::string&& name, TraitsFlags&& traitsFlags)
: m_datum(datum)
, m_name(name)
, m_isConst(traitsFlags & TraitsFlags::Const)
, m_isMember(traitsFlags & TraitsFlags::Member)
, m_isConst(traitsFlags& TraitsFlags::Const)
, m_isMember(traitsFlags& TraitsFlags::Member)
{}
void Variable::Reflect(AZ::ReflectContext* reflectContext)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
@@ -339,5 +338,5 @@ namespace ScriptCanvas
m_variable = nullptr;
m_connectionVariable = nullptr;
}
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -12,7 +12,9 @@ namespace ScriptCanvas
namespace Grammar
{
AZ_CVAR(bool, g_disableParseOnGraphValidation, false, {}, AZ::ConsoleFunctorFlags::Null, "In case parsing the graph is interfering with opening a graph, disable parsing on validation");
AZ_CVAR(bool, g_printAbstractCodeModel, false, {}, AZ::ConsoleFunctorFlags::Null, "Print out the Abstract Code Model at the end of parsing for debug purposes.");
AZ_CVAR(bool, g_saveRawTranslationOuputToFile, false, {}, AZ::ConsoleFunctorFlags::Null, "Save out the raw result of translation for debug purposes.");
AZ_CVAR(bool, g_printAbstractCodeModel, true, {}, AZ::ConsoleFunctorFlags::Null, "Print out the Abstract Code Model at the end of parsing for debug purposes.");
AZ_CVAR(bool, g_printAbstractCodeModelAtPrefabTime, false, {}, AZ::ConsoleFunctorFlags::Null, "Print out the Abstract Code Model at the end of parsing (at prefab time) for debug purposes.");
AZ_CVAR(bool, g_saveRawTranslationOuputToFile, true, {}, AZ::ConsoleFunctorFlags::Null, "Save out the raw result of translation for debug purposes.");
AZ_CVAR(bool, g_saveRawTranslationOuputToFileAtPrefabTime, false, {}, AZ::ConsoleFunctorFlags::Null, "Save out the raw result of translation (at prefab time) for debug purposes.");
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -108,7 +108,7 @@ namespace ScriptCanvas
constexpr const char* k_InitializeExecutionOutByRequiredCountName = "InitializeExecutionOutByRequiredCount";
constexpr const char* k_InterpretedConfigurationPerformance = "SCRIPT_CANVAS_GLOBAL_PERFORMANCE";
constexpr const char* k_InterpretedConfigurationRelease = "SCRIPT_CANVAS_GLOBAL_RELEASE";
constexpr const char* k_NodeableCallInterpretedOut = "ExecutionOut";
constexpr const char* k_NodeableUserBaseClassName = "Nodeable";
constexpr const char* k_NodeableSetExecutionOutName = "SetExecutionOut";
@@ -120,7 +120,7 @@ namespace ScriptCanvas
constexpr const char* k_OnGraphStartFunctionName = "OnGraphStart";
constexpr const char* k_OverrideNodeableMetatableName = "OverrideNodeableMetatable";
constexpr const char* k_stringFormatLexicalScopeName = "string";
constexpr const char* k_stringFormatName = "format";
@@ -139,7 +139,7 @@ namespace ScriptCanvas
constexpr const char* k_DependentAssetsIndexArgName = "dependentAssetsIndex";
constexpr const char* k_UnpackDependencyConstructionArgsFunctionName = "UnpackDependencyConstructionArgs";
constexpr const char* k_UnpackDependencyConstructionArgsLeafFunctionName = "UnpackDependencyConstructionArgsLeaf";
enum class ExecutionCharacteristics : AZ::u32
{
Object,
@@ -147,7 +147,7 @@ namespace ScriptCanvas
};
// default to a pure, interpreted function
enum ExecutionStateSelection : AZ::u32
enum class ExecutionStateSelection : AZ::u32
{
InterpretedPure,
InterpretedPureOnGraphStart,
@@ -172,7 +172,7 @@ namespace ScriptCanvas
Count,
};
#undef REGISTER_ENUM
// create the Symbol strings
#define REGISTER_ENUM(x) #x,
static const char* g_SymbolNames[] =
@@ -247,7 +247,9 @@ namespace ScriptCanvas
AZ_CVAR_EXTERNED(bool, g_disableParseOnGraphValidation);
AZ_CVAR_EXTERNED(bool, g_printAbstractCodeModel);
AZ_CVAR_EXTERNED(bool, g_printAbstractCodeModelAtPrefabTime);
AZ_CVAR_EXTERNED(bool, g_saveRawTranslationOuputToFile);
AZ_CVAR_EXTERNED(bool, g_saveRawTranslationOuputToFileAtPrefabTime);
struct DependencyInfo
{
@@ -258,7 +260,7 @@ namespace ScriptCanvas
struct Request
{
AZ::Data::AssetId assetId;
AZ::Data::AssetId scriptAssetId;
const Graph* graph = nullptr;
AZStd::string_view name;
AZStd::string_view path;
@@ -291,7 +293,7 @@ namespace ScriptCanvas
Source() = default;
Source
( const Graph& graph
(const Graph& graph
, const AZ::Data::AssetId& id
, const GraphData& graphData
, const VariableData& variableData
@@ -305,8 +307,8 @@ namespace ScriptCanvas
AZStd::string ToTypeSafeEBusResultName(const Data::Type& type);
AZStd::string ToSafeName(const AZStd::string& name);
NamespacePath ToNamespacePath(AZStd::string_view path, AZStd::string_view name);
}
}
}
}
namespace AZStd
{
@@ -0,0 +1,101 @@
/*
* 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 <AzCore/Serialization/Json/JsonSerialization.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Serialization/ScriptUserDataSerializer.h>
using namespace ScriptCanvas;
namespace AZ
{
AZ_CLASS_ALLOCATOR_IMPL(ScriptUserDataSerializer, SystemAllocator, 0);
JsonSerializationResult::Result ScriptUserDataSerializer::Load
( void* outputValue
, [[maybe_unused]] const Uuid& outputValueTypeId
, const rapidjson::Value& inputValue
, JsonDeserializerContext& context)
{
namespace JSR = JsonSerializationResult;
AZ_Assert(outputValueTypeId == azrtti_typeid<RuntimeVariable>(), "ScriptUserDataSerializer Load against output typeID that was not RuntimeVariable");
AZ_Assert(outputValue, "ScriptUserDataSerializer Load against null output");
auto outputVariable = reinterpret_cast<RuntimeVariable*>(outputValue);
JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField);
AZ::Uuid typeId = AZ::Uuid::CreateNull();
auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier);
if (typeIdMember == inputValue.MemberEnd())
{
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Missing, AZStd::string::format("ScriptUserDataSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier));
}
result.Combine(LoadTypeId(typeId, typeIdMember->value, context));
if (typeId.IsNull())
{
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "ScriptUserDataSerializer::Load failed to load the AZ TypeId of the value");
}
outputVariable->value = context.GetSerializeContext()->CreateAny(typeId);
if (outputVariable->value.empty() || outputVariable->value.type() != typeId)
{
return context.Report(result, "ScriptUserDataSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed.");
}
result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast<void>(&outputVariable->value), typeId, inputValue, "value", context));
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
? "ScriptUserDataSerializer Load finished loading RuntimeVariable"
: "ScriptUserDataSerializer Load failed to load RuntimeVariable");
}
JsonSerializationResult::Result ScriptUserDataSerializer::Store
( rapidjson::Value& outputValue
, const void* inputValue
, const void* defaultValue
, [[maybe_unused]] const Uuid& valueTypeId
, JsonSerializerContext& context)
{
namespace JSR = JsonSerializationResult;
AZ_Assert(valueTypeId == azrtti_typeid<RuntimeVariable>(), "RuntimeVariable Store against value typeID that was not RuntimeVariable");
AZ_Assert(inputValue, "RuntimeVariable Store against null inputValue pointer ");
auto inputScriptDataPtr = reinterpret_cast<const RuntimeVariable*>(inputValue);
auto defaultScriptDataPtr = reinterpret_cast<const RuntimeVariable*>(defaultValue);
auto inputAnyPtr = &inputScriptDataPtr->value;
auto defaultAnyPtr = defaultScriptDataPtr ? &defaultScriptDataPtr->value : nullptr;
if (defaultAnyPtr)
{
ScriptCanvas::Datum inputDatum(ScriptCanvas::Data::FromAZType(inputAnyPtr->type()), ScriptCanvas::Datum::eOriginality::Copy, AZStd::any_cast<void>(inputAnyPtr), inputAnyPtr->type());
ScriptCanvas::Datum defaultDatum(ScriptCanvas::Data::FromAZType(defaultAnyPtr->type()), ScriptCanvas::Datum::eOriginality::Copy, AZStd::any_cast<void>(defaultAnyPtr), defaultAnyPtr->type());
if (inputDatum == defaultDatum)
{
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "ScriptUserDataSerializer Store used defaults for RuntimeVariable");
}
}
JSR::ResultCode result(JSR::Tasks::WriteValue);
outputValue.SetObject();
{
rapidjson::Value typeValue;
result.Combine(StoreTypeId(typeValue, inputAnyPtr->type(), context));
outputValue.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), AZStd::move(typeValue), context.GetJsonAllocator());
}
result.Combine(ContinueStoringToJsonObjectField(outputValue, "value", AZStd::any_cast<void>(inputAnyPtr), AZStd::any_cast<void>(defaultAnyPtr), inputAnyPtr->type(), context));
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
? "ScriptUserDataSerializer Store finished saving RuntimeVariable"
: "ScriptUserDataSerializer Store failed to save RuntimeVariable");
}
}
@@ -0,0 +1,36 @@
/*
* 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/Memory/Memory.h>
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
#include <AzCore/Serialization/SerializeContext.h>
namespace AZ
{
class ScriptUserDataSerializer
: public BaseJsonSerializer
{
public:
AZ_RTTI(ScriptUserDataSerializer, "{7E5FC193-8CDB-4251-A68B-F337027381DF}", BaseJsonSerializer);
AZ_CLASS_ALLOCATOR_DECL;
private:
JsonSerializationResult::Result Load
( void* outputValue
, const Uuid& outputValueTypeId
, const rapidjson::Value& inputValue
, JsonDeserializerContext& context) override;
JsonSerializationResult::Result Store
( rapidjson::Value& outputValue
, const void* inputValue
, const void* defaultValue
, const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -75,7 +75,7 @@ namespace ScriptCanvas
{
return m_model.GetSource().m_name;
}
AZStd::string_view GraphToX::GetFullPath() const
{
return m_model.GetSource().m_path;
@@ -120,7 +120,7 @@ namespace ScriptCanvas
resolution += Grammar::ToIdentifier(namespaces[index]);
}
}
return resolution;
}
@@ -128,13 +128,13 @@ namespace ScriptCanvas
{
writer.Write(m_configuration.m_singleLineComment);
}
void GraphToX::OpenBlockComment(Writer& writer)
{
writer.WriteIndent();
writer.WriteLine(m_configuration.m_blockCommentOpen);
}
void GraphToX::OpenFunctionBlock(Writer& writer)
{
writer.WriteLineIndented(m_configuration.m_functionBlockOpen);
@@ -162,7 +162,7 @@ namespace ScriptCanvas
void GraphToX::WriteCopyright(Writer& writer)
{
OpenBlockComment(writer);
writer.WriteLine(GetAmazonCopyright());
writer.WriteLine(GetCopyright());
CloseBlockComment(writer);
}
@@ -206,5 +206,5 @@ namespace ScriptCanvas
writer.Write("Last written: ");
writer.WriteLine(buffer);
}
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -30,7 +30,6 @@ namespace TranslationCPP
AZ::Outcome<AZStd::pair<AZStd::string, AZStd::string>, AZStd::pair<AZStd::string, AZStd::string>> ToCPlusPlus(const Grammar::AbstractCodeModel& model, bool rawSave = false)
{
AZStd::string dotH, dotCPP;
auto outcome = GraphToCPlusPlus::Translate(model, dotH, dotCPP);
if (outcome.IsSuccess())
{
@@ -48,13 +47,11 @@ namespace TranslationCPP
{
saveOutcome = SaveDotCPP(model.GetSource(), dotCPP);
}
if (!saveOutcome.IsSuccess())
{
AZ_TracePrintf("Save failed %s", saveOutcome.GetError().data());
}
}
return AZ::Success(AZStd::make_pair(AZStd::move(dotH), AZStd::move(dotCPP)));
}
else
@@ -96,16 +93,28 @@ namespace ScriptCanvas
{
namespace Translation
{
Result ParseGraph(const Grammar::Request& request)
AZ::Outcome<Grammar::AbstractCodeModelConstPtr, AZStd::string> ParseGraph(const Grammar::Request& request)
{
AZ::Outcome<Grammar::Source, AZStd::string> sourceOutcome = Grammar::Source::Construct(request);
if (!sourceOutcome.IsSuccess())
{
return Result(sourceOutcome.TakeError());
return AZ::Failure(sourceOutcome.TakeError());
}
Grammar::AbstractCodeModelConstPtr model = Grammar::AbstractCodeModel::Parse(sourceOutcome.TakeValue());
return AZ::Success(model);
}
Result ParseAndTranslateGraph(const Grammar::Request& request)
{
auto parseOutcome = ParseGraph(request);
if (!parseOutcome.IsSuccess())
{
return Result(parseOutcome.TakeError());
}
Grammar::AbstractCodeModelConstPtr model = parseOutcome.TakeValue();
Translations translations;
Errors errors;
@@ -124,61 +133,56 @@ namespace ScriptCanvas
}
}
// if (targetFlags & (TargetFlags::Cpp | TargetFlags::Hpp))
// {
// auto outcomeCPP = TranslationCPP::ToCPlusPlus(*model.get(), rawSave);
// if (outcomeCPP.IsSuccess())
// {
// auto hppAndCpp = outcomeCPP.TakeValue();
//
// TargetResult cppResult;
// cppResult.m_text = AZStd::move(hppAndCpp.first);
// translations.emplace(TargetFlags::Hpp, AZStd::move(cppResult));
// TargetResult hppResult;
// hppResult.m_text = AZStd::move(hppAndCpp.second);
// translations.emplace(TargetFlags::Cpp, AZStd::move(hppResult));
// }
// else
// {
// auto hppAndCpp = outcomeCPP.TakeError();
// errors.emplace(TargetFlags::Hpp, AZStd::move(hppAndCpp.first));
// errors.emplace(TargetFlags::Cpp, AZStd::move(hppAndCpp.second));
// }
// }
// Translation to C++ (executed via BehaviorContext calls) has been demonstrated in the past and is partially in progress.
// These calls allow for users to execute multiple translations from the same abstract code model.
// More work is required to complete all the latest features of the ACM, and do integrate output files into the build.
//
// if (targetFlags & (TargetFlags::Cpp | TargetFlags::Hpp))
// {
// auto outcomeCPP = TranslationCPP::ToCPlusPlus(*model.get(), rawSave);
// if (outcomeCPP.IsSuccess())
// {
// auto hppAndCpp = outcomeCPP.TakeValue();
//
// TargetResult cppResult;
// cppResult.m_text = AZStd::move(hppAndCpp.first);
// translations.emplace(TargetFlags::Hpp, AZStd::move(cppResult));
// TargetResult hppResult;
// hppResult.m_text = AZStd::move(hppAndCpp.second);
// translations.emplace(TargetFlags::Cpp, AZStd::move(hppResult));
// }
// else
// {
// auto hppAndCpp = outcomeCPP.TakeError();
// errors.emplace(TargetFlags::Hpp, AZStd::move(hppAndCpp.first));
// errors.emplace(TargetFlags::Cpp, AZStd::move(hppAndCpp.second));
// }
// }
}
else
{
ValidationResults results;
for (auto& test : model->GetValidationEvents())
{
results.AddValidationEvent(test.get());
}
}
return Result(model, AZStd::move(translations), AZStd::move(errors));
}
}
Result ToCPlusPlusAndLua(const Grammar::Request& request)
{
Grammar::Request toBoth = request;
toBoth.translationTargetFlags = TargetFlags::Lua | TargetFlags::Cpp;
return ParseGraph(toBoth);
return ParseAndTranslateGraph(toBoth);
}
Result ToCPlusPlus(const Grammar::Request& request)
{
Grammar::Request toCpp = request;
toCpp.translationTargetFlags = TargetFlags::Cpp;
return ParseGraph(toCpp);
return ParseAndTranslateGraph(toCpp);
}
Result ToLua(const Grammar::Request& request)
{
Grammar::Request toLua = request;
toLua.translationTargetFlags = TargetFlags::Lua;
return ParseGraph(toLua);
return ParseAndTranslateGraph(toLua);
}
}
}
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -18,14 +18,15 @@ namespace ScriptCanvas
namespace Translation
{
Result ParseGraph(const Grammar::Request& request);
AZ::Outcome<Grammar::AbstractCodeModelConstPtr, AZStd::string> ParseGraph(const Grammar::Request& request);
Result ParseAndTranslateGraph(const Grammar::Request& request);
Result ToCPlusPlus(const Grammar::Request& request);
Result ToCPlusPlusAndLua(const Grammar::Request& request);
Result ToLua(const Grammar::Request& request);
}
}
Result ToLua(const Grammar::Request& request);
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -41,7 +41,7 @@ namespace ScriptCanvas
Cpp = 1 << 1,
Hpp = 1 << 2,
};
// information required at runtime begin execution of the compiled graph from the host
struct RuntimeInputs
{
@@ -51,10 +51,13 @@ namespace ScriptCanvas
static void Reflect(AZ::ReflectContext* reflectContext);
Grammar::ExecutionStateSelection m_executionSelection = Grammar::ExecutionStateSelection::InterpretedPure;
AZStd::vector<Nodeable*> m_nodeables;
AZStd::vector<AZStd::pair<VariableId, Datum>> m_variables;
// either the entityId was a (member) variable in the source graph, or it got promoted to one during parsing
AZStd::vector<AZStd::pair<VariableId, Data::EntityIDType>> m_entityIds;
// Statics required for internal, local values that need non-code constructible initialization,
// when the system can't pass in the input from C++.
AZStd::vector<AZStd::pair<VariableId, AZStd::any>> m_staticVariables;
@@ -84,7 +87,7 @@ namespace ScriptCanvas
using ErrorList = AZStd::vector<AZStd::string>;
using Errors = AZStd::unordered_map<TargetFlags, ErrorList>;
using Translations = AZStd::unordered_map<TargetFlags, TargetResult>;
AZStd::sys_time_t SumDurations(const Translations& translation);
class Result
@@ -98,6 +101,7 @@ namespace ScriptCanvas
const AZStd::sys_time_t m_translationDuration;
Result(AZStd::string invalidSourceInfo);
Result(Result&& source);
Result(Grammar::AbstractCodeModelConstPtr model);
Result(Grammar::AbstractCodeModelConstPtr model, Translations&& translations, Errors&& errors);
@@ -107,7 +111,7 @@ namespace ScriptCanvas
AZ::Outcome<void, AZStd::string> IsSuccess(TargetFlags flag) const;
bool TranslationSucceed(TargetFlags flag) const;
};
struct LuaAssetResult
{
AZ::Data::Asset<AZ::ScriptAsset> m_scriptAsset;
@@ -117,7 +121,5 @@ namespace ScriptCanvas
AZStd::sys_time_t m_parseDuration;
AZStd::sys_time_t m_translationDuration;
};
}
}
}
}
@@ -166,7 +166,7 @@ namespace ScriptCanvas
return TranslationUtilitiesCPP::k_namespaceNameNative;
}
AZStd::string_view GetAmazonCopyright()
AZStd::string_view GetCopyright()
{
return
"* 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.\n"
@@ -34,7 +34,7 @@ namespace ScriptCanvas
AZStd::string EntityIdValueToString(const AZ::EntityId& entityId, const Configuration& config);
AZStd::string_view GetAmazonCopyright();
AZStd::string_view GetCopyright();
AZStd::string_view GetAutoNativeNamespace();
@@ -1,6 +1,6 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
@@ -102,44 +102,44 @@ namespace ScriptCanvas
classElement.RemoveElementByName(AZ_CRC_CE("Scope"));
classElement.AddElementWithData<VariableFlags::InitialValueSource>(context, "InitialValueSource", VariableFlags::InitialValueSource::Component);
}
classElement.RemoveElementByName(AZ_CRC("ExposeAsInput", 0x0f7879f0));
classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd));
}
else
if (classElement.GetVersion() < 3)
{
bool exposeAsInputField = false;
classElement.GetChildData<bool>(AZ_CRC("ExposeAsInput", 0x0f7879f0), exposeAsInputField);
if (exposeAsInputField)
if (classElement.GetVersion() < 3)
{
bool exposeAsInputField = false;
classElement.GetChildData<bool>(AZ_CRC("ExposeAsInput", 0x0f7879f0), exposeAsInputField);
if (exposeAsInputField)
{
classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd));
classElement.AddElementWithData<VariableFlags::Scope>(context, "Scope", VariableFlags::Scope::Graph);
}
else
{
AZ::u8 exposureType = VariableFlags::Deprecated::Exposure::Exp_Local;
classElement.GetChildData<AZ::u8>(AZ_CRC("Exposure", 0x398f29cd), exposureType);
VariableFlags::Scope scope = VariableFlags::Scope::Graph;
if (((exposureType & VariableFlags::Deprecated::Exposure::Exp_InOut) == VariableFlags::Deprecated::Exposure::Exp_InOut)
|| exposureType & VariableFlags::Deprecated::Exposure::Exp_Input)
{
scope = VariableFlags::Scope::Graph;
}
else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Output)
{
scope = VariableFlags::Scope::Function;
}
classElement.AddElementWithData<VariableFlags::Scope>(context, "Scope", scope);
}
classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd));
classElement.AddElementWithData<VariableFlags::Scope>(context, "Scope", VariableFlags::Scope::Graph);
classElement.RemoveElementByName(AZ_CRC("ExposeAsInput", 0x0f7879f0));
}
else
{
AZ::u8 exposureType = VariableFlags::Deprecated::Exposure::Exp_Local;
classElement.GetChildData<AZ::u8>(AZ_CRC("Exposure", 0x398f29cd), exposureType);
VariableFlags::Scope scope = VariableFlags::Scope::Graph;
if ((exposureType & VariableFlags::Deprecated::Exposure::Exp_InOut) == VariableFlags::Deprecated::Exposure::Exp_InOut)
{
scope = VariableFlags::Scope::Graph;
}
else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Input)
{
scope = VariableFlags::Scope::Graph;
}
else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Output)
{
scope = VariableFlags::Scope::Function;
}
classElement.AddElementWithData<VariableFlags::Scope>(context, "Scope", scope);
}
classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd));
classElement.RemoveElementByName(AZ_CRC("ExposeAsInput", 0x0f7879f0));
}
return true;
}
@@ -203,8 +203,8 @@ namespace ScriptCanvas
editContext->Class<GraphVariable>("Variable", "Represents a Variable field within a Script Canvas Graph")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, &GraphVariable::GetVisibility)
->Attribute(AZ::Edit::Attributes::ChildNameLabelOverride, &GraphVariable::GetDisplayName)
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &GraphVariable::GetDisplayName)
->Attribute(AZ::Edit::Attributes::ChildNameLabelOverride, &GraphVariable::GetVariableName)
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &GraphVariable::GetVariableName)
->Attribute(AZ::Edit::Attributes::DescriptionTextOverride, &GraphVariable::GetDescriptionOverride)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &GraphVariable::m_InitialValueSource, "Initial Value Source", "Variables can get their values from within the graph or through component properties.")