Avoid stabilizing inputs & outputs while the being configured, as connected nodes may delay instantiating slot types. Should fix #27

This commit is contained in:
rgthree
2023-09-18 22:40:00 -04:00
parent 8bbeb2b670
commit 1f6e63d665
2 changed files with 58 additions and 17 deletions
+30 -8
View File
@@ -43,6 +43,9 @@ app.registerExtension({
readonly isVirtualNode?: boolean;
readonly hideSlotLabels: boolean;
private configuring = true;
private schedulePromise: Promise<void> | null = null;
constructor(title = RerouteNode.title) {
super(title);
this.isVirtualNode = true;
@@ -55,9 +58,11 @@ app.registerExtension({
}
override configure(info: SerializedLGraphNode) {
this.configuring = true;
super.configure(info);
this.setResizable(this.properties['resizable']);
this.applyNodeSize();
this.configuring = false;
}
setResizable(resizable: boolean) {
@@ -103,7 +108,7 @@ app.registerExtension({
}
}
}
this.stabilize();
this.scheduleStabilize();
}
override onDrawForeground(ctx: CanvasRenderingContext2D, canvas: TLGraphCanvas): void {
@@ -127,7 +132,26 @@ app.registerExtension({
return super.disconnectOutput(slot, targetNode);
}
scheduleStabilize(ms = 64) {
if (!this.schedulePromise) {
this.schedulePromise = new Promise((resolve) => {
setTimeout(() => {
this.schedulePromise = null
this.stabilize();
resolve();
}, ms);
});
}
return this.schedulePromise;
}
stabilize() {
// If we are currently "configuring" then skip this stabilization. The connected nodes may
// not yet be configured.
if (this.configuring) {
return;
}
// Find root input
let currentNode: TLGraphNode | null = this;
let updateNodes = [];
@@ -194,18 +218,16 @@ app.registerExtension({
updateNodes.push(node);
} else {
// We've found an output
const nodeOutType =
node.inputs &&
node.inputs[link?.target_slot] &&
node.inputs[link.target_slot].type
? node.inputs[link.target_slot].type
: null;
if (
const nodeOutType = node.inputs?.[link.target_slot]?.type;
if (nodeOutType == null) {
console.warn(`[rgthree] Reroute - Connected node ${node.id} does not have type information for slot ${link.target_slot}. Skipping connection enforcement, but something is odd with that node.`);
} else if (
inputType &&
String(nodeOutType) !== String(inputType) && // Sometimes these are arrays, so see if the strings match.
nodeOutType !== "*"
) {
// The output doesnt match our input so disconnect it
console.warn(`[rgthree] Reroute - Disconnecting connected node's input (${node.id}.${link.target_slot}) (${node.type}) because its type (${String(nodeOutType)}) does not match the reroute type (${String(inputType)})`);
node.disconnectInput(link.target_slot);
} else {
outputType = nodeOutType;
+28 -9
View File
@@ -7,6 +7,8 @@ app.registerExtension({
class RerouteNode extends LGraphNode {
constructor(title = RerouteNode.title) {
super(title);
this.configuring = true;
this.schedulePromise = null;
this.isVirtualNode = true;
this.hideSlotLabels = true;
this.setResizable(this.properties['resizable']);
@@ -16,9 +18,11 @@ app.registerExtension({
setTimeout(() => this.applyNodeSize(), 20);
}
configure(info) {
this.configuring = true;
super.configure(info);
this.setResizable(this.properties['resizable']);
this.applyNodeSize();
this.configuring = false;
}
setResizable(resizable) {
this.properties['resizable'] = !!resizable;
@@ -46,7 +50,7 @@ app.registerExtension({
}
}
}
this.stabilize();
this.scheduleStabilize();
}
onDrawForeground(ctx, canvas) {
var _a, _b, _c;
@@ -68,8 +72,23 @@ app.registerExtension({
disconnectOutput(slot, targetNode) {
return super.disconnectOutput(slot, targetNode);
}
scheduleStabilize(ms = 64) {
if (!this.schedulePromise) {
this.schedulePromise = new Promise((resolve) => {
setTimeout(() => {
this.schedulePromise = null;
this.stabilize();
resolve();
}, ms);
});
}
return this.schedulePromise;
}
stabilize() {
var _a, _b, _c;
var _a, _b, _c, _d, _e;
if (this.configuring) {
return;
}
let currentNode = this;
let updateNodes = [];
let inputType = null;
@@ -125,14 +144,14 @@ app.registerExtension({
updateNodes.push(node);
}
else {
const nodeOutType = node.inputs &&
node.inputs[link === null || link === void 0 ? void 0 : link.target_slot] &&
node.inputs[link.target_slot].type
? node.inputs[link.target_slot].type
: null;
if (inputType &&
const nodeOutType = (_d = (_c = node.inputs) === null || _c === void 0 ? void 0 : _c[link.target_slot]) === null || _d === void 0 ? void 0 : _d.type;
if (nodeOutType == null) {
console.warn(`[rgthree] Reroute - Connected node ${node.id} does not have type information for slot ${link.target_slot}. Skipping connection enforcement, but something is odd with that node.`);
}
else if (inputType &&
String(nodeOutType) !== String(inputType) &&
nodeOutType !== "*") {
console.warn(`[rgthree] Reroute - Disconnecting connected node's input (${node.id}.${link.target_slot}) (${node.type}) because its type (${String(nodeOutType)}) does not match the reroute type (${String(inputType)})`);
node.disconnectInput(link.target_slot);
}
else {
@@ -151,7 +170,7 @@ app.registerExtension({
node.__outputType = displayType;
node.outputs[0].name = "";
node.size = node.computeSize();
(_c = node.applyNodeSize) === null || _c === void 0 ? void 0 : _c.call(node);
(_e = node.applyNodeSize) === null || _e === void 0 ? void 0 : _e.call(node);
for (const l of node.outputs[0].links || []) {
const link = app.graph.links[l];
if (link) {