From d80edff13347ddd61183257f336f60018e7be5bb Mon Sep 17 00:00:00 2001 From: Anjal Doshi Date: Tue, 12 Dec 2023 18:52:52 -0800 Subject: [PATCH] Fix Undo/Redo for Add and Paste actions that results in a new signal chain --- .../ProcessorGraph/ProcessorGraph.cpp | 46 ++++++++++++++++++- .../ProcessorGraph/ProcessorGraph.h | 3 ++ .../ProcessorGraph/ProcessorGraphActions.cpp | 23 ++++++++-- .../ProcessorGraph/ProcessorGraphActions.h | 10 +++- Source/UI/EditorViewport.cpp | 14 +++++- 5 files changed, 89 insertions(+), 7 deletions(-) diff --git a/Source/Processors/ProcessorGraph/ProcessorGraph.cpp b/Source/Processors/ProcessorGraph/ProcessorGraph.cpp index c3f1bf28b..3853a93c5 100644 --- a/Source/Processors/ProcessorGraph/ProcessorGraph.cpp +++ b/Source/Processors/ProcessorGraph/ProcessorGraph.cpp @@ -312,6 +312,13 @@ GenericProcessor* ProcessorGraph::createProcessor(Plugin::Description& descripti } else { GenericProcessor* rootSource = sourceNode; + + if (sourceNode->isMerger()) + { + Merger* merger = (Merger*) sourceNode; + rootSource = merger->getSourceNode(1); + } + while (rootSource->getSourceNode() != nullptr) rootSource = rootSource->getSourceNode(); @@ -518,7 +525,12 @@ bool ProcessorGraph::checkForNewRootNodes(GenericProcessor* processor, GenericProcessor* sourceA = merger->getSourceNode(0); while (sourceA->getSourceNode() != nullptr) - sourceA = sourceA->getSourceNode(); + { + if (sourceA->isMerger()) + sourceA = ((Merger*) sourceA)->getSourceNode(1); + else + sourceA = sourceA->getSourceNode(); + } createEmptyProcessor(processor, rootNodes.indexOf(sourceA) + 1); @@ -683,6 +695,7 @@ void ProcessorGraph::updateSettings(GenericProcessor* processor, bool signalChai && !processorToUpdate->getSourceNode()->isEmpty()) { processorToUpdate = processorToUpdate->getSourceNode(); + processor = processorToUpdate; } Array splitters; @@ -941,6 +954,37 @@ void ProcessorGraph::deleteNodes(Array processorsToDelete) } } + +void ProcessorGraph::reconnectProcessors(int sourceNodeId, + int destNodeid) +{ + GenericProcessor* sourceNode = getProcessorWithNodeId(sourceNodeId); + GenericProcessor* destNode = getProcessorWithNodeId(destNodeid); + + // if dest node is a merger, switch to path that points to the processor being removed + if (sourceNode != nullptr && destNode != nullptr) + { + if (destNode->getSourceNode() != nullptr + && destNode->getSourceNode()->isEmpty()) + { + if (!isConsoleApp) + { + AccessClass::getGraphViewer()->removeNode(destNode->getSourceNode()); + AccessClass::getEditorViewport()->removeEditor(destNode->getSourceNode()->getEditor()); + } + + rootNodes.remove(rootNodes.indexOf(destNode->getSourceNode())); + emptyProcessors.removeObject(destNode->getSourceNode()); + } + + sourceNode->setDestNode(destNode); + destNode->setSourceNode(sourceNode); + + updateSettings(destNode); + } +} + + void ProcessorGraph::clearSignalChain() { diff --git a/Source/Processors/ProcessorGraph/ProcessorGraph.h b/Source/Processors/ProcessorGraph/ProcessorGraph.h index 99d0a67a7..2e6b546c1 100644 --- a/Source/Processors/ProcessorGraph/ProcessorGraph.h +++ b/Source/Processors/ProcessorGraph/ProcessorGraph.h @@ -134,6 +134,9 @@ class TESTABLE ProcessorGraph : public AudioProcessorGraph /* Creates connections in signal chain*/ void updateConnections(); + /* Connects two processors if not already connected*/ + void reconnectProcessors(int srcNodeId, int destNodeId); + /* Calls startAcquisition() for all processors*/ void startAcquisition(); diff --git a/Source/Processors/ProcessorGraph/ProcessorGraphActions.cpp b/Source/Processors/ProcessorGraph/ProcessorGraphActions.cpp index 32ea39be5..efa4dcd76 100644 --- a/Source/Processors/ProcessorGraph/ProcessorGraphActions.cpp +++ b/Source/Processors/ProcessorGraph/ProcessorGraphActions.cpp @@ -132,6 +132,8 @@ bool AddProcessor::undo() settings = processorGraph->createNodeXml(processor, false); processorGraph->deleteNodes(processorToDelete); + + processorGraph->reconnectProcessors(sourceNodeId, destNodeId); } return true; @@ -139,12 +141,22 @@ bool AddProcessor::undo() PasteProcessors::PasteProcessors(Array copyBuffer_, - int insertionPoint_) : + int insertionPoint_, + GenericProcessor* sourceProcessor, + GenericProcessor* destProcessor) : processorGraph(AccessClass::getProcessorGraph()), insertionPoint(insertionPoint_), copyBuffer(copyBuffer_) { - + if (sourceProcessor != nullptr) + sourceNodeId = sourceProcessor->getNodeId(); + else + sourceNodeId = -1; + + if (destProcessor != nullptr) + destNodeId = destProcessor->getNodeId(); + else + destNodeId = -1; } PasteProcessors::~PasteProcessors() @@ -156,10 +168,11 @@ bool PasteProcessors::perform() { Array newProcessors; - for (int i = 0; i < copyBuffer.size(); i++) + // paste processors in reverse order so sources dont immediately create a new signal chain + for (int i = copyBuffer.size() - 1; i >= 0; i--) { newProcessors.add(processorGraph->createProcessorAtInsertionPoint(copyBuffer.getUnchecked(i), - insertionPoint++, true)); + insertionPoint, true)); } for (auto p : newProcessors) @@ -190,6 +203,8 @@ bool PasteProcessors::undo() processorGraph->deleteNodes(processorsToDelete); + processorGraph->reconnectProcessors(sourceNodeId, destNodeId); + nodeIds.clear(); return true; diff --git a/Source/Processors/ProcessorGraph/ProcessorGraphActions.h b/Source/Processors/ProcessorGraph/ProcessorGraphActions.h index 8132f8555..d04ea8e51 100644 --- a/Source/Processors/ProcessorGraph/ProcessorGraphActions.h +++ b/Source/Processors/ProcessorGraph/ProcessorGraphActions.h @@ -89,7 +89,9 @@ class PasteProcessors : public UndoableAction /** Constructor*/ PasteProcessors(Array copyBuffer, - int insertionPoint); + int insertionPoint, + GenericProcessor* source, + GenericProcessor* dest); /** Destructor */ ~PasteProcessors(); @@ -107,6 +109,12 @@ class PasteProcessors : public UndoableAction Array nodeIds; + // source node id of the first processor in the copy buffer + int sourceNodeId; + + // destination node id of the last processor in the copy buffer + int destNodeId; + int insertionPoint; ProcessorGraph* processorGraph; diff --git a/Source/UI/EditorViewport.cpp b/Source/UI/EditorViewport.cpp index 38b9001d7..9b7b62ada 100755 --- a/Source/UI/EditorViewport.cpp +++ b/Source/UI/EditorViewport.cpp @@ -727,7 +727,19 @@ void EditorViewport::paste() AccessClass::getProcessorGraph()->getUndoManager()->beginNewTransaction(); - PasteProcessors* action = new PasteProcessors(processorInfo, insertionPoint); + GenericProcessor* source = nullptr; + GenericProcessor* dest = nullptr; + if (insertionPoint > 0) + { + source = editorArray[insertionPoint-1]->getProcessor(); + } + + if (editorArray.size() > insertionPoint) + { + dest = editorArray[insertionPoint]->getProcessor(); + } + + PasteProcessors* action = new PasteProcessors(processorInfo, insertionPoint, source, dest); AccessClass::getProcessorGraph()->getUndoManager()->perform(action);