|
@@ -512,7 +512,7 @@ namespace ScriptCanvasEditor
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- bool Graph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, AZStd::unordered_map<ScriptCanvas::SlotId, AZStd::vector<ScriptCanvas::SlotId>>& outSlotIdMap)
|
|
|
|
|
|
+ bool Graph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport)
|
|
{
|
|
{
|
|
auto findReplacementMatch = [](const ScriptCanvas::Slot* oldSlot, const AZStd::vector<const ScriptCanvas::Slot*>& newSlots)->ScriptCanvas::SlotId
|
|
auto findReplacementMatch = [](const ScriptCanvas::Slot* oldSlot, const AZStd::vector<const ScriptCanvas::Slot*>& newSlots)->ScriptCanvas::SlotId
|
|
{
|
|
{
|
|
@@ -529,14 +529,14 @@ namespace ScriptCanvasEditor
|
|
return {};
|
|
return {};
|
|
};
|
|
};
|
|
|
|
|
|
- oldNode->CustomizeReplacementNode(newNode, outSlotIdMap);
|
|
|
|
-
|
|
|
|
if (!newNode)
|
|
if (!newNode)
|
|
{
|
|
{
|
|
AZ_Warning("ScriptCanvas", false, "Replacement node can not be null.");
|
|
AZ_Warning("ScriptCanvas", false, "Replacement node can not be null.");
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ oldNode->CustomizeReplacementNode(newNode, nodeUpdateSlotReport.m_oldSlotsToNewSlots);
|
|
|
|
+
|
|
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> slotNameMap = oldNode->GetReplacementSlotsMap();
|
|
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> slotNameMap = oldNode->GetReplacementSlotsMap();
|
|
|
|
|
|
const auto newSlots = newNode->GetAllSlots();
|
|
const auto newSlots = newNode->GetAllSlots();
|
|
@@ -544,16 +544,19 @@ namespace ScriptCanvasEditor
|
|
bool usingDefaults = true;
|
|
bool usingDefaults = true;
|
|
size_t defaultMatchesFound = 0;
|
|
size_t defaultMatchesFound = 0;
|
|
|
|
|
|
|
|
+ auto& oldSlotsToNewSlots = nodeUpdateSlotReport.m_oldSlotsToNewSlots;
|
|
|
|
+
|
|
for (auto oldSlot : oldSlots)
|
|
for (auto oldSlot : oldSlots)
|
|
{
|
|
{
|
|
const ScriptCanvas::SlotId oldSlotId = oldSlot->GetId();
|
|
const ScriptCanvas::SlotId oldSlotId = oldSlot->GetId();
|
|
const AZStd::string oldSlotName = oldSlot->GetName();
|
|
const AZStd::string oldSlotName = oldSlot->GetName();
|
|
- auto slotIdsIter = outSlotIdMap.find(oldSlotId);
|
|
|
|
|
|
+
|
|
|
|
+ auto slotIdsIter = oldSlotsToNewSlots.find(oldSlotId);
|
|
auto slotNamesIter = slotNameMap.find(oldSlotName);
|
|
auto slotNamesIter = slotNameMap.find(oldSlotName);
|
|
// For old node slot remapping, we should get:
|
|
// For old node slot remapping, we should get:
|
|
// 1. if old slot name is not static, we should find the mapping in user provided slot id map
|
|
// 1. if old slot name is not static, we should find the mapping in user provided slot id map
|
|
// 2. if old slot name is static, we should find the mapping in codegen generated map (case 1 can override case 2)
|
|
// 2. if old slot name is static, we should find the mapping in codegen generated map (case 1 can override case 2)
|
|
- if (slotIdsIter != outSlotIdMap.end())
|
|
|
|
|
|
+ if (slotIdsIter != oldSlotsToNewSlots.end())
|
|
{
|
|
{
|
|
for (auto newSlotId : slotIdsIter->second)
|
|
for (auto newSlotId : slotIdsIter->second)
|
|
{
|
|
{
|
|
@@ -581,9 +584,10 @@ namespace ScriptCanvasEditor
|
|
if (!newSlotName.empty())
|
|
if (!newSlotName.empty())
|
|
{
|
|
{
|
|
auto newSlot = newNode->GetSlotByName(newSlotName);
|
|
auto newSlot = newNode->GetSlotByName(newSlotName);
|
|
|
|
+
|
|
if (!newSlot)
|
|
if (!newSlot)
|
|
{
|
|
{
|
|
- AZ_Warning("ScriptCanvas", false, "Failed to find slot with name %s in replacement Node(%s).", newSlotName.c_str(), newNode->GetNodeName().c_str());
|
|
|
|
|
|
+ AZ_Warning("ScriptCanvas", false, "Failed to find slot with name %s in replacement Node (%s).", newSlotName.c_str(), newNode->GetNodeName().c_str());
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
else if (newSlot && oldSlot->GetType() != newSlot->GetType())
|
|
else if (newSlot && oldSlot->GetType() != newSlot->GetType())
|
|
@@ -591,10 +595,11 @@ namespace ScriptCanvasEditor
|
|
AZ_Warning("ScriptCanvas", false, "Failed to map deprecated Node (%s) Slot (%s) to replacement Node (%s) Slot (%s).", oldNode->GetNodeName().c_str(), oldSlot->GetName().c_str(), newNode->GetNodeName().c_str(), newSlot->GetName().c_str());
|
|
AZ_Warning("ScriptCanvas", false, "Failed to map deprecated Node (%s) Slot (%s) to replacement Node (%s) Slot (%s).", oldNode->GetNodeName().c_str(), oldSlot->GetName().c_str(), newNode->GetNodeName().c_str(), newSlot->GetName().c_str());
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+
|
|
newSlotIds.push_back(newSlot->GetId());
|
|
newSlotIds.push_back(newSlot->GetId());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- outSlotIdMap.emplace(oldSlot->GetId(), newSlotIds);
|
|
|
|
|
|
+ oldSlotsToNewSlots.emplace(oldSlot->GetId(), newSlotIds);
|
|
}
|
|
}
|
|
else if (slotNameMap.empty())
|
|
else if (slotNameMap.empty())
|
|
{
|
|
{
|
|
@@ -605,7 +610,7 @@ namespace ScriptCanvasEditor
|
|
{
|
|
{
|
|
++defaultMatchesFound;
|
|
++defaultMatchesFound;
|
|
AZStd::vector<ScriptCanvas::SlotId> slotIds{ newSlotId };
|
|
AZStd::vector<ScriptCanvas::SlotId> slotIds{ newSlotId };
|
|
- outSlotIdMap.emplace(oldSlot->GetId(), slotIds);
|
|
|
|
|
|
+ oldSlotsToNewSlots.emplace(oldSlot->GetId(), slotIds);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -615,7 +620,7 @@ namespace ScriptCanvasEditor
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (usingDefaults && defaultMatchesFound != oldSlots.size())
|
|
|
|
|
|
+ if (usingDefaults && oldSlotsToNewSlots.size() != oldSlots.size())
|
|
{
|
|
{
|
|
AZ_Warning("ScriptCanvas", false, "Failed to remap deprecated Node(%s) not all old slots were present in the new node.", oldNode->GetNodeName().c_str());
|
|
AZ_Warning("ScriptCanvas", false, "Failed to remap deprecated Node(%s) not all old slots were present in the new node.", oldNode->GetNodeName().c_str());
|
|
}
|
|
}
|
|
@@ -690,8 +695,10 @@ namespace ScriptCanvasEditor
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- AZ::Outcome<ScriptCanvas::Node*> Graph::ReplaceNodeByConfig(ScriptCanvas::Node* oldNode, const ScriptCanvas::NodeConfiguration& nodeConfig,
|
|
|
|
- ScriptCanvas::ReplacementConnectionMap& remapConnections)
|
|
|
|
|
|
+ AZ::Outcome<ScriptCanvas::Node*> Graph::ReplaceNodeByConfig
|
|
|
|
+ ( ScriptCanvas::Node* oldNode
|
|
|
|
+ , const ScriptCanvas::NodeConfiguration& nodeConfig
|
|
|
|
+ , ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport)
|
|
{
|
|
{
|
|
auto nodeEntity = oldNode->GetEntity();
|
|
auto nodeEntity = oldNode->GetEntity();
|
|
if (!nodeEntity)
|
|
if (!nodeEntity)
|
|
@@ -731,8 +738,8 @@ namespace ScriptCanvasEditor
|
|
AddNode(newNode->GetEntityId());
|
|
AddNode(newNode->GetEntityId());
|
|
ScriptCanvas::NodeUtils::InitializeNode(newNode, nodeConfig);
|
|
ScriptCanvas::NodeUtils::InitializeNode(newNode, nodeConfig);
|
|
|
|
|
|
- AZStd::unordered_map<ScriptCanvas::SlotId, AZStd::vector<ScriptCanvas::SlotId>> slotIdMap;
|
|
|
|
- rollbackRequired = !SanityCheckNodeReplacement(oldNode, newNode, slotIdMap);
|
|
|
|
|
|
+ rollbackRequired = !SanityCheckNodeReplacement(oldNode, newNode, nodeUpdateSlotReport);
|
|
|
|
+ auto& slotIdMap = nodeUpdateSlotReport.m_oldSlotsToNewSlots;
|
|
|
|
|
|
if (rollbackRequired)
|
|
if (rollbackRequired)
|
|
{
|
|
{
|
|
@@ -748,25 +755,15 @@ namespace ScriptCanvasEditor
|
|
else
|
|
else
|
|
{
|
|
{
|
|
nodeEntity->Activate();
|
|
nodeEntity->Activate();
|
|
-
|
|
|
|
newNode->SignalReconfigurationBegin();
|
|
newNode->SignalReconfigurationBegin();
|
|
-
|
|
|
|
newNode->SetNodeDisabledFlag(oldNode->GetNodeDisabledFlag());
|
|
newNode->SetNodeDisabledFlag(oldNode->GetNodeDisabledFlag());
|
|
|
|
+
|
|
for (auto slotIdIter : slotIdMap)
|
|
for (auto slotIdIter : slotIdMap)
|
|
{
|
|
{
|
|
ScriptCanvas::Slot* oldSlot = oldNode->GetSlot(slotIdIter.first);
|
|
ScriptCanvas::Slot* oldSlot = oldNode->GetSlot(slotIdIter.first);
|
|
const ScriptCanvas::Endpoint oldEndpoint{ nodeEntity->GetId(), oldSlot->GetId() };
|
|
const ScriptCanvas::Endpoint oldEndpoint{ nodeEntity->GetId(), oldSlot->GetId() };
|
|
if (slotIdIter.second.size() == 0)
|
|
if (slotIdIter.second.size() == 0)
|
|
{
|
|
{
|
|
- // If remap id is empty, then we should just cache the old slot connection for delete
|
|
|
|
- if (oldSlot->IsInput())
|
|
|
|
- {
|
|
|
|
- ScriptCanvas::VersioningUtils::CreateRemapConnectionsForTargetEndpoint(*this, oldEndpoint, ScriptCanvas::Endpoint(), remapConnections);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- ScriptCanvas::VersioningUtils::CreateRemapConnectionsForSourceEndpoint(*this, oldEndpoint, ScriptCanvas::Endpoint(), remapConnections);
|
|
|
|
- }
|
|
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -808,35 +805,11 @@ namespace ScriptCanvasEditor
|
|
|
|
|
|
ScriptCanvas::VersioningUtils::CopyOldValueToDataSlot(newSlot, oldSlot->GetVariableReference(), oldSlot->FindDatum());
|
|
ScriptCanvas::VersioningUtils::CopyOldValueToDataSlot(newSlot, oldSlot->GetVariableReference(), oldSlot->FindDatum());
|
|
}
|
|
}
|
|
-
|
|
|
|
- // if old slot is visible, we need to check its connections for remapping
|
|
|
|
- if (oldSlot->IsVisible())
|
|
|
|
- {
|
|
|
|
- ScriptCanvas::Endpoint newEndpoint;
|
|
|
|
- if (newSlot)
|
|
|
|
- {
|
|
|
|
- newEndpoint = { nodeEntity->GetId(), newSlot->GetId() };
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- AZ_Warning("ScriptCanvas", false, "Invalid slot! Unable to create new connection for Node (%s).", newNode->GetNodeName().c_str());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (oldSlot->IsInput())
|
|
|
|
- {
|
|
|
|
- ScriptCanvas::VersioningUtils::CreateRemapConnectionsForTargetEndpoint(*this, oldEndpoint, newEndpoint, remapConnections);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- ScriptCanvas::VersioningUtils::CreateRemapConnectionsForSourceEndpoint(*this, oldEndpoint, newEndpoint, remapConnections);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- delete oldNode;
|
|
|
|
|
|
|
|
|
|
+ delete oldNode;
|
|
newNode->SignalReconfigurationEnd();
|
|
newNode->SignalReconfigurationEnd();
|
|
-
|
|
|
|
return AZ::Success(newNode);
|
|
return AZ::Success(newNode);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -3634,8 +3607,7 @@ namespace ScriptCanvasEditor
|
|
|
|
|
|
AZStd::unordered_map< AZ::EntityId, AZ::EntityId > scriptCanvasToGraphCanvasMapping;
|
|
AZStd::unordered_map< AZ::EntityId, AZ::EntityId > scriptCanvasToGraphCanvasMapping;
|
|
|
|
|
|
- bool graphNeedsDirtying = false;
|
|
|
|
-
|
|
|
|
|
|
+ bool graphNeedsDirtying = !GetVersion().IsLatest();
|
|
{
|
|
{
|
|
QScopedValueRollback<bool> ignoreRequests(m_ignoreSaveRequests, true);
|
|
QScopedValueRollback<bool> ignoreRequests(m_ignoreSaveRequests, true);
|
|
|
|
|
|
@@ -3659,7 +3631,8 @@ namespace ScriptCanvasEditor
|
|
AZStd::unordered_set<AZ::EntityId> deletedNodes;
|
|
AZStd::unordered_set<AZ::EntityId> deletedNodes;
|
|
AZStd::unordered_set<AZ::EntityId> assetSanitizationSet;
|
|
AZStd::unordered_set<AZ::EntityId> assetSanitizationSet;
|
|
AZStd::unordered_set<ScriptCanvas::Node*> sanityCheckRequiredNodes;
|
|
AZStd::unordered_set<ScriptCanvas::Node*> sanityCheckRequiredNodes;
|
|
- ScriptCanvas::ReplacementConnectionMap remapConnections;
|
|
|
|
|
|
+
|
|
|
|
+ ScriptCanvas::GraphUpdateSlotReport graphUpdateSlotReport;
|
|
|
|
|
|
for (const AZ::EntityId& scriptCanvasNodeId : nodeList)
|
|
for (const AZ::EntityId& scriptCanvasNodeId : nodeList)
|
|
{
|
|
{
|
|
@@ -3674,12 +3647,15 @@ namespace ScriptCanvasEditor
|
|
ScriptCanvas::NodeConfiguration nodeConfig = scriptCanvasNode->GetReplacementNodeConfiguration();
|
|
ScriptCanvas::NodeConfiguration nodeConfig = scriptCanvasNode->GetReplacementNodeConfiguration();
|
|
if (nodeConfig.IsValid())
|
|
if (nodeConfig.IsValid())
|
|
{
|
|
{
|
|
- auto nodeOutcome = ReplaceNodeByConfig(scriptCanvasNode, nodeConfig, remapConnections);
|
|
|
|
|
|
+ ScriptCanvas::NodeUpdateSlotReport nodeUpdateSlotReport;
|
|
|
|
+ auto nodeOutcome = ReplaceNodeByConfig(scriptCanvasNode, nodeConfig, nodeUpdateSlotReport);
|
|
|
|
+
|
|
if (nodeOutcome.IsSuccess())
|
|
if (nodeOutcome.IsSuccess())
|
|
{
|
|
{
|
|
graphNeedsDirtying = true;
|
|
graphNeedsDirtying = true;
|
|
scriptCanvasNode = nodeOutcome.GetValue();
|
|
scriptCanvasNode = nodeOutcome.GetValue();
|
|
m_updateStrings.insert(AZStd::string::format("Replaced node (%s)", scriptCanvasNode->GetNodeName().c_str()));
|
|
m_updateStrings.insert(AZStd::string::format("Replaced node (%s)", scriptCanvasNode->GetNodeName().c_str()));
|
|
|
|
+ ScriptCanvas::MergeUpdateSlotReport(scriptCanvasNodeId, graphUpdateSlotReport, nodeUpdateSlotReport);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -3688,7 +3664,6 @@ namespace ScriptCanvasEditor
|
|
scriptCanvasToGraphCanvasMapping[scriptCanvasNodeId] = graphCanvasNodeId;
|
|
scriptCanvasToGraphCanvasMapping[scriptCanvasNodeId] = graphCanvasNodeId;
|
|
|
|
|
|
auto saveDataIter2 = m_graphCanvasSaveData.find(scriptCanvasNodeId);
|
|
auto saveDataIter2 = m_graphCanvasSaveData.find(scriptCanvasNodeId);
|
|
-
|
|
|
|
if (saveDataIter2 != m_graphCanvasSaveData.end())
|
|
if (saveDataIter2 != m_graphCanvasSaveData.end())
|
|
{
|
|
{
|
|
GraphCanvas::EntitySaveDataRequestBus::Event(graphCanvasNodeId, &GraphCanvas::EntitySaveDataRequests::ReadSaveData, (*saveDataIter2->second));
|
|
GraphCanvas::EntitySaveDataRequestBus::Event(graphCanvasNodeId, &GraphCanvas::EntitySaveDataRequests::ReadSaveData, (*saveDataIter2->second));
|
|
@@ -3699,7 +3674,7 @@ namespace ScriptCanvasEditor
|
|
|
|
|
|
GraphCanvas::SceneRequestBus::Event(graphCanvasGraphId, &GraphCanvas::SceneRequests::AddNode, graphCanvasNodeId, position, false);
|
|
GraphCanvas::SceneRequestBus::Event(graphCanvasGraphId, &GraphCanvas::SceneRequests::AddNode, graphCanvasNodeId, position, false);
|
|
|
|
|
|
- // If the node is deprecated, we want to stomp whatever style it had saved and apply the deperecated style
|
|
|
|
|
|
+ // If the node is deprecated, we want to stomp whatever style it had saved and apply the deprecated style
|
|
if (scriptCanvasNode->IsDeprecated())
|
|
if (scriptCanvasNode->IsDeprecated())
|
|
{
|
|
{
|
|
GraphCanvas::NodeTitleRequestBus::Event(graphCanvasNodeId, &GraphCanvas::NodeTitleRequests::SetPaletteOverride, "DeprecatedNodeTitlePalette");
|
|
GraphCanvas::NodeTitleRequestBus::Event(graphCanvasNodeId, &GraphCanvas::NodeTitleRequests::SetPaletteOverride, "DeprecatedNodeTitlePalette");
|
|
@@ -3719,26 +3694,12 @@ namespace ScriptCanvasEditor
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // Remap connections step should be done before editor processing connections for graph
|
|
|
|
- //
|
|
|
|
- // Delete underlying data conenections.
|
|
|
|
- for (auto remapConnection : remapConnections)
|
|
|
|
- {
|
|
|
|
- RemoveConnection(remapConnection.first);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Recreate connections in a separate pass to avoid triggering display updates for invalid slot ids.
|
|
|
|
- for (auto remapConnection : remapConnections)
|
|
|
|
|
|
+ if (!graphUpdateSlotReport.IsEmpty())
|
|
{
|
|
{
|
|
- for (auto newEndpointPair : remapConnection.second)
|
|
|
|
- {
|
|
|
|
- if (newEndpointPair.first.IsValid() && newEndpointPair.second.IsValid())
|
|
|
|
- {
|
|
|
|
- ConnectByEndpoint(newEndpointPair.first, newEndpointPair.second);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ // currently, it is expected that there are no deleted old slots, those need manual correction
|
|
|
|
+ AZ_Error("ScriptCanvas", graphUpdateSlotReport.m_deletedOldSlots.empty(), "Graph upgrade path: If old slots are deleted, manual upgrading is required");
|
|
|
|
+ UpdateConnectionStatus(*this, graphUpdateSlotReport);
|
|
}
|
|
}
|
|
- ////
|
|
|
|
|
|
|
|
AZStd::unordered_set<AZ::EntityId> graphCanvasNodesToDelete;
|
|
AZStd::unordered_set<AZ::EntityId> graphCanvasNodesToDelete;
|
|
|
|
|