Integrating latest 47acbe8
This commit is contained in:
@@ -0,0 +1,767 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include <Editor/Include/ScriptCanvas/Components/GraphUpgrade.h>
|
||||
#include <Editor/Include/ScriptCanvas/Components/EditorGraph.h>
|
||||
|
||||
#include <Editor/Nodes/NodeDisplayUtils.h>
|
||||
#include <ScriptCanvas/Bus/RequestBus.h>
|
||||
#include <GraphCanvas/Components/SceneBus.h>
|
||||
#include <GraphCanvas/Components/EntitySaveDataBus.h>
|
||||
#include <ScriptCanvas/Core/ConnectionBus.h>
|
||||
#include <ScriptCanvas/GraphCanvas/MappingBus.h>
|
||||
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
|
||||
#include <GraphCanvas/GraphCanvasBus.h>
|
||||
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
|
||||
namespace Helpers
|
||||
{
|
||||
static AZStd::string ConnectionToText(ScriptCanvasEditor::Graph* graph, ScriptCanvas::Endpoint& from, ScriptCanvas::Endpoint& to)
|
||||
{
|
||||
AZ_Assert(graph, "A valid graph must be provided");
|
||||
|
||||
ScriptCanvas::Node* fromNode = graph->FindNode(from.GetNodeId());
|
||||
ScriptCanvas::Node* toNode = graph->FindNode(to.GetNodeId());
|
||||
|
||||
ScriptCanvas::Slot* fromSlot = fromNode ? fromNode->GetSlot(from.GetSlotId()) : nullptr;
|
||||
ScriptCanvas::Slot* toSlot = toNode ? toNode->GetSlot(to.GetSlotId()) : nullptr;
|
||||
|
||||
AZStd::string fromNodeName = fromNode ? fromNode->GetNodeName() : "Unknown Node";
|
||||
AZStd::string toNodeName = toNode ? toNode->GetNodeName() : "Unknown Node";
|
||||
|
||||
AZStd::string fromSlotName = fromSlot ? fromSlot->GetName() : "Unknown Slot";
|
||||
AZStd::string toSlotName = toSlot ? toSlot->GetName() : "Unknown Slot";
|
||||
|
||||
return AZStd::string::format("%s:%s to %s:%s", fromNodeName.c_str(), fromSlotName.c_str(), toNodeName.c_str(), toSlotName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Start::OnEnter()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
GraphCanvas::GraphCanvasRequestBus::BroadcastResult(graph->m_graphCanvasSceneEntity, &GraphCanvas::GraphCanvasRequests::CreateSceneAndActivate);
|
||||
|
||||
if (!graph->m_graphCanvasSceneEntity)
|
||||
{
|
||||
// TODO: Need to shut it all down.
|
||||
}
|
||||
|
||||
GraphCanvas::SceneRequestBus::Event(sm->m_graphCanvasGraphId, &GraphCanvas::SceneRequests::SetEditorId, ScriptCanvasEditor::AssetEditorId);
|
||||
}
|
||||
|
||||
void PreventUndo::OnEnter()
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::PushPreventUndoStateUpdate);
|
||||
}
|
||||
|
||||
void CollectData::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
sm->m_scriptCanvasId = graph->GetScriptCanvasId();
|
||||
|
||||
// Remove nodes that do not have components, these could be versioning artifacts
|
||||
// or nodes that are missing due to a missing gem
|
||||
AZStd::vector<AZ::Entity*> nodesToRemove;
|
||||
for (auto* node : graph->GetGraphData()->m_nodes)
|
||||
{
|
||||
if (node->GetComponents().empty())
|
||||
{
|
||||
AZ_TracePrintf("Script Canvas", "Removing node due to missing components: %s\nVerify that all gems that this script relies on are enabled\n", node->GetName().c_str());
|
||||
|
||||
nodesToRemove.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
for (AZ::Entity* nodeEntity : nodesToRemove)
|
||||
{
|
||||
graph->GetGraphData()->m_nodes.erase(nodeEntity);
|
||||
}
|
||||
|
||||
for (const AZ::EntityId& scriptCanvasNodeId : graph->GetNodes())
|
||||
{
|
||||
sm->m_assetSanitizationSet.insert(scriptCanvasNodeId);
|
||||
|
||||
ScriptCanvas::Node* scriptCanvasNode = graph->FindNode(scriptCanvasNodeId);
|
||||
|
||||
sm->m_graphCanvasGraphId = graph->GetGraphCanvasGraphId();
|
||||
|
||||
if (scriptCanvasNode)
|
||||
{
|
||||
sm->m_allNodes.insert(scriptCanvasNode);
|
||||
|
||||
if (scriptCanvasNode->IsDeprecated())
|
||||
{
|
||||
sm->m_deprecatedNodes.insert(scriptCanvasNode);
|
||||
}
|
||||
|
||||
if (scriptCanvasNode->IsOutOfDate(graph->GetVersion()))
|
||||
{
|
||||
sm->m_outOfDateNodes.insert(scriptCanvasNode);
|
||||
}
|
||||
|
||||
if (scriptCanvasNode->IsSanityCheckRequired())
|
||||
{
|
||||
sm->m_sanityCheckRequiredNodes.insert(scriptCanvasNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IState::ExitStatus CollectData::OnExit()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
|
||||
Log("---------------------------------------------------------------------\n");
|
||||
Log("Upgrading\n");
|
||||
Log("%d Nodes\n", sm->m_allNodes.size());
|
||||
|
||||
if (sm->m_deprecatedNodes.size() > 0)
|
||||
{
|
||||
Log("%d Deprecated\n", sm->m_deprecatedNodes.size());
|
||||
}
|
||||
|
||||
if (sm->m_outOfDateNodes.size() > 0)
|
||||
{
|
||||
Log("%d Out of Date\n", sm->m_outOfDateNodes.size());
|
||||
}
|
||||
|
||||
if (sm->m_sanityCheckRequiredNodes.size() > 0)
|
||||
{
|
||||
Log("%d Require Additional Checks\n", sm->m_sanityCheckRequiredNodes.size());
|
||||
}
|
||||
Log("---------------------------------------------------------------------\n");
|
||||
|
||||
return ExitStatus::Default;
|
||||
}
|
||||
|
||||
void PreRequisites::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
graph->m_variableDataModel.Activate(sm->m_scriptCanvasId);
|
||||
|
||||
graph->ConnectGraphCanvasBuses();
|
||||
|
||||
GraphCanvas::SceneRequestBus::Event(sm->m_graphCanvasGraphId, &GraphCanvas::SceneRequests::SignalLoadStart);
|
||||
|
||||
auto saveDataIter = graph->m_graphCanvasSaveData.find(graph->GetEntityId());
|
||||
|
||||
if (saveDataIter != graph->m_graphCanvasSaveData.end())
|
||||
{
|
||||
GraphCanvas::EntitySaveDataRequestBus::Event(sm->m_graphCanvasGraphId, &GraphCanvas::EntitySaveDataRequests::ReadSaveData, (*saveDataIter->second));
|
||||
}
|
||||
}
|
||||
|
||||
void UpgradeConnections::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
AZStd::vector< AZ::EntityId > connectionIds = graph->GetConnections();
|
||||
|
||||
for (const AZ::EntityId& connectionId : connectionIds)
|
||||
{
|
||||
ScriptCanvas::Endpoint scriptCanvasSourceEndpoint;
|
||||
ScriptCanvas::Endpoint scriptCanvasTargetEndpoint;
|
||||
|
||||
ScriptCanvas::ConnectionRequestBus::EventResult(scriptCanvasSourceEndpoint, connectionId, &ScriptCanvas::ConnectionRequests::GetSourceEndpoint);
|
||||
ScriptCanvas::ConnectionRequestBus::EventResult(scriptCanvasTargetEndpoint, connectionId, &ScriptCanvas::ConnectionRequests::GetTargetEndpoint);
|
||||
|
||||
Log("Upgrade Connection: %s\n", Helpers::ConnectionToText(graph, scriptCanvasSourceEndpoint, scriptCanvasTargetEndpoint).c_str());
|
||||
|
||||
AZ::EntityId graphCanvasSourceNode;
|
||||
|
||||
auto scriptCanvasIter = sm->m_scriptCanvasToGraphCanvasMapping.find(scriptCanvasSourceEndpoint.GetNodeId());
|
||||
|
||||
if (scriptCanvasIter != sm->m_scriptCanvasToGraphCanvasMapping.end())
|
||||
{
|
||||
graphCanvasSourceNode = scriptCanvasIter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", false, "Could not find ScriptCanvas Node with id %llu", static_cast<AZ::u64>(scriptCanvasSourceEndpoint.GetNodeId()));
|
||||
}
|
||||
|
||||
AZ::EntityId graphCanvasSourceSlotId;
|
||||
SlotMappingRequestBus::EventResult(graphCanvasSourceSlotId, graphCanvasSourceNode, &SlotMappingRequests::MapToGraphCanvasId, scriptCanvasSourceEndpoint.GetSlotId());
|
||||
|
||||
if (!graphCanvasSourceSlotId.IsValid())
|
||||
{
|
||||
// For the EBusHandler's I need to remap these to a different visual node.
|
||||
// Since multiple GraphCanvas nodes depict a single ScriptCanvas EBus node.
|
||||
if (EBusHandlerNodeDescriptorRequestBus::FindFirstHandler(graphCanvasSourceNode) != nullptr)
|
||||
{
|
||||
GraphCanvas::Endpoint graphCanvasEventEndpoint;
|
||||
EBusHandlerNodeDescriptorRequestBus::EventResult(graphCanvasEventEndpoint, graphCanvasSourceNode, &EBusHandlerNodeDescriptorRequests::MapSlotToGraphCanvasEndpoint, scriptCanvasSourceEndpoint.GetSlotId());
|
||||
|
||||
graphCanvasSourceSlotId = graphCanvasEventEndpoint.GetSlotId();
|
||||
}
|
||||
|
||||
if (!graphCanvasSourceSlotId.IsValid())
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", sm->m_deletedNodes.count(scriptCanvasSourceEndpoint.GetNodeId()) > 0, "Could not create connection(%s) for Node(%s).", connectionId.ToString().c_str(), scriptCanvasSourceEndpoint.GetNodeId().ToString().c_str());
|
||||
graph->DisconnectById(connectionId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
GraphCanvas::Endpoint graphCanvasTargetEndpoint;
|
||||
|
||||
scriptCanvasIter = sm->m_scriptCanvasToGraphCanvasMapping.find(scriptCanvasTargetEndpoint.GetNodeId());
|
||||
|
||||
if (scriptCanvasIter != sm->m_scriptCanvasToGraphCanvasMapping.end())
|
||||
{
|
||||
graphCanvasTargetEndpoint.m_nodeId = scriptCanvasIter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", false, "Could not find ScriptCanvas Node with id %llu", static_cast<AZ::u64>(scriptCanvasSourceEndpoint.GetNodeId()));
|
||||
}
|
||||
|
||||
SlotMappingRequestBus::EventResult(graphCanvasTargetEndpoint.m_slotId, graphCanvasTargetEndpoint.GetNodeId(), &SlotMappingRequests::MapToGraphCanvasId, scriptCanvasTargetEndpoint.GetSlotId());
|
||||
|
||||
if (!graphCanvasTargetEndpoint.IsValid())
|
||||
{
|
||||
// For the EBusHandler's I need to remap these to a different visual node.
|
||||
// Since multiple GraphCanvas nodes depict a single ScriptCanvas EBus node.
|
||||
if (EBusHandlerNodeDescriptorRequestBus::FindFirstHandler(graphCanvasTargetEndpoint.GetNodeId()) != nullptr)
|
||||
{
|
||||
EBusHandlerNodeDescriptorRequestBus::EventResult(graphCanvasTargetEndpoint, graphCanvasTargetEndpoint.GetNodeId(), &EBusHandlerNodeDescriptorRequests::MapSlotToGraphCanvasEndpoint, scriptCanvasTargetEndpoint.GetSlotId());
|
||||
}
|
||||
|
||||
if (!graphCanvasTargetEndpoint.IsValid())
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", sm->m_deletedNodes.count(scriptCanvasTargetEndpoint.GetNodeId()) > 0, "Could not create connection(%s) for Node(%s).", connectionId.ToString().c_str(), scriptCanvasTargetEndpoint.GetNodeId().ToString().c_str());
|
||||
graph->DisconnectById(connectionId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
AZ::EntityId graphCanvasConnectionId;
|
||||
GraphCanvas::SlotRequestBus::EventResult(graphCanvasConnectionId, graphCanvasSourceSlotId, &GraphCanvas::SlotRequests::DisplayConnectionWithEndpoint, graphCanvasTargetEndpoint);
|
||||
|
||||
if (graphCanvasConnectionId.IsValid())
|
||||
{
|
||||
AZStd::any* userData = nullptr;
|
||||
GraphCanvas::ConnectionRequestBus::EventResult(userData, graphCanvasConnectionId, &GraphCanvas::ConnectionRequests::GetUserData);
|
||||
|
||||
if (userData)
|
||||
{
|
||||
(*userData) = connectionId;
|
||||
|
||||
SceneMemberMappingConfigurationRequestBus::Event(graphCanvasConnectionId, &SceneMemberMappingConfigurationRequests::ConfigureMapping, connectionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VerifySaveDataVersion::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
GraphCanvas::SceneRequestBus::Event(graph->GetGraphCanvasGraphId(), &GraphCanvas::SceneRequests::ProcessEnableDisableQueue);
|
||||
|
||||
if (graph->m_graphCanvasSaveVersion != GraphCanvas::EntitySaveDataContainer::CurrentVersion)
|
||||
{
|
||||
for (auto saveDataPair : graph->m_graphCanvasSaveData)
|
||||
{
|
||||
auto graphCanvasIter = sm->m_scriptCanvasToGraphCanvasMapping.find(saveDataPair.first);
|
||||
graph->OnSaveDataDirtied(graphCanvasIter->second);
|
||||
}
|
||||
|
||||
graph->m_graphCanvasSaveVersion = GraphCanvas::EntitySaveDataContainer::CurrentVersion;
|
||||
sm->m_graphNeedsDirtying = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SanityChecks::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
if (!sm->m_sanityCheckRequiredNodes.empty())
|
||||
{
|
||||
sm->m_graphNeedsDirtying = true;
|
||||
}
|
||||
|
||||
for (auto node : sm->m_sanityCheckRequiredNodes)
|
||||
{
|
||||
if (node)
|
||||
{
|
||||
node->SanityCheckDynamicDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IState::ExitStatus SanityChecks::OnExit()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
|
||||
GraphCanvas::SceneRequestBus::Event(sm->m_graphCanvasGraphId, &GraphCanvas::SceneRequests::SignalLoadEnd);
|
||||
EditorGraphNotificationBus::Event(sm->m_scriptCanvasId, &EditorGraphNotifications::OnGraphCanvasSceneDisplayed);
|
||||
|
||||
return IState::ExitStatus::Default;
|
||||
}
|
||||
|
||||
void UpgradeScriptEvents::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
auto currentIter = graph->GetGraphData()->m_scriptEventAssets.begin();
|
||||
|
||||
while (currentIter != graph->GetGraphData()->m_scriptEventAssets.end())
|
||||
{
|
||||
if (sm->m_assetSanitizationSet.find(currentIter->first) == sm->m_assetSanitizationSet.end())
|
||||
{
|
||||
currentIter->second = {};
|
||||
currentIter = graph->GetGraphData()->m_scriptEventAssets.erase(currentIter);
|
||||
sm->m_graphNeedsDirtying = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
++currentIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FixLeakedData::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
// Fix up leaked data elements
|
||||
auto mapIter = graph->m_graphCanvasSaveData.begin();
|
||||
|
||||
while (mapIter != graph->m_graphCanvasSaveData.end())
|
||||
{
|
||||
// Deleted using the wrong id, which orphaned the SaveData. For now we want to go through and sanitize our save data to avoid keeping around a bunch
|
||||
// of old save data for no reason.
|
||||
//
|
||||
// Need to bypass our internal save data for graph canvas information
|
||||
if (sm->m_scriptCanvasToGraphCanvasMapping.find(mapIter->first) == sm->m_scriptCanvasToGraphCanvasMapping.end()
|
||||
&& mapIter->first != graph->GetEntityId())
|
||||
{
|
||||
delete mapIter->second;
|
||||
mapIter = graph->m_graphCanvasSaveData.erase(mapIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
++mapIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateOutOfDateNodes::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
AZStd::unordered_set< AZ::EntityId > graphCanvasNodesToDelete;
|
||||
|
||||
for (auto scriptCanvasNode : sm->m_outOfDateNodes)
|
||||
{
|
||||
graph->OnVersionConversionBegin((*scriptCanvasNode));
|
||||
|
||||
auto graphCanvasNodeId = sm->m_scriptCanvasToGraphCanvasMapping[scriptCanvasNode->GetEntityId()];
|
||||
ScriptCanvas::UpdateResult updateResult = scriptCanvasNode->UpdateNode();
|
||||
|
||||
graph->OnVersionConversionEnd((*scriptCanvasNode));
|
||||
|
||||
switch (updateResult)
|
||||
{
|
||||
case ScriptCanvas::UpdateResult::DeleteNode:
|
||||
{
|
||||
sm->m_graphNeedsDirtying = true;
|
||||
sm->m_deletedNodes.insert(scriptCanvasNode->GetEntityId());
|
||||
graphCanvasNodesToDelete.insert(graphCanvasNodeId);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
sm->m_graphNeedsDirtying = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!graphCanvasNodesToDelete.empty())
|
||||
{
|
||||
for (auto& nodeId : sm->m_deletedNodes)
|
||||
{
|
||||
ScriptCanvas::Node* node = graph->FindNode(nodeId);
|
||||
if (node)
|
||||
{
|
||||
Log("Deleted: %s\n", node->GetNodeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
GraphCanvas::SceneRequestBus::Event(sm->m_graphCanvasGraphId, &GraphCanvas::SceneRequests::Delete, graphCanvasNodesToDelete);
|
||||
}
|
||||
}
|
||||
|
||||
void ReplaceDeprecatedConnections::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
// Delete underlying data connections.
|
||||
for (auto remapConnection : sm->m_replacementConnections)
|
||||
{
|
||||
graph->RemoveConnection(remapConnection.first);
|
||||
}
|
||||
|
||||
// Recreate connections in a separate pass to avoid triggering display updates for invalid slot ids.
|
||||
for (auto remapConnection : sm->m_replacementConnections)
|
||||
{
|
||||
for (auto newEndpointPair : remapConnection.second)
|
||||
{
|
||||
if (newEndpointPair.first.IsValid() && newEndpointPair.second.IsValid())
|
||||
{
|
||||
graph->ConnectByEndpoint(newEndpointPair.first, newEndpointPair.second);
|
||||
|
||||
Log("Replaced Connection: %s\n", Helpers::ConnectionToText(graph, newEndpointPair.first, newEndpointPair.second).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReplaceDeprecatedNodes::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
for (auto& node : sm->m_deprecatedNodes)
|
||||
{
|
||||
ScriptCanvas::NodeConfiguration nodeConfig = node->GetReplacementNodeConfiguration();
|
||||
if (nodeConfig.IsValid())
|
||||
{
|
||||
auto nodeOutcome = graph->ReplaceNodeByConfig(node, nodeConfig, sm->m_replacementConnections);
|
||||
if (nodeOutcome.IsSuccess())
|
||||
{
|
||||
sm->m_allNodes.erase(node);
|
||||
sm->m_outOfDateNodes.erase(node);
|
||||
sm->m_sanityCheckRequiredNodes.erase(node);
|
||||
|
||||
sm->m_graphNeedsDirtying = true;
|
||||
auto replacedNode = nodeOutcome.GetValue();
|
||||
|
||||
sm->m_allNodes.insert(replacedNode);
|
||||
|
||||
if (replacedNode->IsOutOfDate(graph->GetVersion()))
|
||||
{
|
||||
sm->m_outOfDateNodes.insert(replacedNode);
|
||||
}
|
||||
|
||||
if (replacedNode->IsSanityCheckRequired())
|
||||
{
|
||||
sm->m_sanityCheckRequiredNodes.insert(replacedNode);
|
||||
}
|
||||
|
||||
Log("Replaced node (%s)\n", replacedNode->GetNodeName().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BuildGraphCanvasMapping::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
for (auto& scriptCanvasNode : sm->m_allNodes)
|
||||
{
|
||||
auto scriptCanvasNodeId = scriptCanvasNode->GetEntityId();
|
||||
|
||||
AZ::EntityId graphCanvasNodeId = Nodes::DisplayScriptCanvasNode(sm->m_graphCanvasGraphId, scriptCanvasNode);
|
||||
sm->m_scriptCanvasToGraphCanvasMapping[scriptCanvasNodeId] = graphCanvasNodeId;
|
||||
|
||||
auto saveDataIter = graph->m_graphCanvasSaveData.find(scriptCanvasNodeId);
|
||||
|
||||
if (saveDataIter != graph->m_graphCanvasSaveData.end())
|
||||
{
|
||||
GraphCanvas::EntitySaveDataRequestBus::Event(graphCanvasNodeId, &GraphCanvas::EntitySaveDataRequests::ReadSaveData, (*saveDataIter->second));
|
||||
}
|
||||
|
||||
AZ::Vector2 position;
|
||||
GraphCanvas::GeometryRequestBus::EventResult(position, graphCanvasNodeId, &GraphCanvas::GeometryRequests::GetPosition);
|
||||
|
||||
GraphCanvas::SceneRequestBus::Event(sm->m_graphCanvasGraphId, &GraphCanvas::SceneRequests::AddNode, graphCanvasNodeId, position, false);
|
||||
|
||||
// If the node is deprecated, we want to stomp whatever style it had saved and apply the deprecated style
|
||||
if (scriptCanvasNode->IsDeprecated())
|
||||
{
|
||||
Log("Marking node deprecated: %s\n", scriptCanvasNode->GetNodeName().c_str());
|
||||
GraphCanvas::NodeTitleRequestBus::Event(graphCanvasNodeId, &GraphCanvas::NodeTitleRequests::SetPaletteOverride, "DeprecatedNodeTitlePalette");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParseGraph::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
ScriptCanvas::ValidationResults validationResults;
|
||||
|
||||
// Disable the s_saveRawTranslationOuputToFile CVar during Parse (not needed for upgrade) and restore to its set value after
|
||||
bool saveRawTranslationOuputToFile = ScriptCanvas::Grammar::s_saveRawTranslationOuputToFile;
|
||||
ScriptCanvas::Grammar::s_saveRawTranslationOuputToFile = false;
|
||||
|
||||
graph->Parse(validationResults);
|
||||
|
||||
ScriptCanvas::Grammar::s_saveRawTranslationOuputToFile = saveRawTranslationOuputToFile;
|
||||
|
||||
if (validationResults.HasResults())
|
||||
{
|
||||
for (auto& err : validationResults.GetEvents())
|
||||
{
|
||||
// Register this graph as needing manual updates
|
||||
AZ::Interface<IUpgradeRequests>::Get()->GraphNeedsManualUpgrade(sm->m_asset.GetId());
|
||||
|
||||
Log("%s: %s\n", err->GetIdentifier().c_str(), err->GetDescription().data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreUndo::Run()
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::PopPreventUndoStateUpdate);
|
||||
}
|
||||
|
||||
void Finalize::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
if (sm->m_graphNeedsDirtying)
|
||||
{
|
||||
graph->SignalDirty();
|
||||
}
|
||||
|
||||
graph->MarkVersion();
|
||||
}
|
||||
|
||||
void DisplayReport::Run()
|
||||
{
|
||||
Log("Upgrade Complete\n\n\n");
|
||||
}
|
||||
|
||||
void Skip::Run()
|
||||
{
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
|
||||
Log("Up to date (skipped)\n");
|
||||
}
|
||||
|
||||
// Transitions
|
||||
int Start::EvaluateTransition()
|
||||
{
|
||||
return PreventUndo::StateID();
|
||||
}
|
||||
|
||||
int PreventUndo::EvaluateTransition()
|
||||
{
|
||||
return PreRequisites::StateID();
|
||||
}
|
||||
|
||||
int PreRequisites::EvaluateTransition()
|
||||
{
|
||||
return CollectData::StateID();
|
||||
}
|
||||
|
||||
int CollectData::EvaluateTransition()
|
||||
{
|
||||
return ReplaceDeprecatedNodes::StateID();
|
||||
}
|
||||
|
||||
int ReplaceDeprecatedNodes::EvaluateTransition()
|
||||
{
|
||||
return BuildGraphCanvasMapping::StateID();
|
||||
}
|
||||
|
||||
int BuildGraphCanvasMapping::EvaluateTransition()
|
||||
{
|
||||
return ReplaceDeprecatedConnections::StateID();
|
||||
}
|
||||
|
||||
int ReplaceDeprecatedConnections::EvaluateTransition()
|
||||
{
|
||||
return UpdateOutOfDateNodes::StateID();
|
||||
}
|
||||
|
||||
int UpdateOutOfDateNodes::EvaluateTransition()
|
||||
{
|
||||
return UpgradeConnections::StateID();
|
||||
}
|
||||
|
||||
int UpgradeConnections::EvaluateTransition()
|
||||
{
|
||||
return FixLeakedData::StateID();
|
||||
}
|
||||
|
||||
int FixLeakedData::EvaluateTransition()
|
||||
{
|
||||
return UpgradeScriptEvents::StateID();
|
||||
}
|
||||
|
||||
int UpgradeScriptEvents::EvaluateTransition()
|
||||
{
|
||||
return SanityChecks::StateID();
|
||||
}
|
||||
|
||||
int SanityChecks::EvaluateTransition()
|
||||
{
|
||||
return VerifySaveDataVersion::StateID();
|
||||
}
|
||||
|
||||
int VerifySaveDataVersion::EvaluateTransition()
|
||||
{
|
||||
return RestoreUndo::StateID();
|
||||
}
|
||||
|
||||
int RestoreUndo::EvaluateTransition()
|
||||
{
|
||||
return Finalize::StateID();
|
||||
}
|
||||
|
||||
int Finalize::EvaluateTransition()
|
||||
{
|
||||
return ParseGraph::StateID();
|
||||
}
|
||||
|
||||
int ParseGraph::EvaluateTransition()
|
||||
{
|
||||
return DisplayReport::StateID();
|
||||
}
|
||||
|
||||
int DisplayReport::EvaluateTransition()
|
||||
{
|
||||
return EXIT_STATE_ID;
|
||||
}
|
||||
|
||||
int Skip::EvaluateTransition()
|
||||
{
|
||||
return EXIT_STATE_ID;
|
||||
}
|
||||
//
|
||||
|
||||
|
||||
#define RegisterState(stateName) m_states.emplace_back(new stateName(this));
|
||||
|
||||
EditorGraphUpgradeMachine::EditorGraphUpgradeMachine(Graph* graph)
|
||||
: m_graph(graph)
|
||||
{
|
||||
RegisterState(Start);
|
||||
RegisterState(PreRequisites);
|
||||
RegisterState(PreventUndo);
|
||||
RegisterState(CollectData);
|
||||
RegisterState(ReplaceDeprecatedNodes);
|
||||
RegisterState(ReplaceDeprecatedConnections);
|
||||
RegisterState(VerifySaveDataVersion);
|
||||
RegisterState(SanityChecks);
|
||||
RegisterState(UpgradeScriptEvents);
|
||||
RegisterState(UpdateOutOfDateNodes);
|
||||
RegisterState(UpgradeConnections);
|
||||
RegisterState(BuildGraphCanvasMapping);
|
||||
RegisterState(FixLeakedData);
|
||||
RegisterState(RestoreUndo);
|
||||
RegisterState(Finalize);
|
||||
RegisterState(DisplayReport);
|
||||
RegisterState(Skip);
|
||||
RegisterState(ParseGraph);
|
||||
}
|
||||
|
||||
void EditorGraphUpgradeMachine::SetAsset(const AZ::Data::Asset<AZ::Data::AssetData>& asset)
|
||||
{
|
||||
if (m_asset != asset)
|
||||
{
|
||||
m_asset = asset;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorGraphUpgradeMachine::OnComplete(IState::ExitStatus exitStatus)
|
||||
{
|
||||
UpgradeNotifications::Bus::Broadcast(&UpgradeNotifications::OnGraphUpgradeComplete, m_asset, exitStatus == IState::ExitStatus::Skipped);
|
||||
|
||||
m_asset = {};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// State Machine Internals
|
||||
|
||||
void StateMachine::OnSystemTick()
|
||||
{
|
||||
IState::ExitStatus exitStatus = IState::ExitStatus::Default;
|
||||
|
||||
if (m_currentState)
|
||||
{
|
||||
m_currentState->Run();
|
||||
|
||||
int targetState = m_currentState->EvaluateTransition();
|
||||
if (targetState != IState::EXIT_STATE_ID)
|
||||
{
|
||||
exitStatus = m_currentState->Exit();
|
||||
|
||||
auto state = AZStd::find_if(m_states.begin(), m_states.end(), [targetState](AZStd::shared_ptr<IState>& state) { if (state->GetStateId() == targetState) { return true; } return false; });
|
||||
|
||||
if (state != m_states.end())
|
||||
{
|
||||
m_currentState = *state;
|
||||
m_currentState->Enter();
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "Target State ID: %d Not Registered (From: %s)", targetState, m_currentState->GetName());
|
||||
m_currentState = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exitStatus = m_currentState->Exit();
|
||||
m_currentState = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_currentState)
|
||||
{
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
|
||||
OnComplete(exitStatus);
|
||||
}
|
||||
}
|
||||
|
||||
void StateMachine::Run(int startStateID)
|
||||
{
|
||||
auto startState = AZStd::find_if(m_states.begin(), m_states.end(), [startStateID](AZStd::shared_ptr<IState>& state) { if (state->GetStateId() == startStateID) { return true; } return false; });
|
||||
if (startState != m_states.end())
|
||||
{
|
||||
m_currentState = *startState;
|
||||
|
||||
m_currentState->Enter();
|
||||
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user