Initial saving/loading of JSON serialization of sc editor assets
Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com>
This commit is contained in:
@@ -114,11 +114,13 @@ namespace ScriptCanvasEditor
|
||||
|
||||
ScriptCanvas::ScriptCanvasData& ScriptCanvasAsset::GetScriptCanvasData()
|
||||
{
|
||||
AZ_Assert(m_data != nullptr, "data not initialized");
|
||||
return *m_data;
|
||||
}
|
||||
|
||||
const ScriptCanvas::ScriptCanvasData& ScriptCanvasAsset::GetScriptCanvasData() const
|
||||
{
|
||||
AZ_Assert(m_data != nullptr, "data not initialized");
|
||||
return *m_data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace ScriptCanvasEditor
|
||||
AZ::Data::AssetHandler::LoadResult ScriptCanvasAssetHandler::LoadAssetData
|
||||
( const AZ::Data::Asset<AZ::Data::AssetData>& assetTarget
|
||||
, AZStd::shared_ptr<AZ::Data::AssetDataStream> streamSource
|
||||
, const AZ::Data::AssetFilterCB& assetLoadFilterCB)
|
||||
, [[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilterCB)
|
||||
{
|
||||
namespace JSRU = AZ::JsonSerializationUtils;
|
||||
using namespace ScriptCanvas;
|
||||
@@ -86,30 +86,43 @@ namespace ScriptCanvasEditor
|
||||
|
||||
if (scriptCanvasAssetTarget && m_serializeContext && streamSource)
|
||||
{
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
// more mapping stuff
|
||||
settings.m_serializeContext = m_serializeContext;
|
||||
streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
// presume JSON serialization...
|
||||
if (JSRU::LoadObjectFromStreamByType
|
||||
( scriptCanvasAssetTarget
|
||||
, azrtti_typeid<ScriptCanvasAsset>()
|
||||
, *streamSource
|
||||
, &settings).IsSuccess())
|
||||
{
|
||||
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...if there is a failure, check if it is saved in the old format
|
||||
streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
// tolerate unknown classes in the editor. Let the asset processor warn about bad nodes...
|
||||
bool loadSuccess = AZ::Utils::LoadObjectFromStreamInPlace(*streamSource, scriptCanvasAssetTarget->GetScriptCanvasData()
|
||||
, m_serializeContext
|
||||
, AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES));
|
||||
auto& scriptCanvasDataTarget = scriptCanvasAssetTarget->GetScriptCanvasData();
|
||||
AZStd::vector<AZ::u8> byteBuffer(streamSource->GetLength());
|
||||
AZ::IO::ByteContainerStream<decltype(byteBuffer)> byteStreamSource(&byteBuffer);
|
||||
const size_t bytesRead = streamSource->Read(byteBuffer.size(), byteBuffer.data());
|
||||
|
||||
return loadSuccess ? AZ::Data::AssetHandler::LoadResult::LoadComplete : AZ::Data::AssetHandler::LoadResult::Error;
|
||||
if (bytesRead == streamSource->GetLength())
|
||||
{
|
||||
byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
// \todo more mapping stuff needs to go in the settings
|
||||
settings.m_serializeContext = m_serializeContext;
|
||||
byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
// attempt JSON deserialization...
|
||||
if (JSRU::LoadObjectFromStreamByType
|
||||
( &scriptCanvasDataTarget
|
||||
, azrtti_typeid<ScriptCanvasData>()
|
||||
, byteStreamSource
|
||||
, &settings).IsSuccess())
|
||||
{
|
||||
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)
|
||||
else
|
||||
{
|
||||
// ...if there is a failure, check if it is saved in the old format
|
||||
byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
// tolerate unknown classes in the editor. Let the asset processor warn about bad nodes...
|
||||
if (AZ::Utils::LoadObjectFromStreamInPlace(byteStreamSource, scriptCanvasAssetTarget->GetScriptCanvasData()
|
||||
, m_serializeContext
|
||||
, AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)))
|
||||
{
|
||||
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return AZ::Data::AssetHandler::LoadResult::Error;
|
||||
|
||||
+13
-3
@@ -43,9 +43,19 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
namespace {{attribute_Namespace}}
|
||||
{
|
||||
{% endif %}
|
||||
|
||||
{% set className = Class.attrib['Name'] %}
|
||||
{% set baseClass = Class.attrib['Base'] %}
|
||||
{% if Class.attrib['Base'] is defined %}
|
||||
{% if Class.attrib['Base'].split(';')|length > 1 %}
|
||||
{% set baseClass = Class.attrib['Base'].split(';')[0] %}
|
||||
{% set baseClasses = ", ".join(Class.attrib['Base'].split(';')) %}
|
||||
{% else %}
|
||||
{% set baseClass = Class.attrib['Base'] %}
|
||||
{% set baseClasses = Class.attrib['Base'] %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% set baseClass = "ScriptCanvas::Node" %}
|
||||
{% set baseClasses = "ScriptCanvas::Node" %}
|
||||
{% endif %}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -66,7 +76,7 @@ namespace {{attribute_Namespace}}
|
||||
// You must #include the generated header into the source header
|
||||
#define SCRIPTCANVAS_NODE_{{ className }} \
|
||||
public: \
|
||||
AZ_COMPONENT({{ className }}, "{{ classUuid }}"{% if baseClass is defined %}, {{ baseClass }}{% endif %}); \
|
||||
AZ_COMPONENT({{ className }}, "{{ classUuid }}", {{ baseClasses}} ); \
|
||||
static void Reflect(AZ::ReflectContext* reflection); \
|
||||
void ConfigureSlots() override; \
|
||||
bool RequiresDynamicSlotOrdering() const override; \
|
||||
|
||||
+15
-7
@@ -26,12 +26,22 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#include "{{ xml.attrib['Include'] }}"
|
||||
|
||||
{% for Class in xml.iter('Class') %}
|
||||
{% if Class.attrib['Base'] is defined %}
|
||||
{% if Class.attrib['Base'].split(';')|length > 1 %}
|
||||
{% set baseClass = Class.attrib['Base'].split(';')[0] %}
|
||||
{% set baseClasses = ", ".join(Class.attrib['Base'].split(';')) %}
|
||||
{% else %}
|
||||
{% set baseClass = Class.attrib['Base'] %}
|
||||
{% set baseClasses = Class.attrib['Base'] %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% set baseClass = "ScriptCanvas::Node" %}
|
||||
{% set baseClasses = "ScriptCanvas::Node" %}
|
||||
{% endif %}
|
||||
void {{ Class.attrib['QualifiedName'] }}::ConfigureSlots()
|
||||
{
|
||||
{% if Class.attrib['Base'] is defined %}
|
||||
{{ Class.attrib['Base'] }}::ConfigureSlots();
|
||||
{{ baseClass }}::ConfigureSlots();
|
||||
|
||||
{% endif %}
|
||||
{% for Property in Class.iter('Property') %}
|
||||
{% if Property.attrib['IsInput'] | booleanTrue %}
|
||||
// {{ Property.attrib['Name'] }}
|
||||
@@ -194,13 +204,11 @@ void {{ Class.attrib['QualifiedName'] }}::Reflect(AZ::ReflectContext* context)
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% if Class.attrib['Base'] is defined %}
|
||||
static_assert((std::is_base_of<ScriptCanvas::Node, {{ Class.attrib['Base'] }}>::value), "Script Canvas nodes require the first base class to be derived from ScriptCanvas::Node");
|
||||
static_assert((std::is_base_of<ScriptCanvas::Node, {{ baseClass }}>::value), "Script Canvas nodes require the first base class to be derived from ScriptCanvas::Node");
|
||||
|
||||
{% endif %}
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<{{ Class.attrib['QualifiedName'] }}{% if Class.attrib['Base'] is defined %}, {{ Class.attrib['Base'] }}{% endif %}>()
|
||||
serializeContext->Class<{{ Class.attrib['QualifiedName'] }}, {{ baseClass }}>()
|
||||
{% if Class.attrib['EventHandler'] is defined %}
|
||||
->EventHandler<{{ Class.attrib['EventHandler'] }}>()
|
||||
{% endif %}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <Core/NamedId.h>
|
||||
#include <ScriptCanvas/Grammar/PrimitivesDeclarations.h>
|
||||
|
||||
#define OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class Entity;
|
||||
@@ -94,7 +96,7 @@ namespace ScriptCanvas
|
||||
|
||||
struct VersionData
|
||||
{
|
||||
AZ_TYPE_INFO(VersionData, "{14C629F6-467B-46FE-8B63-48FDFCA42175}");
|
||||
AZ_TYPE_INFO(VersionData, "{52036892-DA63-4199-AC6A-9BAFE6B74EFC}");
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
|
||||
@@ -2041,7 +2041,27 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void Datum::OnWriteEnd()
|
||||
void Datum::OnSerializeBegin()
|
||||
{
|
||||
if (m_type.GetType() == Data::eType::BehaviorContextObject)
|
||||
{
|
||||
if (BehaviorContextObjectPtr ptr = (*AZStd::any_cast<BehaviorContextObjectPtr>(&m_storage.value)))
|
||||
{
|
||||
ptr->OnSerializeBegin();
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("ScriptCanvas", false, AZStd::string::format("Datum type (%s) failed to serialized, did not store BehaviorContextObjectPtr properly", m_type.GetAZType().ToString<AZStd::string>().c_str()).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Datum::OnReadBegin()
|
||||
{
|
||||
OnSerializeBegin();
|
||||
}
|
||||
|
||||
void Datum::OnDeserialize()
|
||||
{
|
||||
if (m_type.GetType() == Data::eType::BehaviorContextObject)
|
||||
{
|
||||
@@ -2059,11 +2079,16 @@ namespace ScriptCanvas
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Script Canvas", false, AZStd::string::format("Datum type (%s) de-serialized, but no such class found in the behavior context", m_type.GetAZType().ToString<AZStd::string>().c_str()).c_str());
|
||||
AZ_Error("ScriptCanvas", false, AZStd::string::format("Datum type (%s) de-serialized, but no such class found in the behavior context", m_type.GetAZType().ToString<AZStd::string>().c_str()).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Datum::OnWriteEnd()
|
||||
{
|
||||
OnSerializeEnd();
|
||||
}
|
||||
|
||||
void Datum::Reflect(AZ::ReflectContext* reflection)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
|
||||
|
||||
@@ -8,14 +8,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
#include <ScriptCanvas/Core/SerializationListener.h>
|
||||
#include <ScriptCanvas/Data/BehaviorContextObject.h>
|
||||
#include <ScriptCanvas/Data/Data.h>
|
||||
#include <ScriptCanvas/Data/DataTrait.h>
|
||||
#include <ScriptCanvas/Data/BehaviorContextObject.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -33,11 +34,12 @@ namespace ScriptCanvas
|
||||
/// A Datum is used to provide generic storage for all data types in ScriptCanvas, and provide a common interface to accessing, modifying, and displaying them
|
||||
/// in the editor, regardless of their actual ScriptCanvas or BehaviorContext type.
|
||||
class Datum final
|
||||
: public SerializationListener
|
||||
{
|
||||
friend class AZ::DatumSerializer;
|
||||
|
||||
public:
|
||||
AZ_TYPE_INFO(Datum, "{8B836FC0-98A8-4A81-8651-35C7CA125451}");
|
||||
AZ_RTTI(Datum, "{8B836FC0-98A8-4A81-8651-35C7CA125451}", SerializationListener);
|
||||
AZ_CLASS_ALLOCATOR(Datum, AZ::SystemAllocator, 0);
|
||||
|
||||
enum class eOriginality : int
|
||||
@@ -237,6 +239,13 @@ namespace ScriptCanvas
|
||||
class SerializeContextEventHandler : public AZ::SerializeContext::IEventHandler
|
||||
{
|
||||
public:
|
||||
/// Called after we are done writing to the instance pointed by classPtr.
|
||||
void OnReadBegin(void* classPtr) override
|
||||
{
|
||||
Datum* datum = reinterpret_cast<Datum*>(classPtr);
|
||||
datum->OnReadBegin();
|
||||
}
|
||||
|
||||
/// Called after we are done writing to the instance pointed by classPtr.
|
||||
void OnWriteEnd(void* classPtr) override
|
||||
{
|
||||
@@ -341,6 +350,10 @@ namespace ScriptCanvas
|
||||
|
||||
void OnDatumEdited();
|
||||
|
||||
void OnSerializeBegin() override;
|
||||
|
||||
void OnDeserialize() override;
|
||||
|
||||
void OnReadBegin();
|
||||
|
||||
void OnWriteEnd();
|
||||
|
||||
@@ -25,9 +25,7 @@ namespace ScriptCanvas
|
||||
/// Called to rebuild the Endpoint map
|
||||
void OnWriteEnd(void* classPtr) override
|
||||
{
|
||||
auto* graphData = reinterpret_cast<GraphData*>(classPtr);
|
||||
graphData->BuildEndpointMap();
|
||||
graphData->LoadDependentAssets();
|
||||
reinterpret_cast<GraphData*>(classPtr)->OnDeserialized();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -215,4 +213,10 @@ namespace ScriptCanvas
|
||||
|
||||
m_dependentAssets.clear();
|
||||
}
|
||||
|
||||
void GraphData::OnDeserialized()
|
||||
{
|
||||
BuildEndpointMap();
|
||||
LoadDependentAssets();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace ScriptCanvas
|
||||
void BuildEndpointMap();
|
||||
void Clear(bool deleteData = false);
|
||||
void LoadDependentAssets();
|
||||
void OnDeserialized();
|
||||
|
||||
using NodeContainer = AZStd::unordered_set<AZ::Entity*>;
|
||||
using ConnectionContainer = AZStd::vector<AZ::Entity*>;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace ScriptCanvas
|
||||
void OnWriteEnd(void* objectPtr) override
|
||||
{
|
||||
auto node = reinterpret_cast<Node*>(objectPtr);
|
||||
node->RebuildInternalState();
|
||||
node->OnDeserialize();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2616,6 +2616,11 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void Node::OnDeserialize()
|
||||
{
|
||||
RebuildInternalState();
|
||||
}
|
||||
|
||||
void Node::OnEndpointConnected(const Endpoint& endpoint)
|
||||
{
|
||||
const SlotId& currentSlotId = EndpointNotificationBus::GetCurrentBusId()->GetSlotId();
|
||||
|
||||
@@ -14,25 +14,23 @@
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/tuple.h>
|
||||
|
||||
#include <ScriptCanvas/CodeGen/NodeableCodegen.h>
|
||||
#include <ScriptCanvas/Core/Contracts/TypeContract.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
#include <ScriptCanvas/Core/DatumBus.h>
|
||||
#include <ScriptCanvas/Core/Endpoint.h>
|
||||
#include <ScriptCanvas/Core/SubgraphInterface.h>
|
||||
#include <ScriptCanvas/Core/ExecutionNotificationsBus.h>
|
||||
#include <ScriptCanvas/Core/GraphBus.h>
|
||||
#include <ScriptCanvas/Core/NodeBus.h>
|
||||
#include <ScriptCanvas/Core/SerializationListener.h>
|
||||
#include <ScriptCanvas/Core/Slot.h>
|
||||
#include <ScriptCanvas/Core/SubgraphInterface.h>
|
||||
#include <ScriptCanvas/Debugger/StatusBus.h>
|
||||
#include <ScriptCanvas/Debugger/ValidationEvents/ValidationEvent.h>
|
||||
#include <ScriptCanvas/Execution/ErrorBus.h>
|
||||
#include <ScriptCanvas/Execution/ExecutionBus.h>
|
||||
#include <ScriptCanvas/Variable/GraphVariable.h>
|
||||
#include <ScriptCanvas/Grammar/Primitives.h>
|
||||
#include <ScriptCanvas/Debugger/ValidationEvents/ValidationEvent.h>
|
||||
|
||||
#include <ScriptCanvas/CodeGen/NodeableCodegen.h>
|
||||
|
||||
#include <ScriptCanvas/Variable/GraphVariable.h>
|
||||
|
||||
#define SCRIPT_CANVAS_CALL_ON_INDEX_SEQUENCE(lambdaInterior)\
|
||||
int dummy[]{ 0, ( lambdaInterior , 0)... };\
|
||||
@@ -401,6 +399,7 @@ namespace ScriptCanvas
|
||||
, public DatumNotificationBus::Handler
|
||||
, public NodeRequestBus::Handler
|
||||
, public EndpointNotificationBus::MultiHandler
|
||||
, public SerializationListener
|
||||
{
|
||||
friend class Graph;
|
||||
friend class RuntimeComponent;
|
||||
@@ -472,7 +471,7 @@ namespace ScriptCanvas
|
||||
|
||||
public:
|
||||
|
||||
AZ_COMPONENT(Node, "{52B454AE-FA7E-4FE9-87D3-A1CAB235C691}");
|
||||
AZ_COMPONENT(Node, "{52B454AE-FA7E-4FE9-87D3-A1CAB235C691}", SerializationListener);
|
||||
static void Reflect(AZ::ReflectContext* reflection);
|
||||
|
||||
Node();
|
||||
@@ -821,6 +820,7 @@ namespace ScriptCanvas
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
void OnDeserialize() override;
|
||||
|
||||
virtual void OnReconfigurationBegin() {}
|
||||
virtual void OnReconfigurationEnd() {}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
class SerializationListener
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(SerializationListener, "{CA4EE281-30B3-4928-BCD8-9305CE75E463}");
|
||||
virtual ~SerializationListener() = 0 {}
|
||||
|
||||
virtual void OnSerializeBegin() {}
|
||||
virtual void OnSerializeEnd() {}
|
||||
|
||||
virtual void OnDeserialize() {}
|
||||
};
|
||||
|
||||
using SerializationListeners = AZStd::vector<SerializationListener*>;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
void BehaviorContextObject::OnReadBegin()
|
||||
void BehaviorContextObject::OnSerializeBegin()
|
||||
{
|
||||
if (!IsOwned())
|
||||
{
|
||||
@@ -25,18 +25,12 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void BehaviorContextObject::OnWriteEnd()
|
||||
{
|
||||
// Id Remapping invokes this method as well, not just serializing from an ObjectStream
|
||||
}
|
||||
|
||||
void BehaviorContextObject::Reflect(AZ::ReflectContext* reflection)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
|
||||
{
|
||||
serializeContext->Class<BehaviorContextObject>()
|
||||
->Version(0)
|
||||
->EventHandler<SerializeContextEventHandler>()
|
||||
->Field("m_flags", &BehaviorContextObject::m_flags)
|
||||
->Field("m_object", &BehaviorContextObject::m_object)
|
||||
;
|
||||
@@ -55,24 +49,11 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void BehaviorContextObject::SerializeContextEventHandler::OnReadBegin(void* classPtr)
|
||||
{
|
||||
BehaviorContextObject* object = reinterpret_cast<BehaviorContextObject*>(classPtr);
|
||||
object->OnReadBegin();
|
||||
}
|
||||
|
||||
void BehaviorContextObject::SerializeContextEventHandler::OnWriteEnd(void* classPtr)
|
||||
{
|
||||
BehaviorContextObject* object = reinterpret_cast<BehaviorContextObject*>(classPtr);
|
||||
object->OnWriteEnd();
|
||||
}
|
||||
|
||||
BehaviorContextObjectPtr BehaviorContextObject::CloneObject(const AZ::BehaviorClass& behaviorClass)
|
||||
{
|
||||
if (SystemRequestBus::HasHandlers())
|
||||
{
|
||||
AZStd::vector<char> buffer;
|
||||
|
||||
{
|
||||
bool wasOwned = IsOwned();
|
||||
m_flags |= Flags::Owned;
|
||||
@@ -87,7 +68,6 @@ namespace ScriptCanvas
|
||||
}
|
||||
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char>> readStream(&buffer);
|
||||
|
||||
BehaviorContextObject* newObject = CreateDefault(behaviorClass);
|
||||
AZ::Utils::LoadObjectFromStreamInPlace(readStream, (*newObject));
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace ScriptCanvas
|
||||
class BehaviorContextObject final
|
||||
{
|
||||
friend struct AZStd::IntrusivePtrCountPolicy<BehaviorContextObject>;
|
||||
friend class Datum;
|
||||
|
||||
public:
|
||||
AZ_TYPE_INFO(BehaviorContextObject, "{B735214D-5182-4536-B748-61EC83C1F007}");
|
||||
@@ -69,16 +70,6 @@ namespace ScriptCanvas
|
||||
Reference = 1 << 3,
|
||||
};
|
||||
|
||||
class SerializeContextEventHandler : public AZ::SerializeContext::IEventHandler
|
||||
{
|
||||
public:
|
||||
/// Called right before we start reading from the instance pointed by classPtr.
|
||||
void OnReadBegin(void* classPtr) override;
|
||||
|
||||
/// Called after we are done writing to the instance pointed by classPtr.
|
||||
void OnWriteEnd(void* classPtr) override;
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
static AZ::BehaviorObject InvokeConstructor(const AZ::BehaviorClass& behaviorClass, void* resultPtr, Args&&... args);
|
||||
|
||||
@@ -128,9 +119,7 @@ namespace ScriptCanvas
|
||||
|
||||
AZ_FORCE_INLINE bool IsOwned() const;
|
||||
|
||||
void OnReadBegin();
|
||||
|
||||
void OnWriteEnd();
|
||||
void OnSerializeBegin();
|
||||
|
||||
AZ_FORCE_INLINE void add_ref();
|
||||
|
||||
|
||||
@@ -602,13 +602,21 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void EBusEventHandler::OnWriteEnd()
|
||||
void EBusEventHandler::OnDeserialize()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
if (!m_ebus)
|
||||
{
|
||||
CreateHandler(m_ebusName);
|
||||
}
|
||||
|
||||
/// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super
|
||||
Node::OnDeserialize();
|
||||
}
|
||||
|
||||
void EBusEventHandler::OnWriteEnd()
|
||||
{
|
||||
OnDeserialize();
|
||||
}
|
||||
|
||||
NodeTypeIdentifier EBusEventHandler::GetOutputNodeType(const SlotId& slotId) const
|
||||
|
||||
@@ -138,6 +138,8 @@ namespace ScriptCanvas
|
||||
|
||||
void SetAutoConnectToGraphOwner(bool enabled);
|
||||
|
||||
void OnDeserialize();
|
||||
|
||||
void OnWriteEnd();
|
||||
|
||||
AZStd::string GetNodeName() const override
|
||||
|
||||
@@ -313,6 +313,7 @@ namespace ScriptCanvas
|
||||
}
|
||||
|
||||
PopulateNodeType();
|
||||
m_warnOnMissingFunction = true;
|
||||
}
|
||||
|
||||
bool Method::InitializeOverloaded([[maybe_unused]] const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName)
|
||||
@@ -739,10 +740,11 @@ namespace ScriptCanvas
|
||||
return TupleType{ nullptr, MethodType::Count, EventType::Count, nullptr };
|
||||
}
|
||||
|
||||
void Method::OnWriteEnd()
|
||||
void Method::OnDeserialize()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_warnOnMissingFunction = true;
|
||||
const AZ::BehaviorClass* bcClass{};
|
||||
const AZ::BehaviorMethod* method{};
|
||||
EventType eventType;
|
||||
@@ -758,13 +760,20 @@ namespace ScriptCanvas
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", !m_warnOnMissingFunction, "method node failed to deserialize properly");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_resultSlotIDs.empty())
|
||||
{
|
||||
m_resultSlotIDs.emplace_back(SlotId{});
|
||||
}
|
||||
|
||||
/// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super
|
||||
Node::OnDeserialize();
|
||||
}
|
||||
|
||||
void Method::OnWriteEnd()
|
||||
{
|
||||
OnDeserialize();
|
||||
}
|
||||
|
||||
bool Method::BranchesOnResult() const
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace AZ
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
|
||||
AZ::Outcome<void, AZStd::string> IsExposable(const AZ::BehaviorMethod& method);
|
||||
|
||||
Grammar::FunctionPrototype ToSignature(const AZ::BehaviorMethod& method);
|
||||
@@ -31,7 +30,8 @@ namespace ScriptCanvas
|
||||
{
|
||||
namespace Core
|
||||
{
|
||||
class Method : public Node
|
||||
class Method
|
||||
: public Node
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(Method, "{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF}", Node);
|
||||
@@ -107,6 +107,8 @@ namespace ScriptCanvas
|
||||
|
||||
SlotId GetBusSlotId() const;
|
||||
|
||||
void OnDeserialize();
|
||||
|
||||
void OnWriteEnd();
|
||||
|
||||
virtual bool IsMethodOverloaded() const { return false; }
|
||||
@@ -180,7 +182,7 @@ namespace ScriptCanvas
|
||||
AZStd::vector<SlotId> m_inputSlots;
|
||||
AZStd::vector<SlotId> m_resultSlotIDs;
|
||||
AZStd::recursive_mutex m_mutex; // post-serialization
|
||||
bool m_warnOnMissingFunction = true;
|
||||
bool m_warnOnMissingFunction = false;
|
||||
Method(const Method&) = delete;
|
||||
};
|
||||
|
||||
|
||||
@@ -397,20 +397,16 @@ namespace ScriptCanvas
|
||||
return signature;
|
||||
}
|
||||
|
||||
void MethodOverloaded::OnReadBegin()
|
||||
{
|
||||
}
|
||||
|
||||
void MethodOverloaded::OnReadEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void MethodOverloaded::OnWriteBegin()
|
||||
{
|
||||
SetWarnOnMissingFunction(false);
|
||||
}
|
||||
|
||||
void MethodOverloaded::OnWriteEnd()
|
||||
{
|
||||
OnDeserialize();
|
||||
}
|
||||
|
||||
void MethodOverloaded::OnDeserialize()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(GetMutex());
|
||||
|
||||
@@ -462,6 +458,9 @@ namespace ScriptCanvas
|
||||
}
|
||||
|
||||
SetWarnOnMissingFunction(true);
|
||||
|
||||
/// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super
|
||||
Node::OnDeserialize();
|
||||
}
|
||||
|
||||
void MethodOverloaded::SetupMethodData(const AZ::BehaviorMethod* behaviorMethod, const AZ::BehaviorClass* behaviorClass)
|
||||
|
||||
@@ -92,12 +92,13 @@ namespace ScriptCanvas
|
||||
Grammar::FunctionPrototype GetInputSignature() const;
|
||||
|
||||
// SerializeContextReadWriteHandler
|
||||
void OnReadBegin();
|
||||
void OnReadEnd();
|
||||
void OnReadBegin() {}
|
||||
void OnReadEnd() {}
|
||||
|
||||
void OnWriteBegin();
|
||||
void OnWriteEnd();
|
||||
////
|
||||
|
||||
void OnDeserialize() override;
|
||||
|
||||
void SetupMethodData(const AZ::BehaviorMethod* lookupMethod, const AZ::BehaviorClass* lookupClass);
|
||||
void ConfigureContracts();
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace AZ
|
||||
AZ_Assert(azrtti_typeid<decltype(outputDatum->m_datumLabel)>() == azrtti_typeid<decltype(label)>()
|
||||
, "m_datumLabel type changed and won't load properly");
|
||||
|
||||
result.Combine( ContinueLoadingFromJsonObjectField
|
||||
result.Combine(ContinueLoadingFromJsonObjectField
|
||||
( &label
|
||||
, azrtti_typeid<decltype(outputDatum->m_datumLabel)>()
|
||||
, inputValue
|
||||
@@ -95,6 +95,7 @@ namespace AZ
|
||||
Datum copy(scType, Datum::eOriginality::Original, AZStd::any_cast<void>(&storage), scType.GetAZType());
|
||||
copy.SetLabel(label);
|
||||
*outputDatum = copy;
|
||||
outputDatum->OnDeserialize();
|
||||
|
||||
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
|
||||
? "DatumSerializer Load finished loading Datum"
|
||||
@@ -124,7 +125,9 @@ namespace AZ
|
||||
( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "DatumSerializer Store used defaults for Datum");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const_cast<Datum*>(inputScriptDataPtr)->OnSerializeBegin();
|
||||
|
||||
JSR::ResultCode result(JSR::Tasks::WriteValue);
|
||||
outputValue.SetObject();
|
||||
|
||||
@@ -162,7 +165,7 @@ namespace AZ
|
||||
, inputScriptDataPtr->GetType().GetAZType()
|
||||
, context));
|
||||
} // datum storage end
|
||||
|
||||
|
||||
result.Combine(ContinueStoringToJsonObjectField
|
||||
( outputValue
|
||||
, "label"
|
||||
@@ -171,9 +174,9 @@ namespace AZ
|
||||
, azrtti_typeid<decltype(inputScriptDataPtr->m_datumLabel)>()
|
||||
, context));
|
||||
|
||||
const_cast<Datum*>(inputScriptDataPtr)->OnSerializeEnd();
|
||||
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
|
||||
? "DatumSerializer Store finished saving Datum"
|
||||
: "DatumSerializer Store failed to save Datum");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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/Core/SerializationListener.h>
|
||||
#include <ScriptCanvas/Core/GraphData.h>
|
||||
#include <ScriptCanvas/Serialization/GraphDataSerializer.h>
|
||||
|
||||
using namespace ScriptCanvas;
|
||||
|
||||
namespace GraphDataSerializerCpp
|
||||
{
|
||||
void CollectNodes(const GraphData::NodeContainer& container, SerializationListeners& listeners)
|
||||
{
|
||||
for (auto& nodeEntity : container)
|
||||
{
|
||||
if (nodeEntity)
|
||||
{
|
||||
if (auto listener = azrtti_cast<SerializationListener*>(AZ::EntityUtils::FindFirstDerivedComponent<Node>(nodeEntity)))
|
||||
{
|
||||
listeners.push_back(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(GraphDataSerializer, SystemAllocator, 0);
|
||||
|
||||
JsonSerializationResult::Result GraphDataSerializer::Load
|
||||
( void* outputValue
|
||||
, [[maybe_unused]] const Uuid& outputValueTypeId
|
||||
, const rapidjson::Value& inputValue
|
||||
, JsonDeserializerContext& context)
|
||||
{
|
||||
namespace JSR = JsonSerializationResult;
|
||||
|
||||
AZ_Assert(outputValueTypeId == azrtti_typeid<GraphData>()
|
||||
, "RuntimeVariableSerializer Load against output typeID that was not GraphData");
|
||||
AZ_Assert(outputValue, "RuntimeVariableSerializer Load against null output");
|
||||
context.GetMetadata().Add(SerializationListeners());
|
||||
JSR::ResultCode result(JSR::Tasks::ReadField);
|
||||
result.Combine(ContinueLoading(outputValue, outputValueTypeId, inputValue, context, ContinuationFlags::NoTypeSerializer));
|
||||
auto listeners = context.GetMetadata().Find<SerializationListeners>();
|
||||
AZ_Assert(listeners, "Failed to create SerializationListeners");
|
||||
GraphDataSerializerCpp::CollectNodes(reinterpret_cast<GraphData*>(outputValue)->m_nodes, *listeners);
|
||||
|
||||
for (auto listener : *listeners)
|
||||
{
|
||||
listener->OnDeserialize();
|
||||
}
|
||||
|
||||
reinterpret_cast<GraphData*>(outputValue)->OnDeserialized();
|
||||
|
||||
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
|
||||
? "GraphDataSerializer Load finished loading GraphData"
|
||||
: "GraphDataSerializer Load failed to load GraphData");
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result GraphDataSerializer::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<GraphData>()
|
||||
, "RuntimeVariableSerializer Store against output typeID that was not GraphData");
|
||||
AZ_Assert(inputValue, "RuntimeVariableSerializer Store against null output");
|
||||
context.GetMetadata().Add(SerializationListeners());
|
||||
auto listeners = context.GetMetadata().Find<SerializationListeners>();
|
||||
GraphDataSerializerCpp::CollectNodes(reinterpret_cast<const GraphData*>(inputValue)->m_nodes, *listeners);
|
||||
|
||||
for (auto listener : *listeners)
|
||||
{
|
||||
listener->OnSerializeBegin();
|
||||
}
|
||||
|
||||
JSR::ResultCode result(JSR::Tasks::WriteValue);
|
||||
result.Combine(ContinueStoring(outputValue, inputValue, defaultValue, valueTypeId, context, ContinuationFlags::NoTypeSerializer));
|
||||
|
||||
for (auto listener : *listeners)
|
||||
{
|
||||
listener->OnSerializeEnd();
|
||||
}
|
||||
|
||||
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
|
||||
? "GraphDataSerializer::Store finished storing GraphData"
|
||||
: "GraphDataSerializer::Store failed to store GraphData");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 GraphDataSerializer
|
||||
: public BaseJsonSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(GraphDataSerializer, "{2DFF5794-785F-4434-9314-52BB3EF1D00E}", 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
@@ -50,6 +50,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast<void>(&outputVariable->value), typeId, inputValue, "value", context));
|
||||
|
||||
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
|
||||
? "RuntimeVariableSerializer Load finished loading RuntimeVariable"
|
||||
: "RuntimeVariableSerializer Load failed to load RuntimeVariable");
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <AzCore/Component/EntityUtils.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
@@ -23,8 +22,9 @@
|
||||
#include <ScriptCanvas/Execution/ExecutionPerformanceTimer.h>
|
||||
#include <ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h>
|
||||
#include <ScriptCanvas/Execution/RuntimeComponent.h>
|
||||
#include <ScriptCanvas/Serialization/RuntimeVariableSerializer.h>
|
||||
#include <ScriptCanvas/Serialization/DatumSerializer.h>
|
||||
#include <ScriptCanvas/Serialization/GraphDataSerializer.h>
|
||||
#include <ScriptCanvas/Serialization/RuntimeVariableSerializer.h>
|
||||
#include <ScriptCanvas/SystemComponent.h>
|
||||
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace ScriptCanvas
|
||||
{
|
||||
void SystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
VersionData::Reflect(context);
|
||||
Nodeable::Reflect(context);
|
||||
ReflectLibraries(context);
|
||||
|
||||
@@ -88,13 +89,9 @@ namespace ScriptCanvas
|
||||
|
||||
if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast<AZ::JsonRegistrationContext*>(context))
|
||||
{
|
||||
jsonContext->Serializer<AZ::RuntimeVariableSerializer>()
|
||||
->HandlesType<RuntimeVariable>()
|
||||
;
|
||||
|
||||
jsonContext->Serializer<AZ::DatumSerializer>()
|
||||
->HandlesType<Datum>()
|
||||
;
|
||||
jsonContext->Serializer<AZ::DatumSerializer>()->HandlesType<Datum>();
|
||||
jsonContext->Serializer<AZ::GraphDataSerializer>()->HandlesType<GraphData>();
|
||||
jsonContext->Serializer<AZ::RuntimeVariableSerializer>()->HandlesType<RuntimeVariable>();
|
||||
}
|
||||
|
||||
#if defined(SC_EXECUTION_TRACE_ENABLED)
|
||||
|
||||
Reference in New Issue
Block a user