/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ScriptCanvasFileHandlingCpp { using namespace ScriptCanvas; void CollectNodes(const GraphData::NodeContainer& container, SerializationListeners& listeners) { for (auto& nodeEntity : container) { if (nodeEntity) { if (auto listener = azrtti_cast(AZ::EntityUtils::FindFirstDerivedComponent(nodeEntity))) { listeners.push_back(listener); } } } } } namespace ScriptCanvasEditor { AZ::Outcome 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(); auto loadResult = JSRU::LoadObjectFromStringByType ( &dataTarget , azrtti_typeid() , source , &settings); if (!loadResult.IsSuccess()) { return loadResult; } if (auto graphData = dataTarget.ModGraph()) { auto listeners = settings.m_metadata.Find(); 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 LoadFromFile(AZStd::string_view path) { namespace JSRU = AZ::JsonSerializationUtils; using namespace ScriptCanvas; auto fileStringOutcome = AZ::Utils::ReadFile(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)); } }