Merge pull request #1657 from aws-lumberyard-dev/carlitosan/scriptcanvas/prefabs

Initial prefab integration
main
Sandeep 5 years ago committed by GitHub
commit 4c684b1a10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -58,8 +58,11 @@ class TestFileMenuDefaultNewOpen:
sc_main = sc.findChild(QtWidgets.QMainWindow)
sc_tabs = sc_main.findChild(QtWidgets.QTabWidget, "ScriptCanvasTabs")
# 3) Trigger File->New action
# wait for the intial tab count
general.idle_wait(GENERAL_WAIT)
initial_tabs_count = sc_tabs.count()
# 3) Trigger File->New action
action = pyside_utils.find_child_by_pattern(
sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction}
)

@ -689,6 +689,81 @@ namespace AZ
return 1;
}
int Class__IndexAllowNil(lua_State* l)
{
LSV_BEGIN(l, 1);
// calling format __index(table,key)
lua_getmetatable(l, -2); // load the userdata metatable
int metaTableIndex = lua_gettop(l);
// Check if the key is string, if so we expect it to be a function or property name
// otherwise we allow users to provide custom index handlers
// Technically we can allow strings too, but it will clash with function/property names and it be hard to figure
// out what is going on from with in the system.
if (lua_type(l, -2) == LUA_TSTRING)
{
lua_pushvalue(l, -2); // duplicate the key
lua_rawget(l, -2); // load the value at this index
}
else
{
lua_pushliteral(l, "__AZ_Index");
lua_rawget(l, -2); // check if the user provided custom Index method in the class metatable
if (lua_isnil(l, -1)) // if not report an error
{
lua_rawgeti(l, -2, AZ_LUA_CLASS_METATABLE_NAME_INDEX); // load the class name for a better error
if (!lua_isstring(l, -1)) // if we failed it means we are the base metatable
{
lua_pop(l, 1);
lua_rawgeti(l, 1, AZ_LUA_CLASS_METATABLE_NAME_INDEX);
}
ScriptContext::FromNativeContext(l)->Error(ScriptContext::ErrorType::Warning, true, "Invalid index type [], should be string! '%s:%s'!", lua_tostring(l, -1), lua_tostring(l, -4));
}
else
{
// if we have custom index handler
lua_pushvalue(l, -4); // duplicate the table (class pointer)
lua_pushvalue(l, -4); // duplicate the index value for the call
lua_call(l, 2, 1); // call the function
}
lua_remove(l, metaTableIndex); // remove the metatable
return 1;
}
if (!lua_isnil(l, -1))
{
if (lua_tocfunction(l, -1) == &Internal::LuaPropertyTagHelper) // if it's a property
{
lua_getupvalue(l, -1, 1); // push on the stack the getter function
lua_remove(l, -2); // remove property object
if (lua_isnil(l, -1))
{
lua_rawgeti(l, -2, AZ_LUA_CLASS_METATABLE_NAME_INDEX); // load the class name for a better error
if (!lua_isstring(l, -1)) // if we failed it means we are the base metatable
{
lua_pop(l, 1);
lua_rawgeti(l, 1, AZ_LUA_CLASS_METATABLE_NAME_INDEX);
}
ScriptContext::FromNativeContext(l)->Error(ScriptContext::ErrorType::Warning, true, "Property '%s:%s' is write only", lua_tostring(l, -1), lua_tostring(l, -4));
lua_pop(l, 1); // pop class name
}
else
{
lua_pushvalue(l, -4); // copy the user data to be passed as a this pointer.
lua_call(l, 1, 1); // call a function with one argument (this pointer) and 1 result
}
}
}
lua_remove(l, metaTableIndex); // remove the metatable
return 1;
}
//=========================================================================
// Class__NewIndex
// [3/22/2012]
@ -826,30 +901,6 @@ namespace AZ
return 1;
}
//=========================================================================
// ClassMetatable__Index
// [3/24/2012]
//=========================================================================
int ClassMetatable__Index(lua_State* l)
{
// since the Class__Index is generic function (ask for the class metatable)
// we can reuse the code for the base metatable (which is a metatable
// of the class metatable)
return Class__Index(l);
}
//=========================================================================
// ClassMetatable__NewIndex
// [3/30/2012]
//=========================================================================
int ClassMetatable__NewIndex(lua_State* l)
{
// since the Class__NewIndex is generic function (ask for the class metatable)
// we can reuse the code for the base metatable (which is a metatable
// of the class metatable)
return Class__NewIndex(l);
}
inline size_t BufferStringCopy(const char* source, char* destination, size_t destinationSize)
{
size_t srcLen = strlen(source);
@ -5053,9 +5104,20 @@ LUA_API const Node* lua_getDummyNode()
lua_pushcclosure(m_lua, &DefaultBehaviorCaller::Destroy, 0);
lua_rawset(m_lua, -3);
lua_pushliteral(m_lua, "__index");
lua_pushcclosure(m_lua, &Internal::Class__Index, 0);
lua_rawset(m_lua, -3);
{
lua_pushliteral(m_lua, "__index");
if (FindAttribute(Script::Attributes::UseClassIndexAllowNil, behaviorClass->m_attributes))
{
lua_pushcclosure(m_lua, &Internal::Class__IndexAllowNil, 0);
}
else
{
lua_pushcclosure(m_lua, &Internal::Class__Index, 0);
}
lua_rawset(m_lua, -3);
}
lua_pushliteral(m_lua, "__newindex");
lua_pushcclosure(m_lua, &Internal::Class__NewIndex, 0);

@ -16,19 +16,20 @@ namespace AZ
{
namespace Attributes
{
const static AZ::Crc32 Ignore = AZ_CRC("ScriptIgnore", 0xeb7615e1); ///< Don't use the element in the script reflection
const static AZ::Crc32 ClassNameOverride = AZ_CRC("ScriptClassNameOverride", 0x891238a3); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name
const static AZ::Crc32 MethodOverride = AZ_CRC("ScriptFunctionOverride", 0xf89a7882); ///< Use a custom function in the attribute instead of the function
const static AZ::Crc32 ConstructorOverride = AZ_CRC("ConstructorOverride", 0xef5ce4aa); ///< You can provide a custom constructor to be called when created from Lua script
const static AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals
const static AZ::Crc32 GenericConstructorOverride = AZ_CRC("GenericConstructorOverride", 0xe6a1698e); ///< You can provide a custom constructor to be called when creating a script
const static AZ::Crc32 ReaderWriterOverride = AZ_CRC("ReaderWriterOverride", 0x1ad9ce2a); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM
const static AZ::Crc32 ConstructibleFromNil = AZ_CRC("ConstructibleFromNil", 0x23908169); ///< Applied to classes. Value (bool) specifies if the class be default constructed when nil is provided.
const static AZ::Crc32 ToolTip = AZ_CRC("ToolTip", 0xa1b95fb0); ///< Add a tooltip for a method/event/property
const static AZ::Crc32 Category = AZ_CRC("Category", 0x064c19c1); ///< Provide a category to allow for partitioning/sorting/ordering of the element
const static AZ::Crc32 Deprecated = AZ_CRC("Deprecated", 0xfe49a138); ///< Marks a reflected class, method, EBus or property as deprecated.
const static AZ::Crc32 DisallowBroadcast = AZ_CRC("DisallowBroadcast", 0x389b0ac7); ///< Marks a reflected EBus as not allowing Broadcasts, only Events.
const static AZ::Crc32 ClassConstantValue = AZ_CRC_CE("ClassConstantValue"); ///< Indicates the property is backed by a constant value
static constexpr AZ::Crc32 Ignore = AZ_CRC_CE("ScriptIgnore"); ///< Don't use the element in the script reflection
static constexpr AZ::Crc32 ClassNameOverride = AZ_CRC_CE("ScriptClassNameOverride"); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name
static constexpr AZ::Crc32 MethodOverride = AZ_CRC_CE("ScriptFunctionOverride"); ///< Use a custom function in the attribute instead of the function
static constexpr AZ::Crc32 ConstructorOverride = AZ_CRC_CE("ConstructorOverride"); ///< You can provide a custom constructor to be called when created from Lua script
static constexpr AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals
static constexpr AZ::Crc32 GenericConstructorOverride = AZ_CRC_CE("GenericConstructorOverride"); ///< You can provide a custom constructor to be called when creating a script
static constexpr AZ::Crc32 ReaderWriterOverride = AZ_CRC_CE("ReaderWriterOverride"); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM
static constexpr AZ::Crc32 ConstructibleFromNil = AZ_CRC_CE("ConstructibleFromNil"); ///< Applied to classes. Value (bool) specifies if the class be default constructed when nil is provided.
static constexpr AZ::Crc32 ToolTip = AZ_CRC_CE("ToolTip"); ///< Add a tooltip for a method/event/property
static constexpr AZ::Crc32 Category = AZ_CRC_CE("Category"); ///< Provide a category to allow for partitioning/sorting/ordering of the element
static constexpr AZ::Crc32 Deprecated = AZ_CRC_CE("Deprecated"); ///< Marks a reflected class, method, EBus or property as deprecated.
static constexpr AZ::Crc32 DisallowBroadcast = AZ_CRC_CE("DisallowBroadcast"); ///< Marks a reflected EBus as not allowing Broadcasts, only Events.
static constexpr AZ::Crc32 ClassConstantValue = AZ_CRC_CE("ClassConstantValue"); ///< Indicates the property is backed by a constant value
static constexpr AZ::Crc32 UseClassIndexAllowNil = AZ_CRC_CE("UseClassIndexAllowNil"); ///< Use the Class__IndexAllowNil method, which will not report an error on accessing undeclared values (allows for nil)
//! Attribute which stores BehaviorAzEventDescription structure which contains
//! the script name of an AZ::Event and the name of it's parameter arguments
@ -39,11 +40,11 @@ namespace AZ
static constexpr AZ::Crc32 EventParameterTypes = AZ_CRC_CE("EventParameterTypes");
///< Recommends that the Lua runtime look up the member function in the meta table of the first argument, rather than in the original table
const static AZ::Crc32 TreatAsMemberFunction = AZ_CRC("TreatAsMemberFunction", 0x64be831a);
static constexpr AZ::Crc32 TreatAsMemberFunction = AZ_CRC_CE("TreatAsMemberFunction");
///< This attribute can be attached to the EditContext Attribute of a reflected class, the BehaviorContext Attribute of a reflected class, method, ebus or property.
///< ExcludeFlags can be used to prevent elements from appearing in List, Documentation, etc...
const static AZ::Crc32 ExcludeFrom = AZ_CRC("ExcludeFrom", 0xa98972fe);
static constexpr AZ::Crc32 ExcludeFrom = AZ_CRC_CE("ExcludeFrom");
enum ExcludeFlags : AZ::u64
{
List = 1 << 0, //< The reflected item will be excluded from any list (e.g. node palette)
@ -54,7 +55,7 @@ namespace AZ
};
//! Used to specify the usage of a Behavior Context element (e.g. Class or EBus) designed for automation scripts
const static AZ::Crc32 Scope = AZ_CRC("Scope", 0x00af55d3);
static constexpr AZ::Crc32 Scope = AZ_CRC_CE("Scope");
enum class ScopeFlags : AZ::u64
{
Launcher = 1 << 0, //< a type meant for game run-time Launcher client (default value)
@ -63,15 +64,15 @@ namespace AZ
};
//! Provide a partition hierarchy in a string dotted notation to namespace a script element
const static AZ::Crc32 Module = AZ_CRC("Module", 0x0c242628);
static constexpr AZ::Crc32 Module = AZ_CRC_CE("Module");
//! Provide an alternate name for script elements such as helpful PEP8 Python methods and property aliases
const static AZ::Crc32 Alias = AZ_CRC("Alias", 0xe16c6b94);
static constexpr AZ::Crc32 Alias = AZ_CRC_CE("Alias");
const static AZ::Crc32 EnableAsScriptEventParamType = AZ_CRC("ScriptEventParam", 0xa41e4cb0);
const static AZ::Crc32 EnableAsScriptEventReturnType = AZ_CRC("ScriptEventReturn", 0xf89b5337);
static constexpr AZ::Crc32 EnableAsScriptEventParamType = AZ_CRC_CE("ScriptEventParam");
static constexpr AZ::Crc32 EnableAsScriptEventReturnType = AZ_CRC_CE("ScriptEventReturn");
const static AZ::Crc32 Storage = AZ_CRC("ScriptStorage", 0xcd95b44d);
static constexpr AZ::Crc32 Storage = AZ_CRC_CE("ScriptStorage");
enum class StorageType
{
ScriptOwn, // default, Host allocated memory, Lua will destruct object, Lua will free host-memory via host-supplied function
@ -79,7 +80,7 @@ namespace AZ
Value, // Object is Lua allocated memory, Lua will destruct object, Lua will free Lua-memory
};
const static AZ::Crc32 Operator = AZ_CRC("ScriptOperator", 0xfee681b6);
static constexpr AZ::Crc32 Operator = AZ_CRC_CE("ScriptOperator");
enum class OperatorType
{
// note storage policy can be T*,T (only if we store raw pointers), shared_ptr<T>, intrusive pointer<T>
@ -100,7 +101,7 @@ namespace AZ
IndexWrite, // given a key/index and a value, you can store it in the class
};
const static AZ::Crc32 AssetType = AZ_CRC("AssetType", 0xabbf8d5f); ///< Provide an asset type for a generic AssetId method
static constexpr AZ::Crc32 AssetType = AZ_CRC_CE("AssetType"); ///< Provide an asset type for a generic AssetId method
} // Attributes
} // Script

@ -24,7 +24,6 @@ namespace AZ
//=========================================================================
AZStd::string ExtractUserMessage(const ScriptDataContext& dc)
{
AZStd::string userMessage = "Condition failed";
const int argCount = dc.GetNumArguments();
if (argCount > 0 && dc.IsString(argCount - 1))
{
@ -33,12 +32,12 @@ namespace AZ
{
if (value)
{
userMessage = value;
return value;
}
}
}
return userMessage;
return "ExtractUserMessage from print/Debug.Log/Warn/Error/Assert failed. Consider wrapping your argument in tostring().";
}
//=========================================================================

@ -19,7 +19,7 @@
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <LyViewPaneNames.h>
// Undo this
// Undo this
AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
@ -90,8 +90,8 @@ namespace ScriptCanvasEditor
void EditorAssetSystemComponent::Deactivate()
{
ScriptCanvas::Translation::RequestBus::Handler::BusDisconnect();
ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect();
ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect();
EditorAssetConversionBus::Handler::BusDisconnect();
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect();
m_editorAssetRegistry.Unregister();
@ -119,8 +119,8 @@ namespace ScriptCanvasEditor
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> EditorAssetSystemComponent::LoadAsset(AZStd::string_view graphPath)
{
auto outcome = ScriptCanvasBuilder::LoadEditorAsset(graphPath);
auto outcome = ScriptCanvasBuilder::LoadEditorAsset(graphPath, AZ::Data::AssetId(AZ::Uuid::CreateRandom()));
if (outcome.IsSuccess())
{
return outcome.GetValue();

@ -21,8 +21,10 @@ namespace ScriptCanvas
void RuntimeAssetSystemComponent::Reflect(AZ::ReflectContext* context)
{
ScriptCanvas::RuntimeData::Reflect(context);
ScriptCanvas::SubgraphInterfaceData::Reflect(context);
RuntimeData::Reflect(context);
RuntimeDataOverrides::Reflect(context);
SubgraphInterfaceData::Reflect(context);
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<RuntimeAssetSystemComponent, AZ::Component>()

@ -0,0 +1,376 @@
/*
* 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 <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <Builder/ScriptCanvasBuilder.h>
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Grammar/AbstractCodeModel.h>
namespace ScriptCanvasBuilderCpp
{
void AppendTabs(AZStd::string& result, size_t depth)
{
for (size_t i = 0; i < depth; ++i)
{
result += "\t";
}
}
}
namespace ScriptCanvasBuilder
{
void BuildVariableOverrides::Clear()
{
m_source.Reset();
m_variables.clear();
m_entityIds.clear();
m_dependencies.clear();
}
void BuildVariableOverrides::CopyPreviousOverriddenValues(const BuildVariableOverrides& source)
{
for (auto& overriddenValue : m_overrides)
{
auto iter = AZStd::find_if(source.m_overrides.begin(), source.m_overrides.end(), [&overriddenValue](const auto& candidate) { return candidate.GetVariableId() == overriddenValue.GetVariableId(); });
if (iter != source.m_overrides.end())
{
overriddenValue.DeepCopy(*iter);
overriddenValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide);
overriddenValue.SetAllowSignalOnChange(false);
// check that a name update is not necessary anymore
}
}
//////////////////////////////////////////////////////////////////////////
// #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one.
// the above will provide the data to handle the cases where only certain dependency nodes were removed
// until then we do a sanity check, if any part of the depenecies were altered, assume no overrides are valid.
if (m_dependencies.size() != source.m_dependencies.size())
{
return;
}
else
{
for (size_t index = 0; index != m_dependencies.size(); ++index)
{
if (m_dependencies[index].m_source != source.m_dependencies[index].m_source)
{
return;
}
}
}
//////////////////////////////////////////////////////////////////////////
for (size_t index = 0; index != m_dependencies.size(); ++index)
{
m_dependencies[index].CopyPreviousOverriddenValues(source.m_dependencies[index]);
}
}
bool BuildVariableOverrides::IsEmpty() const
{
return m_variables.empty() && m_entityIds.empty() && m_dependencies.empty();
}
void BuildVariableOverrides::Reflect(AZ::ReflectContext* reflectContext)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<BuildVariableOverrides>()
->Version(0)
->Field("source", &BuildVariableOverrides::m_source)
->Field("variables", &BuildVariableOverrides::m_variables)
->Field("entityId", &BuildVariableOverrides::m_entityIds)
->Field("overrides", &BuildVariableOverrides::m_overrides)
->Field("dependencies", &BuildVariableOverrides::m_dependencies)
;
if (auto editContext = serializeContext->GetEditContext())
{
editContext->Class< BuildVariableOverrides>("Variables", "Variables exposed by the attached Script Canvas Graph")
->ClassElement(AZ::Edit::ClassElements::Group, "Variable Fields")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &BuildVariableOverrides::m_overrides, "Variables", "Array of Variables within Script Canvas Graph")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &BuildVariableOverrides::m_dependencies, "Dependencies", "Variables in Dependencies of the Script Canvas Graph")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
;
}
}
}
// use this to initialize the new data, and make sure they have a editor graph variable for proper editor display
void BuildVariableOverrides::PopulateFromParsedResults(const ScriptCanvas::Grammar::ParsedRuntimeInputs& inputs, const ScriptCanvas::VariableData& variables)
{
for (auto& variable : inputs.m_variables)
{
auto graphVariable = variables.FindVariable(variable.first);
if (!graphVariable)
{
AZ_Error("ScriptCanvasBuilder", false, "Missing Variable from graph data that was just parsed");
continue;
}
m_variables.push_back(*graphVariable);
auto& buildVariable = m_variables.back();
buildVariable.DeepCopy(*graphVariable); // in case of BCO, a new one needs to be created
// copy to override list for editor display
m_overrides.push_back(*graphVariable);
auto& overrideValue = m_overrides.back();
overrideValue.DeepCopy(*graphVariable);
overrideValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide);
overrideValue.SetAllowSignalOnChange(false);
}
for (auto& entityId : inputs.m_entityIds)
{
m_entityIds.push_back(entityId);
if (!ScriptCanvas::Grammar::IsParserGeneratedId(entityId.first))
{
auto graphEntityId = variables.FindVariable(entityId.first);
if (!graphEntityId)
{
AZ_Error("ScriptCanvasBuilder", false, "Missing EntityId from graph data that was just parsed");
continue;
}
// copy to override list for editor display
if (graphEntityId->IsComponentProperty())
{
m_overrides.push_back(*graphEntityId);
auto& overrideValue = m_overrides.back();
overrideValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide);
overrideValue.SetAllowSignalOnChange(false);
}
}
}
}
EditorAssetTree* EditorAssetTree::ModRoot()
{
if (!m_parent)
{
return this;
}
return m_parent->ModRoot();
}
void EditorAssetTree::SetParent(EditorAssetTree& parent)
{
m_parent = &parent;
}
AZStd::string EditorAssetTree::ToString(size_t depth) const
{
AZStd::string result;
ScriptCanvasBuilderCpp::AppendTabs(result, depth);
result += m_asset.GetId().ToString<AZStd::string>();
result += m_asset.GetHint();
depth += m_dependencies.empty() ? 0 : 1;
for (const auto& dependency : m_dependencies)
{
result += "\n";
ScriptCanvasBuilderCpp::AppendTabs(result, depth);
result += dependency.ToString(depth);
}
return result;
}
ScriptCanvas::RuntimeDataOverrides ConvertToRuntime(const BuildVariableOverrides& buildOverrides)
{
ScriptCanvas::RuntimeDataOverrides runtimeOverrides;
runtimeOverrides.m_runtimeAsset = AZ::Data::Asset<ScriptCanvas::RuntimeAsset>
(AZ::Data::AssetId(buildOverrides.m_source.GetId().m_guid, AZ_CRC("RuntimeData", 0x163310ae)), azrtti_typeid<ScriptCanvas::RuntimeAsset>(), {});
runtimeOverrides.m_runtimeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad);
runtimeOverrides.m_variableIndices.resize(buildOverrides.m_variables.size());
for (size_t index = 0; index != buildOverrides.m_variables.size(); ++index)
{
auto& variable = buildOverrides.m_variables[index];
auto iter = AZStd::find_if
( buildOverrides.m_overrides.begin()
, buildOverrides.m_overrides.end()
, [&variable](auto& candidate) { return candidate.GetVariableId() == variable.GetVariableId(); });
if (iter != buildOverrides.m_overrides.end())
{
if (iter->GetDatum())
{
runtimeOverrides.m_variables.push_back(ScriptCanvas::RuntimeVariable(iter->GetDatum()->ToAny()));
runtimeOverrides.m_variableIndices[index] = true;
}
else
{
AZ_Warning("ScriptCanvasBuilder", false, "build overrides missing variable override, Script may not function properly");
runtimeOverrides.m_variableIndices[index] = false;
}
}
else
{
runtimeOverrides.m_variableIndices[index] = false;
}
}
for (auto& entity : buildOverrides.m_entityIds)
{
auto& variableId = entity.first;
auto iter = AZStd::find_if(buildOverrides.m_overrides.begin(), buildOverrides.m_overrides.end(), [&variableId](auto& candidate) { return candidate.GetVariableId() == variableId; });
if (iter != buildOverrides.m_overrides.end())
{
// the entity was overridden on the instance
if (iter->GetDatum() && iter->GetDatum()->GetAs<AZ::EntityId>())
{
runtimeOverrides.m_entityIds.push_back(*iter->GetDatum()->GetAs<AZ::EntityId>());
}
else
{
AZ_Warning("ScriptCanvasBuilder", false, "build overrides missing EntityId, Script may not function properly");
runtimeOverrides.m_entityIds.push_back(AZ::EntityId{});
}
}
else
{
// the entity is overridden, as part of the required process of to instantiation
runtimeOverrides.m_entityIds.push_back(entity.second);
}
}
for (auto& buildDependency : buildOverrides.m_dependencies)
{
runtimeOverrides.m_dependencies.push_back(ConvertToRuntime(buildDependency));
}
return runtimeOverrides;
}
AZ::Outcome<EditorAssetTree, AZStd::string> LoadEditorAssetTree(AZ::Data::AssetId editorAssetId, AZStd::string_view assetHint, EditorAssetTree* parent)
{
EditorAssetTree result;
AZ::Data::AssetInfo assetInfo;
AZStd::string watchFolder;
bool resultFound = false;
if (!AzToolsFramework::AssetSystemRequestBus::FindFirstHandler())
{
return AZ::Failure(AZStd::string("LoadEditorAssetTree found no handler for AzToolsFramework::AssetSystemRequestBus."));
}
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
( resultFound
, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourceUUID
, editorAssetId.m_guid
, assetInfo
, watchFolder);
if (!resultFound)
{
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to get engine relative path from %s-%.*s.", editorAssetId.ToString<AZStd::string>().c_str(), aznumeric_cast<int>(assetHint.size()), assetHint.data()));
}
AZStd::vector<AZ::Data::AssetId> dependentAssets;
auto filterCB = [&dependentAssets](const AZ::Data::AssetFilterInfo& filterInfo)->bool
{
if (filterInfo.m_assetType == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
{
dependentAssets.push_back(AZ::Data::AssetId(filterInfo.m_assetId.m_guid, 0));
}
else if (filterInfo.m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>())
{
dependentAssets.push_back(filterInfo.m_assetId);
}
return true;
};
auto loadAssetOutcome = ScriptCanvasBuilder::LoadEditorAsset(assetInfo.m_relativePath, editorAssetId, filterCB);
if (!loadAssetOutcome.IsSuccess())
{
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to load graph from %s-%s: %s", editorAssetId.ToString<AZStd::string>().c_str(), assetHint.data(), loadAssetOutcome.GetError().c_str()));
}
for (auto& dependentAsset : dependentAssets)
{
auto loadDependentOutcome = LoadEditorAssetTree(dependentAsset, "", &result);
if (!loadDependentOutcome.IsSuccess())
{
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to load dependent graph from %s-%s: %s", editorAssetId.ToString<AZStd::string>().c_str(), assetHint.data(), loadDependentOutcome.GetError().c_str()));
}
result.m_dependencies.push_back(loadDependentOutcome.TakeValue());
}
if (parent)
{
result.SetParent(*parent);
}
result.m_asset = loadAssetOutcome.TakeValue();
return AZ::Success(result);
}
AZ::Outcome<BuildVariableOverrides, AZStd::string> ParseEditorAssetTree(const EditorAssetTree& editorAssetTree)
{
auto buildEntity = editorAssetTree.m_asset->GetScriptCanvasEntity();
if (!buildEntity)
{
return AZ::Failure(AZStd::string("No entity from source asset"));
}
auto variableComponent = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::GraphVariableManagerComponent>(buildEntity);
if (!variableComponent)
{
return AZ::Failure(AZStd::string("No GraphVariableManagerComponent in source Entity"));
}
const ScriptCanvas::VariableData* variableData = variableComponent->GetVariableDataConst(); // get this from the entity
if (!variableData)
{
return AZ::Failure(AZStd::string("No variableData in source GraphVariableManagerComponent"));
}
auto parseOutcome = ScriptCanvasBuilder::ParseGraph(*buildEntity, "");
if (!parseOutcome.IsSuccess() || !parseOutcome.GetValue())
{
return AZ::Failure(AZStd::string("graph failed to parse"));
}
BuildVariableOverrides result;
result.m_source = editorAssetTree.m_asset;
result.PopulateFromParsedResults(parseOutcome.GetValue()->GetRuntimeInputs(), *variableData);
// recurse...
for (auto& dependentAsset : editorAssetTree.m_dependencies)
{
// #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one.
auto parseDependentOutcome = ParseEditorAssetTree(dependentAsset);
if (!parseDependentOutcome.IsSuccess())
{
return AZ::Failure(AZStd::string::format
("ParseEditorAssetTree failed to parse dependent graph from %s-%s: %s"
, dependentAsset.m_asset.GetId().ToString<AZStd::string>().c_str()
, dependentAsset.m_asset.GetHint().c_str()
, parseDependentOutcome.GetError().c_str()));
}
result.m_dependencies.push_back(parseDependentOutcome.TakeValue());
}
return AZ::Success(result);
}
}

@ -0,0 +1,82 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Asset/AssetCommon.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Variable/VariableCore.h>
namespace ScriptCanvas
{
namespace Grammar
{
struct ParsedRuntimeInputs;
}
}
namespace ScriptCanvasEditor
{
class ScriptCanvasAsset;
}
namespace ScriptCanvasBuilder
{
class BuildVariableOverrides
{
public:
AZ_TYPE_INFO(BuildVariableOverrides, "{8336D44C-8EDC-4C28-AEB4-3420D5FD5AE2}");
AZ_CLASS_ALLOCATOR(BuildVariableOverrides, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext);
void Clear();
// use this to preserve old values that may have been overridden on the instance, and are still valid in the parsed graph
void CopyPreviousOverriddenValues(const BuildVariableOverrides& source);
bool IsEmpty() const;
// use this to initialize the new data, and make sure they have a editor graph variable for proper editor display
void PopulateFromParsedResults(const ScriptCanvas::Grammar::ParsedRuntimeInputs& inputs, const ScriptCanvas::VariableData& variables);
// #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one.
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> m_source;
// all of the variables here are overrides
AZStd::vector<ScriptCanvas::GraphVariable> m_variables;
// the values here may or may not be overrides
AZStd::vector<AZStd::pair<ScriptCanvas::VariableId, AZ::EntityId>> m_entityIds;
// this is all that gets exposed to the edit context
AZStd::vector<ScriptCanvas::GraphVariable> m_overrides;
// AZStd::vector<size_t> m_entityIdRuntimeInputIndices; since all of the entity ids need to go in, they may not need indices
AZStd::vector<BuildVariableOverrides> m_dependencies;
};
class EditorAssetTree
{
public:
AZ_CLASS_ALLOCATOR(EditorAssetTree, AZ::SystemAllocator, 0);
EditorAssetTree* m_parent = nullptr;
AZStd::vector<EditorAssetTree> m_dependencies;
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> m_asset;
EditorAssetTree* ModRoot();
void SetParent(EditorAssetTree& parent);
AZStd::string ToString(size_t depth = 0) const;
};
// copy the variables overridden during editor / prefab build time back to runtime data
ScriptCanvas::RuntimeDataOverrides ConvertToRuntime(const BuildVariableOverrides& overrides);
AZ::Outcome<EditorAssetTree, AZStd::string> LoadEditorAssetTree(AZ::Data::AssetId editorAssetId, AZStd::string_view assetHint, EditorAssetTree* parent = nullptr);
AZ::Outcome<BuildVariableOverrides, AZStd::string> ParseEditorAssetTree(const EditorAssetTree& editorAssetTree);
}

@ -10,6 +10,7 @@
#include <AssetBuilderSDK/AssetBuilderBusses.h>
#include <AzCore/std/containers/map.h>
#include <AzToolsFramework/ToolsComponents/ToolsAssetCatalogBus.h>
#include <Builder/ScriptCanvasBuilder.h>
#include <Builder/ScriptCanvasBuilderComponent.h>
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <ScriptCanvas/Asset/Functions/RuntimeFunctionAssetHandler.h>
@ -163,6 +164,8 @@ namespace ScriptCanvasBuilder
void PluginComponent::Reflect(AZ::ReflectContext* context)
{
BuildVariableOverrides::Reflect(context);
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<PluginComponent, AZ::Component>()

@ -70,6 +70,7 @@ namespace ScriptCanvasBuilder
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data());
return;
}
AZStd::vector<AZ::u8> fileBuffer(ioStream.GetLength());
size_t bytesRead = ioStream.Read(fileBuffer.size(), fileBuffer.data());
if (bytesRead != ioStream.GetLength())
@ -87,15 +88,15 @@ namespace ScriptCanvasBuilder
{
// force load these before processing
if (filterInfo.m_assetType == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>()
|| filterInfo.m_assetType == azrtti_typeid<ScriptEvents::ScriptEventsAsset>())
|| filterInfo.m_assetType == azrtti_typeid<ScriptEvents::ScriptEventsAsset>())
{
this->m_processEditorAssetDependencies.push_back(filterInfo);
}
// these trigger re-processing
if (filterInfo.m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>()
|| filterInfo.m_assetType == azrtti_typeid<ScriptEvents::ScriptEventsAsset>()
|| filterInfo.m_assetType == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
|| filterInfo.m_assetType == azrtti_typeid<ScriptEvents::ScriptEventsAsset>()
|| filterInfo.m_assetType == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
{
AssetBuilderSDK::SourceFileDependency dependency;
dependency.m_sourceFileDependencyUUID = filterInfo.m_assetId.m_guid;
@ -210,7 +211,7 @@ namespace ScriptCanvasBuilder
bool pathFound = false;
AZStd::string relativePath;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
( pathFound
(pathFound
, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath
, request.m_fullPath.c_str(), relativePath);

@ -55,6 +55,8 @@ namespace ScriptCanvasBuilder
DependencyArguments,
DependencyRequirementsData,
AddAssetDependencySearch,
PrefabIntegration,
CorrectGraphVariableVersion,
// add new entries above
Current,
};
@ -130,10 +132,12 @@ namespace ScriptCanvasBuilder
int GetBuilderVersion();
AZ::Outcome<AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>, AZStd::string> LoadEditorAsset(AZStd::string_view graphPath);
AZ::Outcome<AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>, AZStd::string> LoadEditorAsset(AZStd::string_view graphPath, AZ::Data::AssetId assetId, AZ::Data::AssetFilterCB assetFilterCB = {});
AZ::Outcome<AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasFunctionAsset>, AZStd::string> LoadEditorFunctionAsset(AZStd::string_view graphPath);
AZ::Outcome<ScriptCanvas::Grammar::AbstractCodeModelConstPtr, AZStd::string> ParseGraph(AZ::Entity& buildEntity, AZStd::string_view graphPath);
AZ::Outcome<void, AZStd::string> ProcessTranslationJob(ProcessTranslationJobInput& input);
ScriptCanvasEditor::Graph* PrepareSourceGraph(AZ::Entity* const buildEntity);
@ -149,7 +153,7 @@ namespace ScriptCanvasBuilder
{
public:
static AZ::Uuid GetUUID();
Worker() = default;
Worker(const Worker&) = delete;
@ -175,7 +179,7 @@ namespace ScriptCanvasBuilder
// cached on first time query
mutable AZStd::string m_fingerprintString;
};
class FunctionWorker
: public AssetBuilderSDK::AssetBuilderCommandBus::Handler
{
@ -195,7 +199,7 @@ namespace ScriptCanvasBuilder
int GetVersionNumber() const;
void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) const;
void ShutDown() override {};
private:

@ -17,9 +17,7 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Script/ScriptComponent.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <ScriptCanvas/Asset/Functions/RuntimeFunctionAssetHandler.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
@ -32,7 +30,6 @@
#include <ScriptCanvas/Grammar/AbstractCodeModel.h>
#include <ScriptCanvas/Results/ErrorText.h>
#include <ScriptCanvas/Utils/BehaviorContextUtils.h>
#include <Source/Components/SceneComponent.h>
namespace ScriptCanvasBuilder
@ -62,6 +59,26 @@ namespace ScriptCanvasBuilder
}
}
AZ::Outcome<ScriptCanvas::Grammar::AbstractCodeModelConstPtr, AZStd::string> ParseGraph(AZ::Entity& buildEntity, AZStd::string_view graphPath)
{
AZStd::string fileNameOnly;
AzFramework::StringFunc::Path::GetFullFileName(graphPath.data(), fileNameOnly);
ScriptCanvas::Grammar::Request request;
request.graph = PrepareSourceGraph(&buildEntity);
if (!request.graph)
{
return AZ::Failure(AZStd::string("build entity did not have source graph components"));
}
request.rawSaveDebugOutput = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFileAtPrefabTime;
request.printModelToConsole = ScriptCanvas::Grammar::g_printAbstractCodeModelAtPrefabTime;
request.name = fileNameOnly.empty() ? fileNameOnly : "BuilderGraph";
request.addDebugInformation = false;
return ScriptCanvas::Translation::ParseGraph(request);
}
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(AZ::Entity* buildEntity, AZ::Data::AssetId scriptAssetId, AZStd::string_view rawLuaFilePath)
{
AZStd::string fullPath(rawLuaFilePath);
@ -72,7 +89,7 @@ namespace ScriptCanvasBuilder
auto sourceGraph = PrepareSourceGraph(buildEntity);
ScriptCanvas::Grammar::Request request;
request.assetId = scriptAssetId;
request.scriptAssetId = scriptAssetId;
request.graph = sourceGraph;
request.name = fileNameOnly;
request.rawSaveDebugOutput = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile;
@ -82,7 +99,7 @@ namespace ScriptCanvasBuilder
bool pathFound = false;
AZStd::string relativePath;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
( pathFound
(pathFound
, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath
, fullPath.c_str(), relativePath);
@ -396,7 +413,7 @@ namespace ScriptCanvasBuilder
;
}
AZ::Outcome < AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>, AZStd::string> LoadEditorAsset(AZStd::string_view filePath)
AZ::Outcome < AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>, AZStd::string> LoadEditorAsset(AZStd::string_view filePath, AZ::Data::AssetId assetId, AZ::Data::AssetFilterCB assetFilterCB)
{
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
@ -425,9 +442,9 @@ namespace ScriptCanvasBuilder
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> asset;
asset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()));
asset.Create(assetId);
if (editorAssetHandler.LoadAssetData(asset, assetDataStream, AZ::Data::AssetFilterCB{}) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
if (editorAssetHandler.LoadAssetData(asset, assetDataStream, assetFilterCB) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
{
return AZ::Failure(AZStd::string::format("Failed to load ScriptCavas asset: %s", filePath.data()));
}
@ -513,10 +530,7 @@ namespace ScriptCanvasBuilder
}
}
if (buildEntity->GetState() == AZ::Entity::State::Constructed)
{
buildEntity->Init();
}
ScriptCanvas::ScopedAuxiliaryEntityHandler entityHandler(buildEntity);
if (buildEntity->GetState() == AZ::Entity::State::Init)
{
@ -533,7 +547,7 @@ namespace ScriptCanvasBuilder
auto version = sourceGraph->GetVersion();
if (version.grammarVersion == ScriptCanvas::GrammarVersion::Initial
|| version.runtimeVersion == ScriptCanvas::RuntimeVersion::Initial)
|| version.runtimeVersion == ScriptCanvas::RuntimeVersion::Initial)
{
return AZ::Failure(AZStd::string(ScriptCanvas::ParseErrors::SourceUpdateRequired));
}
@ -542,7 +556,7 @@ namespace ScriptCanvasBuilder
request.path = input.fullPath;
request.name = input.fileNameOnly;
request.namespacePath = input.namespacePath;
request.assetId = input.assetID;
request.scriptAssetId = input.assetID;
request.graph = sourceGraph;
request.rawSaveDebugOutput = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile;
request.printModelToConsole = ScriptCanvas::Grammar::g_printAbstractCodeModel;
@ -728,6 +742,6 @@ namespace ScriptCanvasBuilder
ScriptCanvas::Translation::Result TranslateToLua(ScriptCanvas::Grammar::Request& request)
{
request.translationTargetFlags = ScriptCanvas::Translation::TargetFlags::Lua;
return ScriptCanvas::Translation::ParseGraph(request);
return ScriptCanvas::Translation::ParseAndTranslateGraph(request);
}
}

@ -19,19 +19,30 @@
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <Core/ScriptCanvasBus.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Components/EditorScriptCanvasComponent.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
#include <ScriptCanvas/PerformanceStatisticsBus.h>
namespace EditorScriptCanvasComponentCpp
{
enum Version
{
PrefabIntegration = 10,
// add description above
Current
};
}
namespace ScriptCanvasEditor
{
static bool EditorScriptCanvasComponentVersionConverter(AZ::SerializeContext& serializeContext, AZ::SerializeContext::DataElementNode& rootElement)
@ -74,6 +85,63 @@ namespace ScriptCanvasEditor
rootElement.RemoveElementByName(AZ_CRC("m_variableEntityIdMap", 0xdc6c75a8));
}
if (rootElement.GetVersion() <= EditorScriptCanvasComponentCpp::Version::PrefabIntegration)
{
auto variableDataElementIndex = rootElement.FindElement(AZ_CRC_CE("m_variableData"));
if (variableDataElementIndex == -1)
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: 'm_variableData' index was missing");
return false;
}
auto& variableDataElement = rootElement.GetSubElement(variableDataElementIndex);
ScriptCanvas::EditableVariableData editableData;
if (!variableDataElement.GetData(editableData))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: could not retrieve old 'm_variableData'");
return false;
}
auto scriptCanvasAssetHolderElementIndex = rootElement.FindElement(AZ_CRC_CE("m_assetHolder"));
if (scriptCanvasAssetHolderElementIndex == -1)
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: 'm_assetHolder' index was missing");
return false;
}
auto& scriptCanvasAssetHolderElement = rootElement.GetSubElement(scriptCanvasAssetHolderElementIndex);
ScriptCanvasAssetHolder assetHolder;
if (!scriptCanvasAssetHolderElement.GetData(assetHolder))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: could not retrieve old 'm_assetHolder'");
return false;
}
rootElement.RemoveElement(variableDataElementIndex);
if (!rootElement.AddElementWithData(serializeContext, "runtimeDataIsValid", true))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: failed to add 'runtimeDataIsValid'");
return false;
}
ScriptCanvasBuilder::BuildVariableOverrides overrides;
overrides.m_source = AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>(assetHolder.GetAssetId(), assetHolder.GetAssetType(), assetHolder.GetAssetHint());;
for (auto& variable : editableData.GetVariables())
{
overrides.m_overrides.push_back(variable.m_graphVariable);
}
if (!rootElement.AddElementWithData(serializeContext, "runtimeDataOverrides", overrides))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: failed to add 'runtimeDataOverrides'");
return false;
}
}
return true;
}
@ -83,10 +151,11 @@ namespace ScriptCanvasEditor
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<EditorScriptCanvasComponent, EditorComponentBase>()
->Version(8, &EditorScriptCanvasComponentVersionConverter)
->Version(EditorScriptCanvasComponentCpp::Version::Current, &EditorScriptCanvasComponentVersionConverter)
->Field("m_name", &EditorScriptCanvasComponent::m_name)
->Field("m_assetHolder", &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder)
->Field("m_variableData", &EditorScriptCanvasComponent::m_editableData)
->Field("runtimeDataIsValid", &EditorScriptCanvasComponent::m_runtimeDataIsValid)
->Field("runtimeDataOverrides", &EditorScriptCanvasComponent::m_variableOverrides)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
@ -103,9 +172,9 @@ namespace ScriptCanvasEditor
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Level", 0x9aeacc13))
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/script-canvas/")
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder, "Script Canvas Asset", "Script Canvas asset associated with this component")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_editableData, "Properties", "Script Canvas Graph Properties")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_variableOverrides, "Properties", "Script Canvas Graph Properties")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
;
}
}
@ -133,6 +202,11 @@ namespace ScriptCanvasEditor
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
}
const AZStd::string& EditorScriptCanvasComponent::GetName() const
{
return m_name;
}
void EditorScriptCanvasComponent::UpdateName()
{
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
@ -208,18 +282,7 @@ namespace ScriptCanvasEditor
if (fileAssetId.IsValid())
{
AssetTrackerNotificationBus::Handler::BusConnect(fileAssetId);
ScriptCanvasMemoryAsset::pointer memoryAsset;
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, fileAssetId);
if (memoryAsset && memoryAsset->GetAsset().GetStatus() == AZ::Data::AssetData::AssetStatus::Ready)
{
OnScriptCanvasAssetReady(memoryAsset);
}
else
{
AssetTrackerRequestBus::Broadcast(&AssetTrackerRequests::Load, m_scriptCanvasAssetHolder.GetAssetId(), m_scriptCanvasAssetHolder.GetAssetType(), nullptr);
}
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
}
}
@ -233,81 +296,67 @@ namespace ScriptCanvasEditor
EditorComponentBase::Deactivate();
//EditorScriptCanvasAssetNotificationBus::Handler::BusDisconnect();
EditorScriptCanvasComponentRequestBus::Handler::BusDisconnect();
EditorContextMenuRequestBus::Handler::BusDisconnect();
}
//=========================================================================
void EditorScriptCanvasComponent::BuildGameEntity(AZ::Entity* gameEntity)
void EditorScriptCanvasComponent::BuildGameEntityData()
{
AZ::Data::AssetId editorAssetId = m_scriptCanvasAssetHolder.GetAssetId();
using namespace ScriptCanvasBuilder;
m_runtimeDataIsValid = false;
if (!editorAssetId.IsValid())
auto assetTreeOutcome = LoadEditorAssetTree(m_scriptCanvasAssetHolder.GetAssetId(), m_scriptCanvasAssetHolder.GetAssetHint());
if (!assetTreeOutcome.IsSuccess())
{
AZ_Warning("ScriptCanvas", false, "EditorScriptCanvasComponent::BuildGameEntityData failed: %s", assetTreeOutcome.GetError().c_str());
return;
}
AZ::Data::AssetId runtimeAssetId(editorAssetId.m_guid, AZ_CRC("RuntimeData", 0x163310ae));
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> runtimeAsset(runtimeAssetId, azrtti_typeid<ScriptCanvas::RuntimeAsset>(), {});
EditorAssetTree& editorAssetTree = assetTreeOutcome.GetValue();
/*
This defense against creating useless runtime components is pending changes the slice update system.
It also would require better abilities to check asset integrity when building assets that depend
on ScriptCanvas assets.
auto parseOutcome = ParseEditorAssetTree(editorAssetTree);
if (!parseOutcome.IsSuccess())
{
AZ_Warning("ScriptCanvas", false, "EditorScriptCanvasComponent::BuildGameEntityData failed: %s", parseOutcome.GetError().c_str());
return;
}
AZ::Data::AssetInfo assetInfo;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, runtimeAssetId);
auto& variableOverrides = parseOutcome.GetValue();
if (assetInfo.m_assetType == AZ::Data::s_invalidAssetType)
if (!m_variableOverrides.IsEmpty())
{
AZ_Warning("ScriptCanvas", false, "No ScriptCanvas Runtime Asset information for Entity ('%s' - '%s') Graph ('%s'), asset may be in error or deleted"
, gameEntity->GetName().c_str()
, GetEntityId().ToString().c_str()
, GetName().c_str());
return;
variableOverrides.CopyPreviousOverriddenValues(m_variableOverrides);
}
AzFramework::AssetSystem::AssetStatus statusResult = AzFramework::AssetSystem::AssetStatus_Unknown;
AzFramework::AssetSystemRequestBus::BroadcastResult(statusResult, &AzFramework::AssetSystem::AssetSystemRequests::GetAssetStatusById, runtimeAssetId);
m_variableOverrides = parseOutcome.TakeValue();
m_runtimeDataIsValid = true;
}
if (statusResult != AzFramework::AssetSystem::AssetStatus_Compiled)
void EditorScriptCanvasComponent::BuildGameEntity(AZ::Entity* gameEntity)
{
if (!m_runtimeDataIsValid)
{
AZ_Warning("ScriptCanvas", false, "No ScriptCanvas Runtime Asset for Entity ('%s' - '%s') Graph ('%s'), compilation may have failed or not completed"
, gameEntity->GetName().c_str()
, GetEntityId().ToString().c_str()
, GetName().c_str());
// this is fine, there could have been no graph set, or set to a graph that failed to compile
return;
}
*/
// #functions2 dependency-ctor-args make recursive
auto executionComponent = gameEntity->CreateComponent<ScriptCanvas::RuntimeComponent>(runtimeAsset);
ScriptCanvas::VariableData varData;
// build everything again as a sanity check against dependencies. All of the variable overrides that were valid will be copied over
BuildGameEntityData();
for (const auto& varConfig : m_editableData.GetVariables())
if (!m_runtimeDataIsValid)
{
if (varConfig.m_graphVariable.GetDatum()->Empty())
{
AZ_Error("ScriptCanvas", false, "Data loss detected for GraphVariable ('%s') on Entity ('%s' - '%s') Graph ('%s')"
, varConfig.m_graphVariable.GetVariableName().data()
, gameEntity->GetName().c_str()
, GetEntityId().ToString().c_str()
, GetName().c_str());
}
else
{
varData.AddVariable(varConfig.m_graphVariable.GetVariableName(), varConfig.m_graphVariable);
}
AZ_Error("ScriptCanvasBuilder", false, "Runtime information did not build for ScriptCanvas Component using asset: %s", m_scriptCanvasAssetHolder.GetAssetId().ToString<AZStd::string>().c_str());
return;
}
executionComponent->SetVariableOverrides(varData);
auto runtimeComponent = gameEntity->CreateComponent<ScriptCanvas::RuntimeComponent>();
auto runtimeOverrides = ConvertToRuntime(m_variableOverrides);
runtimeComponent->SetRuntimeDataOverrides(runtimeOverrides);
}
void EditorScriptCanvasComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
{
// If we removed out asset due to the catalog removing. Just set it back.
if (m_removedCatalogId == assetId)
{
if (!m_scriptCanvasAssetHolder.GetAssetId().IsValid())
@ -317,12 +366,9 @@ namespace ScriptCanvasEditor
}
}
}
void EditorScriptCanvasComponent::OnCatalogAssetRemoved(const AZ::Data::AssetId& removedAssetId, const AZ::Data::AssetInfo& /*assetInfo*/)
{
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
// If the Asset gets removed from disk while the Editor is loaded clear out the asset reference.
if (assetId == removedAssetId)
{
m_removedCatalogId = assetId;
@ -355,8 +401,6 @@ namespace ScriptCanvasEditor
}
}
AzToolsFramework::ScopedUndoBatch undo("Update Entity With New SC Graph");
AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::Bus::Events::AddDirtyEntity, GetEntityId());
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
}
@ -448,7 +492,6 @@ namespace ScriptCanvasEditor
{
// Invalidate the previously removed catalog id if we are setting a new asset id
m_removedCatalogId.SetInvalid();
SetPrimaryAsset(assetId);
}
}
@ -469,125 +512,17 @@ namespace ScriptCanvasEditor
{
if (memoryAsset->GetFileAssetId() == m_scriptCanvasAssetHolder.GetAssetId())
{
LoadVariables(memoryAsset);
auto assetData = memoryAsset->GetAsset();
AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity();
AZ_Assert(scriptCanvasEntity, "This graph must have a valid entity");
BuildGameEntityData();
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
UpdateName();
}
}
/*! Start Variable Block Implementation */
void EditorScriptCanvasComponent::AddVariable(AZStd::string_view varName, const ScriptCanvas::GraphVariable& graphVariable)
{
// We only add component properties to the component
if (!graphVariable.IsComponentProperty())
{
return;
}
const auto& variableId = graphVariable.GetVariableId();
ScriptCanvas::EditableVariableConfiguration* originalVarNameValuePair = m_editableData.FindVariable(variableId);
if (!originalVarNameValuePair)
{
m_editableData.AddVariable(varName, graphVariable);
originalVarNameValuePair = m_editableData.FindVariable(variableId);
}
if (!originalVarNameValuePair)
{
AZ_Error("Script Canvas", false, "Unable to find variable with id %s and name %s on the ScriptCanvas Component. There is an issue in AddVariable",
variableId.ToString().data(), varName.data());
return;
}
// Update the variable name as it may have changed
originalVarNameValuePair->m_graphVariable.SetVariableName(varName);
originalVarNameValuePair->m_graphVariable.SetExposureCategory(graphVariable.GetExposureCategory());
originalVarNameValuePair->m_graphVariable.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide);
originalVarNameValuePair->m_graphVariable.SetAllowSignalOnChange(false);
}
void EditorScriptCanvasComponent::AddNewVariables(const ScriptCanvas::VariableData& graphVarData)
{
for (auto&& variablePair : graphVarData.GetVariables())
{
AddVariable(variablePair.second.GetVariableName(), variablePair.second);
}
}
void EditorScriptCanvasComponent::RemoveVariable(const ScriptCanvas::VariableId& varId)
{
m_editableData.RemoveVariable(varId);
}
void EditorScriptCanvasComponent::RemoveOldVariables(const ScriptCanvas::VariableData& graphVarData)
{
AZStd::vector<ScriptCanvas::VariableId> oldVariableIds;
for (auto varConfig : m_editableData.GetVariables())
{
const auto& variableId = varConfig.m_graphVariable.GetVariableId();
// We only add component sourced graph properties to the script canvas component, so if this variable was switched to a graph-only property remove it.
// Also be sure to remove this variable if it's been deleted entirely.
auto graphVariable = graphVarData.FindVariable(variableId);
if (!graphVariable || !graphVariable->IsComponentProperty())
{
oldVariableIds.push_back(variableId);
}
}
for (const auto& oldVariableId : oldVariableIds)
{
RemoveVariable(oldVariableId);
}
}
bool EditorScriptCanvasComponent::UpdateVariable(const ScriptCanvas::GraphVariable& graphDatum, ScriptCanvas::GraphVariable& updateDatum, ScriptCanvas::GraphVariable& originalDatum)
{
// If the editable datum is the different than the original datum, then the "variable value" has been overridden on this component
// Variable values only propagate from the Script Canvas graph to this component if the original "variable value" has not been overridden
// by the editable "variable value" on this component and the "variable value" on the graph is different than the variable value on this component
auto isNotOverridden = (*updateDatum.GetDatum()) == (*originalDatum.GetDatum());
auto scGraphIsModified = (*originalDatum.GetDatum()) != (*graphDatum.GetDatum());
if (isNotOverridden && scGraphIsModified)
{
ScriptCanvas::ModifiableDatumView originalDatumView;
originalDatum.ConfigureDatumView(originalDatumView);
originalDatumView.AssignToDatum((*graphDatum.GetDatum()));
ScriptCanvas::ModifiableDatumView updatedDatumView;
updateDatum.ConfigureDatumView(updatedDatumView);
updatedDatumView.AssignToDatum((*graphDatum.GetDatum()));
return true;
}
return false;
}
void EditorScriptCanvasComponent::LoadVariables(const ScriptCanvasMemoryAsset::pointer memoryAsset)
{
auto assetData = memoryAsset->GetAsset();
AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity();
AZ_Assert(scriptCanvasEntity, "This graph must have a valid entity");
auto variableComponent = scriptCanvasEntity ? AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::GraphVariableManagerComponent>(scriptCanvasEntity) : nullptr;
if (variableComponent)
{
// Add properties from the SC Asset to the SC Component if they do not exist on the SC Component
AddNewVariables(*variableComponent->GetVariableData());
RemoveOldVariables(*variableComponent->GetVariableData());
}
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
}
void EditorScriptCanvasComponent::ClearVariables()
{
m_editableData.Clear();
m_variableOverrides.Clear();
}
/* End Variable Block Implementation*/
}

@ -19,8 +19,15 @@ namespace ScriptCanvas
namespace ScriptCanvasEditor
{
using LoadedInterpretedDependencies = AZStd::vector<AZStd::pair<AZStd::string, ScriptCanvas::Translation::LuaAssetResult>>;
AZ_INLINE LoadedInterpretedDependencies LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet);
struct LoadedInterpretedDependency
{
AZStd::string path;
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> runtimeAsset;
ScriptCanvas::Translation::LuaAssetResult luaAssetResult;
AZStd::vector<LoadedInterpretedDependency> dependencies;
};
AZ_INLINE AZStd::vector<LoadedInterpretedDependency> LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet);
AZ_INLINE LoadTestGraphResult LoadTestGraph(AZStd::string_view path);
@ -49,10 +56,11 @@ namespace ScriptCanvasEditor
AZ_INLINE void RunGraphImplementation(const RunGraphSpec& runGraphSpec, Reporter& reporter);
AZ_INLINE void RunGraphImplementation(const RunGraphSpec& runGraphSpec, LoadTestGraphResult& loadGraphResult, Reporter& reporter);
AZ_INLINE void RunGraphImplementation(const RunGraphSpec& runGraphSpec, Reporters& reporters);
AZ_INLINE void Simulate(const DurationSpec& duration);
AZ_INLINE void SimulateDuration(const DurationSpec& duration);
AZ_INLINE void SimulateSeconds(const DurationSpec& duration);
AZ_INLINE void SimulateTicks(const DurationSpec& duration);
} // ScriptCanvasEditor
#include <Editor/Framework/ScriptCanvasGraphUtilities.inl>

@ -26,9 +26,25 @@ namespace ScriptCanvasEditor
{
using namespace ScriptCanvas;
AZ_INLINE LoadedInterpretedDependencies LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet)
// The runtime context (appropriately) always assumes that EntityIds are overridden, this step copies the values from the runtime data
// over to the override data to simulate build step that does this when building prefabs
AZ_INLINE void CopyAssetEntityIdsToOverrides(RuntimeDataOverrides& runtimeDataOverrides)
{
LoadedInterpretedDependencies loadedAssets;
runtimeDataOverrides.m_entityIds.reserve(runtimeDataOverrides.m_runtimeAsset->GetData().m_input.m_entityIds.size());
for (auto& varEntityPar : runtimeDataOverrides.m_runtimeAsset->GetData().m_input.m_entityIds)
{
runtimeDataOverrides.m_entityIds.push_back(varEntityPar.second);
}
for (auto& dependency : runtimeDataOverrides.m_dependencies)
{
CopyAssetEntityIdsToOverrides(dependency);
}
}
AZ_INLINE AZStd::vector<LoadedInterpretedDependency> LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet)
{
AZStd::vector<LoadedInterpretedDependency> loadedAssets;
if (!dependencySet.empty())
{
@ -41,7 +57,7 @@ namespace ScriptCanvasEditor
AZ_Assert(namespacePath.size() >= 3, "This functions assumes unit test dependencies are in the ScriptCanvas gem unit test folder");
AZStd::string originalPath = namespacePath[2].data();
for (size_t index = 3; index < namespacePath.size(); ++index)
{
originalPath += "/";
@ -52,11 +68,11 @@ namespace ScriptCanvasEditor
{
originalPath.resize(originalPath.size() - AZStd::string_view(Grammar::k_internalRuntimeSuffix).size());
}
AZStd::string path = AZStd::string::format("%s/%s.scriptcanvas", k_unitTestDirPathRelative, originalPath.data());
LoadTestGraphResult loadResult = LoadTestGraph(path);
AZ_Assert(loadResult.m_runtimeAsset, "failed to load dependent asset");
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> luaAssetOutcome = AZ::Failure(AZStd::string("lua asset creation for function failed"));
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(luaAssetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateLuaAsset, loadResult.m_editorAsset, loadResult.m_graphPath);
AZ_Assert(luaAssetOutcome.IsSuccess(), "failed to create Lua asset");
@ -69,8 +85,9 @@ namespace ScriptCanvasEditor
}
const ScriptCanvas::Translation::LuaAssetResult& luaAssetResult = luaAssetOutcome.GetValue();
loadedAssets.push_back({ modulePath, luaAssetResult });
}
// #functions2_recursive_unit_tests
loadedAssets.push_back({ modulePath, loadResult.m_runtimeAsset, luaAssetResult, {} });
}
}
return loadedAssets;
@ -182,7 +199,7 @@ namespace ScriptCanvasEditor
RuntimeData runtimeDataBuffer;
AZStd::vector<RuntimeData> dependencyDataBuffer;
LoadedInterpretedDependencies dependencies;
AZStd::vector<LoadedInterpretedDependency> dependencies;
if (runGraphSpec.runSpec.execution == ExecutionMode::Interpreted)
{
@ -202,9 +219,12 @@ namespace ScriptCanvasEditor
{
dependencies = LoadInterpretedDepencies(luaAssetResult.m_dependencies.source.userSubgraphs);
RuntimeDataOverrides runtimeDataOverrides;
runtimeDataOverrides.m_runtimeAsset = loadResult.m_runtimeAsset;
if (!dependencies.empty())
{
// eventually, this will need to be recursive, or the full asset handling system will need to be integrated into the testing framework
// #functions2_recursive_unit_tests eventually, this will need to be recursive, or the full asset handling system will need to be integrated into the testing framework
// in order to test functionality with a dependency stack greater than 2
// load all script assets, and their dependencies, initialize statics on all those dependencies if it is the first time loaded
@ -215,7 +235,7 @@ namespace ScriptCanvasEditor
for (auto& dependency : dependencies)
{
inMemoryModules.emplace_back(dependency.first, dependency.second.m_scriptAsset);
inMemoryModules.emplace_back(dependency.path, dependency.luaAssetResult.m_scriptAsset);
}
AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::UseInMemoryRequireHook, inMemoryModules, AZ::ScriptContextIds::DefaultScriptContextId);
@ -224,7 +244,11 @@ namespace ScriptCanvasEditor
for (size_t index = 0; index < dependencies.size(); ++index)
{
auto& dependency = dependencies[index];
const ScriptCanvas::Translation::LuaAssetResult& depencyAssetResult = dependency.second;
const ScriptCanvas::Translation::LuaAssetResult& depencyAssetResult = dependency.luaAssetResult;
RuntimeDataOverrides dependencyRuntimeDataOverrides;
dependencyRuntimeDataOverrides.m_runtimeAsset = dependency.runtimeAsset;
runtimeDataOverrides.m_dependencies.push_back(dependencyRuntimeDataOverrides);
RuntimeData& dependencyData = dependencyDataBuffer[index];
dependencyData.m_input = depencyAssetResult.m_runtimeInputs;
@ -239,7 +263,9 @@ namespace ScriptCanvasEditor
loadResult.m_runtimeAsset.Get()->GetData().m_script = loadResult.m_scriptAsset;
loadResult.m_runtimeAsset.Get()->GetData().m_input = luaAssetResult.m_runtimeInputs;
loadResult.m_runtimeAsset.Get()->GetData().m_debugMap = luaAssetResult.m_debugMap;
loadResult.m_runtimeComponent = loadResult.m_entity->CreateComponent<ScriptCanvas::RuntimeComponent>(loadResult.m_runtimeAsset);
loadResult.m_runtimeComponent = loadResult.m_entity->CreateComponent<ScriptCanvas::RuntimeComponent>();
CopyAssetEntityIdsToOverrides(runtimeDataOverrides);
loadResult.m_runtimeComponent->SetRuntimeDataOverrides(runtimeDataOverrides);
Execution::Context::InitializeActivationData(loadResult.m_runtimeAsset->GetData());
Execution::InitializeInterpretedStatics(loadResult.m_runtimeAsset->GetData());
}

@ -8,14 +8,14 @@
#pragma once
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <Builder/ScriptCanvasBuilder.h>
#include <Editor/Assets/ScriptCanvasAssetHolder.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
#include <ScriptCanvas/Variable/VariableBus.h>
#include <ScriptCanvas/Variable/VariableData.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
namespace ScriptCanvasEditor
{
@ -27,11 +27,10 @@ namespace ScriptCanvasEditor
which it uses to maintain the asset data in memory. Therefore removing an open ScriptCanvasAsset from the file system
will remove the reference from the EditorScriptCanvasComponent, but not the reference from the MainWindow allowing the
ScriptCanvas graph to still be modified while open
Finally per graph instance variables values are stored on the EditorScriptCanvasComponent and injected into the runtime ScriptCanvas component in BuildGameEntity
*/
class EditorScriptCanvasComponent
: public AzToolsFramework::Components::EditorComponentBase
: public AzToolsFramework::Components::EditorComponentBase
, private EditorContextMenuRequestBus::Handler
, private AzFramework::AssetCatalogEventBus::Handler
, private EditorScriptCanvasComponentLoggingBus::Handler
@ -54,7 +53,6 @@ namespace ScriptCanvasEditor
void Deactivate() override;
//=====================================================================
//=====================================================================
// EditorComponentBase
void BuildGameEntity(AZ::Entity* gameEntity) override;
@ -71,10 +69,10 @@ namespace ScriptCanvasEditor
void CloseGraph();
void SetName(const AZStd::string& name) { m_name = name; }
const AZStd::string& GetName() const { return m_name; };
const AZStd::string& GetName() const;
AZ::EntityId GetEditorEntityId() const { return GetEntity() ? GetEntityId() : AZ::EntityId(); }
AZ::NamedEntityId GetNamedEditorEntityId() const { return GetEntity() ? GetNamedEntityId() : AZ::NamedEntityId(); }
//=====================================================================
// EditorScriptCanvasComponentRequestBus
void SetAssetId(const AZ::Data::AssetId& assetId) override;
@ -119,12 +117,8 @@ namespace ScriptCanvasEditor
(void)incompatible;
}
//=====================================================================
// AssetCatalogEventBus
void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override;
void OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) override;
//=====================================================================
void OnScriptCanvasAssetChanged(AZ::Data::AssetId assetId);
void UpdateName();
@ -133,21 +127,15 @@ namespace ScriptCanvasEditor
void OnScriptCanvasAssetReady(const ScriptCanvasMemoryAsset::pointer asset);
//=====================================================================
void AddVariable(AZStd::string_view varName, const ScriptCanvas::GraphVariable& varDatum);
void AddNewVariables(const ScriptCanvas::VariableData& graphVarData);
void RemoveVariable(const ScriptCanvas::VariableId& varId);
void RemoveOldVariables(const ScriptCanvas::VariableData& graphVarData);
bool UpdateVariable(const ScriptCanvas::GraphVariable& graphDatum, ScriptCanvas::GraphVariable& updateDatum, ScriptCanvas::GraphVariable& originalDatum);
void LoadVariables(const ScriptCanvasMemoryAsset::pointer memoryAsset);
void BuildGameEntityData();
void ClearVariables();
private:
AZ::Data::AssetId m_removedCatalogId;
AZ::Data::AssetId m_previousAssetId;
AZStd::string m_name;
ScriptCanvasAssetHolder m_scriptCanvasAssetHolder;
ScriptCanvas::EditableVariableData m_editableData;
bool m_runtimeDataIsValid = false;
ScriptCanvasBuilder::BuildVariableOverrides m_variableOverrides;
};
}

@ -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
*
*/
@ -289,7 +289,7 @@ namespace ScriptCanvasEditor
void LoggingDataAggregator::OnRegistrationDisabled(const AZ::NamedEntityId&, const ScriptCanvas::GraphIdentifier&)
{
}
void LoggingDataAggregator::ResetLog()
@ -324,7 +324,7 @@ namespace ScriptCanvasEditor
m_hasAnchor = false;
m_anchorTimeStamp = ScriptCanvas::Timestamp(0);
}
void LoggingDataAggregator::RegisterScriptCanvas(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
bool foundMatch = false;
@ -335,7 +335,7 @@ namespace ScriptCanvasEditor
if (mapIter->second == graphIdentifier)
{
foundMatch = true;
AZ_Error("ScriptCanvas", false, "Received a duplicated registration callback.");
AZ_Warning("ScriptCanvas", false, "Received a duplicated registration callback.");
}
}

@ -523,7 +523,7 @@ namespace ScriptCanvasEditor
// Creation Actions
{
m_createScriptCanvas = new QToolButton();
m_createScriptCanvas->setIcon(QIcon(ScriptCanvas::AssetDescription::GetIconPath<ScriptCanvasAsset>()));
m_createScriptCanvas->setIcon(QIcon(":/ScriptCanvasEditorResources/Resources/create_graph.png"));
m_createScriptCanvas->setToolTip("Creates a new Script Canvas Graph");
QObject::connect(m_createScriptCanvas, &QToolButton::clicked, this, &MainWindow::OnFileNew);

@ -12,6 +12,7 @@
<file>Resources/capture_offline.png</file>
<file>Resources/create_function_input.png</file>
<file>Resources/create_function_output.png</file>
<file>Resources/create_graph.png</file>
<file>Resources/CollapseAll_Icon.png</file>
<file>Resources/edit_icon.png</file>
<file>Resources/error_icon.png</file>

@ -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
{
return m_runtimeAsset;
}
const RuntimeData& RuntimeComponent::GetAssetData() const
const RuntimeData& RuntimeComponent::GetRuntimeAssetData() 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);
}
}
}
}

@ -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,45 +102,45 @@ 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)
{
classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd));
classElement.AddElementWithData<VariableFlags::Scope>(context, "Scope", VariableFlags::Scope::Graph);
}
else
if (classElement.GetVersion() < 3)
{
AZ::u8 exposureType = VariableFlags::Deprecated::Exposure::Exp_Local;
classElement.GetChildData<AZ::u8>(AZ_CRC("Exposure", 0x398f29cd), exposureType);
bool exposeAsInputField = false;
classElement.GetChildData<bool>(AZ_CRC("ExposeAsInput", 0x0f7879f0), exposeAsInputField);
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)
if (exposeAsInputField)
{
scope = VariableFlags::Scope::Graph;
classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd));
classElement.AddElementWithData<VariableFlags::Scope>(context, "Scope", VariableFlags::Scope::Graph);
}
else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Output)
else
{
scope = VariableFlags::Scope::Function;
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.AddElementWithData<VariableFlags::Scope>(context, "Scope", scope);
classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd));
classElement.RemoveElementByName(AZ_CRC("ExposeAsInput", 0x0f7879f0));
}
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.")

@ -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,10 +9,11 @@
#include <AzCore/Component/EntityUtils.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/Utils.h>
#include <Libraries/Libraries.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/Contract.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/Node.h>
@ -21,6 +22,7 @@
#include <ScriptCanvas/Execution/ExecutionPerformanceTimer.h>
#include <ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
#include <ScriptCanvas/Serialization/ScriptUserDataSerializer.h>
#include <ScriptCanvas/SystemComponent.h>
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
@ -53,7 +55,6 @@ namespace ScriptCanvasSystemComponentCpp
namespace ScriptCanvas
{
void SystemComponent::Reflect(AZ::ReflectContext* context)
{
Nodeable::Reflect(context);
@ -83,11 +84,16 @@ namespace ScriptCanvas
}
}
if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast<AZ::JsonRegistrationContext*>(context))
{
jsonContext->Serializer<AZ::ScriptUserDataSerializer>()
->HandlesType<RuntimeVariable>();
}
#if defined(SC_EXECUTION_TRACE_ENABLED)
ExecutionLogData::Reflect(context);
ExecutionLogAsset::Reflect(context);
#endif//defined(SC_EXECUTION_TRACE_ENABLED)
}
void SystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
@ -144,7 +150,7 @@ namespace ScriptCanvas
ModPerformanceTracker()->CalculateReports();
Execution::PerformanceTrackingReport report = ModPerformanceTracker()->GetGlobalReport();
const double ready = aznumeric_caster(report.timing.initializationTime);
const double instant = aznumeric_caster(report.timing.executionTime);
const double latent = aznumeric_caster(report.timing.latentTime);
@ -357,11 +363,11 @@ namespace ScriptCanvas
auto dataRegistry = ScriptCanvas::GetDataRegistry();
for (const auto& classIter : behaviorContext->m_classes)
{
auto createability = GetCreatibility(serializeContext, classIter.second);
if (createability.first != DataRegistry::Createability::None)
{
dataRegistry->RegisterType(classIter.second->m_typeId, createability.second, createability.first);
}
auto createability = GetCreatibility(serializeContext, classIter.second);
if (createability.first != DataRegistry::Createability::None)
{
dataRegistry->RegisterType(classIter.second->m_typeId, createability.second, createability.first);
}
}
}

@ -588,6 +588,8 @@ set(FILES
Include/ScriptCanvas/Profiler/Aggregator.cpp
Include/ScriptCanvas/Profiler/DrillerEvents.h
Include/ScriptCanvas/Profiler/DrillerEvents.cpp
Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h
Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp
Include/ScriptCanvas/Data/DataTrait.cpp
Include/ScriptCanvas/Data/DataTrait.h
Include/ScriptCanvas/Data/PropertyTraits.cpp
@ -620,5 +622,4 @@ set(SKIP_UNITY_BUILD_INCLUSION_FILES
Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h
Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h
Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.cpp
)

@ -7,6 +7,8 @@
set(FILES
Builder/BuilderSystemComponent.h
Builder/ScriptCanvasBuilder.cpp
Builder/ScriptCanvasBuilder.h
Builder/ScriptCanvasBuilderComponent.cpp
Builder/ScriptCanvasBuilderComponent.h
Builder/ScriptCanvasBuilderWorker.cpp

Loading…
Cancel
Save