You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.5 KiB
C++
130 lines
4.5 KiB
C++
/*
|
|
* 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/IO/FileIO.h>
|
|
#include <AzCore/IO/GenericStreams.h>
|
|
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
|
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
|
|
#include <AzCore/Serialization/Json/JsonUtils.h>
|
|
#include <AzCore/Serialization/SerializeContext.h>
|
|
#include <AzCore/Serialization/Utils.h>
|
|
#include <AzCore/Utils/Utils.h>
|
|
#include <AzCore/std/string/string_view.h>
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
|
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
|
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
|
|
#include <ScriptCanvas/Components/EditorGraph.h>
|
|
#include <ScriptCanvas/Core/SerializationListener.h>
|
|
|
|
namespace ScriptCanvasFileHandlingCpp
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
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 ScriptCanvasEditor
|
|
{
|
|
AZ::Outcome<void, AZStd::string> LoadDataFromJson
|
|
( ScriptCanvas::ScriptCanvasData& dataTarget
|
|
, AZStd::string_view source
|
|
, AZ::SerializeContext& serializeContext)
|
|
{
|
|
namespace JSRU = AZ::JsonSerializationUtils;
|
|
using namespace ScriptCanvas;
|
|
|
|
AZ::JsonDeserializerSettings settings;
|
|
settings.m_serializeContext = &serializeContext;
|
|
settings.m_metadata.Create<SerializationListeners>();
|
|
|
|
auto loadResult = JSRU::LoadObjectFromStringByType
|
|
( &dataTarget
|
|
, azrtti_typeid<ScriptCanvasData>()
|
|
, source
|
|
, &settings);
|
|
|
|
if (!loadResult.IsSuccess())
|
|
{
|
|
return loadResult;
|
|
}
|
|
|
|
if (auto graphData = dataTarget.ModGraph())
|
|
{
|
|
auto listeners = settings.m_metadata.Find<SerializationListeners>();
|
|
AZ_Assert(listeners, "Failed to find SerializationListeners");
|
|
|
|
ScriptCanvasFileHandlingCpp::CollectNodes(graphData->GetGraphData()->m_nodes, *listeners);
|
|
|
|
for (auto listener : *listeners)
|
|
{
|
|
listener->OnDeserialize();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return AZ::Failure(AZStd::string("Failed to find graph data after loading source"));
|
|
}
|
|
|
|
return AZ::Success();
|
|
}
|
|
|
|
AZ::Outcome<ScriptCanvasEditor::SourceHandle, AZStd::string> LoadFromFile(AZStd::string_view path)
|
|
{
|
|
namespace JSRU = AZ::JsonSerializationUtils;
|
|
using namespace ScriptCanvas;
|
|
|
|
auto fileStringOutcome = AZ::Utils::ReadFile<AZStd::string>(path);
|
|
if (!fileStringOutcome)
|
|
{
|
|
return AZ::Failure(fileStringOutcome.TakeError());
|
|
}
|
|
|
|
const auto& asString = fileStringOutcome.GetValue();
|
|
DataPtr scriptCanvasData = Graph::Create();
|
|
|
|
AZ::SerializeContext* serializeContext = nullptr;
|
|
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
|
|
if (!serializeContext)
|
|
{
|
|
return AZ::Failure(AZStd::string("no serialize context available to properly parse source file"));
|
|
}
|
|
|
|
// attempt JSON deserialization...
|
|
auto jsonResult = LoadDataFromJson(*scriptCanvasData, AZStd::string_view{ asString.begin(), asString.size() }, *serializeContext);
|
|
if (!jsonResult.IsSuccess())
|
|
{
|
|
// ...try legacy xml as a failsafe
|
|
AZ::IO::ByteContainerStream byteStream(&asString);
|
|
if (!AZ::Utils::LoadObjectFromStreamInPlace
|
|
( byteStream
|
|
, *scriptCanvasData
|
|
, serializeContext
|
|
, AZ::ObjectStream::FilterDescriptor(nullptr, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)))
|
|
{
|
|
return AZ::Failure(AZStd::string::format("XML and JSON load attempts failed: %s", jsonResult.GetError().c_str()));
|
|
}
|
|
}
|
|
|
|
return AZ::Success(ScriptCanvasEditor::SourceHandle(scriptCanvasData, {}, path));
|
|
}
|
|
}
|