-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDaggerOutputPin.js
More file actions
258 lines (219 loc) · 7.9 KB
/
Copy pathDaggerOutputPin.js
File metadata and controls
258 lines (219 loc) · 7.9 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
'use strict'
const DaggerBasePin = require('./DaggerBasePin.js').DaggerBasePin;
const DaggerInputPin = require('./DaggerInputPin.js').DaggerInputPin;
const DaggerTypes= require('./DaggerTypes.js');
/**
* Class that represents a directed output out of a DaggerNode
* @extends DaggerBasePin
*/
class DaggerOutputPin extends DaggerBasePin {
/**
* DaggerOutputPin ctor
*/
constructor() {
super();
this._connectedTo = [];
// by default, we allow all output pins to be multiconnect
this._allowMultiConnect = true;
}
/**
* Get the pin's direction
* @returns {DaggerBasePin.PinDirection.Output}
*/
get direction() {
return DaggerBasePin.PinDirection.Output;
}
/**
* Get list of all DaggerInputPins this pin is connected to.
* @returns {array}
*/
get connectedTo() {
// make a shallow copy
return this._connectedTo.slice();
}
/**
* Get if this output pin allows for multiple connections (typically true)
* @returns {boolean}
*/
get allowMultiConnect() {
return this._allowMultiConnect;
}
/**
* Set if this output pin allows for multiple connections.
*/
set allowMultiConnect(val) {
this._allowMultiConnect = val;
}
/**
* Get if this pin has any connections.
* @returns {boolean}
*/
get isConnected() {
return this._connectedTo.length !== 0;
}
/**
* Get a list of instance IDs for each DaggerInputPin this pin is connected to.
* @returns {array}
*/
get connectedToUUIDs() {
let retv = [];
for(let pin of this._connectedTo) {
retv.push(pin.instanceID);
}
return retv;
}
/**
* Connect this pin to the given DaggerInputPin
* @param {DaggerInputPin} input
* @returns {boolean}
*/
connectToInput(input) {
if(!input) {
this.emitError("Input pin was null in connectToInput");
return false;
}
let outputpincontainer = this._parentNode.parentGraph;
let inputpincontainer = input.parentNode.parentGraph;
if (outputpincontainer == null) {
this.emitError("Output pin is not associated with a DaggerNode or DaggerGraph");
return false;
}
if (inputpincontainer == null) {
this.emitError("Input pin is not associated with a DaggerNode or DaggerGraph");
return false;
}
if (inputpincontainer != outputpincontainer) {
this.emitError("Input pin and Output pin are not associated with the same DaggerGraph");
return false;
}
if(this._parentNode.parentGraph.enableTopology) {
if(!input.canConnectToPin(this)) {
this.emitError("Input pin indicates it cannot connect to this output pin");
return false;
}
if(!this.canConnectToPin(input)) {
this.emitError("Parent node indicates Input pin cannot connect to this output pin");
return false;
}
}
if(input.isConnected) {
if(input.autoCloneMaster) {
this.emitError(("cannot swap connections on cloned pins"));
return false;
}
// try to disconnect the input pin from it's previous connection
if(!input.disconnectPin(false)) {
this.emitError("Input pin is already connected and was not allowed to disconnect");
return false;
}
}
// call the parent container's before connect to see if we are allowed connect them
if(outputpincontainer.beforePinsConnected(this, input)) {
// connect the two pins
this._connectedTo.push(input);
input._connectedTo = this;
// let the graph know they were connected
outputpincontainer.onPinsConnected(this, input);
// signal the connected for both pins
this.pinConnected.emit(input);
input.pinConnected.emit(this);
outputpincontainer.afterPinsConnected(this, input);
return true;
}
return false;
}
/**
* Get if this pin can connect to the given DaggerInputPin
* @param {DaggerInputPin} pin
* @returns {boolean}
*/
canConnectToPin(pin) {
if(!pin || !(pin instanceof DaggerInputPin))
return false;
// pins need to belong to the same topology system
let mtop = this.topologySystem;
let ttop = pin.topologySystem;
if(mtop != ttop) {
// this->emitInfo("cannt connect to input pin. Outputpin topology is " + QString::number(topologySystem()) + ", input pin topology is " + QString::number(ttop));
return false;
}
// if the input is already connected, we cannot connect
if(pin.isConnected)
{
return false;
}
// if multi-connect is not allowed and we are already connected, then a big whopping NO
if(!this.allowMultiConnect && this.isConnected) {
return false;
}
if(!pin.parentNode.descendents(mtop).includes(this.parentNode)) {
return super.canConnectToPin(pin);
} else if(pin.parentNode.ordinal(mtop) >= this.parentNode().ordinal(mtop)) {
return super.canConnectToPin(pin);
}
return false;
}
/**
* Disconnect this pin from the given DaggerInputPin
* @param {DaggerInputPin} ipin
* @param {boolean} forceDisconnect - when true, the pin will disconnect regardless if the topology says it shouldn't
* @returns {boolean}
*/
disconnectPin(ipin, forceDisconnect) {
// get the parent graph of this pin
let parentGraph = this.parentNode.parentGraph;
if(!parentGraph) {
// emitError("Output pin is not associated with a DaggerGraph");
return false;
}
// do we have this input pin?
if(this._connectedTo.includes(ipin)) {
// call the before connect event to see if we can disconnect them
if(forceDisconnect || parentGraph.beforePinsDisconnected(this, ipin)) {
this._connectedTo.splice(this._connectedTo.indexOf(ipin), 1);
ipin._connectedTo = null;
// let the container know they are disonnected
parentGraph.onPinsDisconnected(this, ipin);
// raise the OnPinDisconnected event
this.pinDisconnected.emit(ipin);
ipin.pinDisconnected.emit(this);
parentGraph.afterPinsDisconnected(this, ipin);
return true;
} else {
// we failed to disconnect them
return false;
}
} else {
// since we were never connected to this pin, they are technically disconnected
return true;
}
return false;
}
/**
* Disconnect this pin from all DaggerInputPins.
* @param {boolean} forceDisconnect - when true, the pin will disconnect regardless if the topology says it shouldn't
* @returns {boolean}
*/
disconnectAll(forceDisconnect) {
// walk backwards through the connected list and try to disconnect them
let ccount = this._connectedTo.length;
for(let i = ccount - 1; i > -1; i--) {
let pin = this._connectedTo[i];
if(!pin.disconnectPin(forceDisconnect)) {
// we failed to disconnect a pin
return false;
}
}
return true;
}
/**
* Clean up when object hierarchy is unraveled. Subclasses should always super.
*/
purgeAll() {
super.purgeAll();
this._connectedTo = [];
}
}
module.exports = {
DaggerOutputPin: DaggerOutputPin
};