summaryrefslogtreecommitdiff
path: root/Other/NodeEditorExamples/Assets/UNEB/Editor/Actions/DeleteNodeAction.cs
blob: 2e2e6672a8fe6e1f8cb06031e266c6edf6f86d79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UNEB.Utility;

namespace UNEB
{
    // Each input can have many outputs
    using InputToOutputPair = Pair<NodeInput, List<NodeOutput>>;

    // Each output can have many inputs
    using OutputToInputsPair = Pair<NodeOutput, List<NodeInput>>;

    public class DeleteNodeAction : UndoableAction
    {
        private NodeGraph _graph;
        private Node _nodeRemoved = null;

        private List<InputToOutputPair> _oldConnectedOutputs;
        private List<OutputToInputsPair> _oldConnectedInputs;

        // The node referenced can only be destroyed if the 
        // delete action has been done or redone.
        private bool _bCanDeleteNode = false;

        public DeleteNodeAction()
        {

            _oldConnectedOutputs = new List<InputToOutputPair>();
            _oldConnectedInputs = new List<OutputToInputsPair>();
        }

        public override bool Init()
        {
            return manager.window.state.selectedNode != null;
        }

        public override void Do()
        {
            _graph = manager.window.graph;
            _nodeRemoved = manager.window.state.selectedNode;
            _graph.Remove(_nodeRemoved);

            // Remember all the old outputs the inputs were connected to.
            foreach (var input in _nodeRemoved.Inputs) {

                if (input.HasOutputConnected()) {
                    _oldConnectedOutputs.Add(new InputToOutputPair(input, input.Outputs.ToList()));
                }
            }

            // Remember all the old input connections that the outputs were connected to.
            foreach (var output in _nodeRemoved.Outputs) {

                if (output.InputCount != 0) {
                    _oldConnectedInputs.Add(new OutputToInputsPair(output, output.Inputs.ToList()));
                }
            }

            disconnectOldConnections();

            _bCanDeleteNode = true;
        }

        public override void Undo()
        {
            _graph.Add(_nodeRemoved);
            reconnectOldConnections();

            _bCanDeleteNode = false;
        }

        public override void Redo()
        {
            _graph.Remove(_nodeRemoved);
            disconnectOldConnections();

            _bCanDeleteNode = true;
        }

        private void disconnectOldConnections()
        {
            // For all the outputs for this node, remove all the connected inputs.
            foreach (var output in _nodeRemoved.Outputs) {
                output.RemoveAll();
            }

            // For all the inputs for this node, remove all the connected outputs.
            foreach (var input in _nodeRemoved.Inputs) {
                input.RemoveAll();
            }
        }

        private void reconnectOldConnections()
        {
            // For all the remembered inputs (of this node) to output pairs, reconnect.
            foreach (InputToOutputPair inOutPair in _oldConnectedOutputs) {

                NodeInput input = inOutPair.item1;
                List<NodeOutput> outputs = inOutPair.item2;

                foreach (var output in outputs) {
                    output.Add(input);
                }
            }

            // For all the remembered outputs (of this node) to inputs, reconnect.
            foreach (OutputToInputsPair outInsPair in _oldConnectedInputs) {

                NodeOutput output = outInsPair.item1;
                List<NodeInput> inputs = outInsPair.item2;

                foreach (var input in inputs) {
                    output.Add(input);
                }
            }
        }

        public override void OnDestroy()
        {
            if (_bCanDeleteNode && _nodeRemoved) {
                ScriptableObject.DestroyImmediate(_nodeRemoved, true);
            }
        }
    }
}