A bunch of util changes as building out dynamic context.
This commit is contained in:
+3
-1
@@ -1,3 +1,5 @@
|
||||
{
|
||||
"printWidth": 100
|
||||
"printWidth": 100,
|
||||
"bracketSpacing": false,
|
||||
"bracketSameLine": true
|
||||
}
|
||||
|
||||
+30
-20
@@ -21,6 +21,7 @@ import {
|
||||
LAYOUT_LABEL_TO_DATA,
|
||||
addConnectionLayoutSupport,
|
||||
addMenuItem,
|
||||
getConnectedOutputNodesAndFilterPassThroughs,
|
||||
getSlotLinks,
|
||||
isValidConnection,
|
||||
} from "./utils.js";
|
||||
@@ -71,7 +72,6 @@ app.registerExtension({
|
||||
readonly hideSlotLabels: boolean;
|
||||
|
||||
private configuring = true;
|
||||
private schedulePromise: Promise<void> | null = null;
|
||||
|
||||
defaultConnectionsLayout = configLayout;
|
||||
|
||||
@@ -137,7 +137,26 @@ app.registerExtension({
|
||||
}
|
||||
}
|
||||
}
|
||||
this.scheduleStabilize();
|
||||
if (this.configuring) {
|
||||
return;
|
||||
}
|
||||
this.stabilize();
|
||||
if (type === LiteGraph.INPUT) {
|
||||
this.updateDownstream(connected ? 'connect' : 'disconnect', {index: 0, name: this.inputs[0]!.name});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates connected nodes of a change (checking and calling updateFromUpstream). Used for Dynamic Context.
|
||||
*/
|
||||
private updateDownstream(
|
||||
update: "connect" | "disconnect" | "move" | "update",
|
||||
updatedIndexes: {index: number; name: string; from?: number},
|
||||
) {
|
||||
const nodes = getConnectedOutputNodesAndFilterPassThroughs(this, this, 0);
|
||||
for (const node of nodes) {
|
||||
(node as any)?.updateFromUpstream?.(update, this, updatedIndexes);
|
||||
}
|
||||
}
|
||||
|
||||
override onDrawForeground(ctx: CanvasRenderingContext2D, canvas: TLGraphCanvas): void {
|
||||
@@ -161,20 +180,6 @@ 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.
|
||||
@@ -229,7 +234,7 @@ app.registerExtension({
|
||||
|
||||
// Find all outputs
|
||||
const nodes: TLGraphNode[] = [this];
|
||||
let outputNode = null;
|
||||
let outputNodes: TLGraphNode[] = [];
|
||||
let outputType = null;
|
||||
while (nodes.length) {
|
||||
currentNode = nodes.pop()!;
|
||||
@@ -266,8 +271,11 @@ app.registerExtension({
|
||||
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 {
|
||||
if (outputType != null && outputType !== nodeOutType) {
|
||||
console.warn(`[rgthree] Reroute - Mismatching output types..`);
|
||||
}
|
||||
outputType = nodeOutType;
|
||||
outputNode = node;
|
||||
outputNodes.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,8 +314,10 @@ app.registerExtension({
|
||||
}
|
||||
}
|
||||
}
|
||||
(inputNode as any)?.onConnectionsChainChange?.();
|
||||
(outputNode as any)?.onConnectionsChainChange?.();
|
||||
// (inputNode as any)?.onConnectionsChainChange?.(this);
|
||||
// for (const outputNode of outputNodes) {
|
||||
// (outputNode as any)?.onConnectionsChainChange?.(this);
|
||||
// }
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -77,7 +77,7 @@ class LogSession {
|
||||
export type RgthreeUiMessage = {
|
||||
id: string;
|
||||
message: string;
|
||||
type?: 'warn'|null;
|
||||
type?: 'warn'|'info'|null;
|
||||
timeout?: number;
|
||||
// closeable?: boolean; // TODO
|
||||
actions?: Array<{
|
||||
@@ -305,8 +305,8 @@ class Rgthree {
|
||||
fireEvent(event: string, data: any) {
|
||||
if (this.eventsToFns.has(event)) {
|
||||
for (let fn of this.eventsToFns.get(event)!) {
|
||||
const event = new Event(data);
|
||||
fn(event);
|
||||
const e = new CustomEvent(event, {detail:data});
|
||||
fn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-19
@@ -400,7 +400,7 @@ export function getConnectedInputNodes(
|
||||
slot?: number,
|
||||
passThroughFollowing = PassThroughFollowing.ALL,
|
||||
) : TLGraphNode[] {
|
||||
return getConnectedNodes(startNode, IoDirection.INPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
|
||||
return getConnectedNodesInfo(startNode, IoDirection.INPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
|
||||
}
|
||||
export function getConnectedInputNodesAndFilterPassThroughs(
|
||||
startNode: TLGraphNode,
|
||||
@@ -413,14 +413,16 @@ export function getConnectedInputNodesAndFilterPassThroughs(
|
||||
passThroughFollowing,
|
||||
);
|
||||
}
|
||||
|
||||
export function getConnectedOutputNodes(
|
||||
startNode: TLGraphNode,
|
||||
currentNode?: TLGraphNode,
|
||||
slot?: number,
|
||||
passThroughFollowing = PassThroughFollowing.ALL,
|
||||
) : TLGraphNode[] {
|
||||
return getConnectedNodes(startNode, IoDirection.OUTPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
|
||||
return getConnectedNodesInfo(startNode, IoDirection.OUTPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
|
||||
}
|
||||
|
||||
export function getConnectedOutputNodesAndFilterPassThroughs(
|
||||
startNode: TLGraphNode,
|
||||
currentNode?: TLGraphNode,
|
||||
@@ -434,39 +436,48 @@ export function getConnectedOutputNodesAndFilterPassThroughs(
|
||||
}
|
||||
|
||||
|
||||
export function getConnectedNodes(
|
||||
export type ConnectedNodeInfo = {node: TLGraphNode, travelFromSlot: number, travelToSlot: number, originTravelFromSlot: number};
|
||||
|
||||
export function getConnectedNodesInfo(
|
||||
startNode: TLGraphNode,
|
||||
dir = IoDirection.INPUT,
|
||||
currentNode?: TLGraphNode,
|
||||
slot?: number,
|
||||
passThroughFollowing = PassThroughFollowing.ALL,
|
||||
) : {node:TLGraphNode, slot: number}[] {
|
||||
originTravelFromSlot?: number
|
||||
) : ConnectedNodeInfo[] {
|
||||
currentNode = currentNode || startNode;
|
||||
let rootNodes: {node:TLGraphNode, slot: number}[] = [];
|
||||
let rootNodes: ConnectedNodeInfo[] = [];
|
||||
const slotsToRemove = [];
|
||||
if (startNode === currentNode || shouldPassThrough(currentNode, passThroughFollowing)) {
|
||||
// const removeDups = startNode === currentNode;
|
||||
let linkIds: Array<number | null>;
|
||||
|
||||
if (dir == IoDirection.OUTPUT) {
|
||||
linkIds = currentNode.outputs?.flatMap((i) => i.links) || [];
|
||||
} else {
|
||||
linkIds = currentNode.inputs?.map((i) => i.link) || [];
|
||||
}
|
||||
if (typeof slot == "number" && slot > -1) {
|
||||
if (linkIds[slot]) {
|
||||
linkIds = [linkIds[slot]!];
|
||||
if (slot != null && slot > -1) {
|
||||
linkIds = currentNode.outputs[slot]?.links ?? [];
|
||||
} else {
|
||||
return [];
|
||||
linkIds = currentNode.outputs?.flatMap((i) => i.links) || [];
|
||||
}
|
||||
} else {
|
||||
if (slot != null && slot > -1) {
|
||||
linkIds = [currentNode.inputs[slot]?.link ?? -1].filter(i => i > -1);
|
||||
} else {
|
||||
linkIds = currentNode.inputs?.map((i) => i.link) || [];
|
||||
}
|
||||
}
|
||||
let graph = app.graph as LGraph;
|
||||
for (const linkId of linkIds) {
|
||||
const link: LLink = (linkId != null && graph.links[linkId]) as LLink;
|
||||
let link: LLink | null = null;
|
||||
if (typeof linkId == "number") {
|
||||
link = graph.links[linkId] as LLink;
|
||||
}
|
||||
if (!link) {
|
||||
continue;
|
||||
}
|
||||
const travelFromSlot = dir == IoDirection.OUTPUT ? link.origin_slot : link.target_slot;
|
||||
const connectedId = dir == IoDirection.OUTPUT ? link.target_id : link.origin_id;
|
||||
const originSlot = dir == IoDirection.OUTPUT ? link.target_slot : link.origin_slot;
|
||||
const travelToSlot = dir == IoDirection.OUTPUT ? link.target_slot : link.origin_slot;
|
||||
originTravelFromSlot = originTravelFromSlot != null ? originTravelFromSlot : travelFromSlot;
|
||||
const originNode: TLGraphNode = graph.getNodeById(connectedId)!;
|
||||
if (!link) {
|
||||
console.error("No connected node found... weird");
|
||||
@@ -480,10 +491,10 @@ export function getConnectedNodes(
|
||||
);
|
||||
} else {
|
||||
// Add the node and, if it's a pass through, let's collect all its nodes as well.
|
||||
rootNodes.push({node: originNode, slot: originSlot});
|
||||
rootNodes.push({node: originNode, travelFromSlot, travelToSlot, originTravelFromSlot});
|
||||
if (shouldPassThrough(originNode, passThroughFollowing)) {
|
||||
for (const foundNode of getConnectedNodes(startNode, dir, originNode)) {
|
||||
if (!rootNodes.includes(foundNode)) {
|
||||
for (const foundNode of getConnectedNodesInfo(startNode, dir, originNode, undefined, undefined, originTravelFromSlot)) {
|
||||
if (!rootNodes.map(n => n.node).includes(foundNode.node)) {
|
||||
rootNodes.push(foundNode);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-20
@@ -2,7 +2,7 @@ var _a;
|
||||
import { app } from "../../scripts/app.js";
|
||||
import { rgthreeConfig } from "./rgthree_config.js";
|
||||
import { rgthree } from "./rgthree.js";
|
||||
import { LAYOUT_CLOCKWISE, LAYOUT_LABEL_OPPOSITES, LAYOUT_LABEL_TO_DATA, addConnectionLayoutSupport, addMenuItem, getSlotLinks, isValidConnection, } from "./utils.js";
|
||||
import { LAYOUT_CLOCKWISE, LAYOUT_LABEL_OPPOSITES, LAYOUT_LABEL_TO_DATA, addConnectionLayoutSupport, addMenuItem, getConnectedOutputNodesAndFilterPassThroughs, getSlotLinks, isValidConnection, } from "./utils.js";
|
||||
import { wait } from "./shared_utils.js";
|
||||
const rerouteConfig = ((_a = rgthreeConfig === null || rgthreeConfig === void 0 ? void 0 : rgthreeConfig['nodes']) === null || _a === void 0 ? void 0 : _a['reroute']) || {};
|
||||
let configWidth = Math.max(Math.round((Number(rerouteConfig['default_width']) || 40) / 10) * 10, 10);
|
||||
@@ -31,7 +31,6 @@ app.registerExtension({
|
||||
var _a;
|
||||
super(title);
|
||||
this.configuring = true;
|
||||
this.schedulePromise = null;
|
||||
this.defaultConnectionsLayout = configLayout;
|
||||
this.isVirtualNode = true;
|
||||
this.hideSlotLabels = true;
|
||||
@@ -75,7 +74,20 @@ app.registerExtension({
|
||||
}
|
||||
}
|
||||
}
|
||||
this.scheduleStabilize();
|
||||
if (this.configuring) {
|
||||
return;
|
||||
}
|
||||
this.stabilize();
|
||||
if (type === LiteGraph.INPUT) {
|
||||
this.updateDownstream(connected ? 'connect' : 'disconnect', { index: 0, name: this.inputs[0].name });
|
||||
}
|
||||
}
|
||||
updateDownstream(update, updatedIndexes) {
|
||||
var _a;
|
||||
const nodes = getConnectedOutputNodesAndFilterPassThroughs(this, this, 0);
|
||||
for (const node of nodes) {
|
||||
(_a = node === null || node === void 0 ? void 0 : node.updateFromUpstream) === null || _a === void 0 ? void 0 : _a.call(node, update, this, updatedIndexes);
|
||||
}
|
||||
}
|
||||
onDrawForeground(ctx, canvas) {
|
||||
var _a, _b, _c;
|
||||
@@ -97,20 +109,8 @@ 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, _d, _e, _f, _g, _h;
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
if (this.configuring) {
|
||||
return;
|
||||
}
|
||||
@@ -155,7 +155,7 @@ app.registerExtension({
|
||||
}
|
||||
}
|
||||
const nodes = [this];
|
||||
let outputNode = null;
|
||||
let outputNodes = [];
|
||||
let outputType = null;
|
||||
while (nodes.length) {
|
||||
currentNode = nodes.pop();
|
||||
@@ -187,8 +187,11 @@ app.registerExtension({
|
||||
node.disconnectInput(link.target_slot);
|
||||
}
|
||||
else {
|
||||
if (outputType != null && outputType !== nodeOutType) {
|
||||
console.warn(`[rgthree] Reroute - Mismatching output types..`);
|
||||
}
|
||||
outputType = nodeOutType;
|
||||
outputNode = node;
|
||||
outputNodes.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,8 +223,6 @@ app.registerExtension({
|
||||
}
|
||||
}
|
||||
}
|
||||
(_g = inputNode === null || inputNode === void 0 ? void 0 : inputNode.onConnectionsChainChange) === null || _g === void 0 ? void 0 : _g.call(inputNode);
|
||||
(_h = outputNode === null || outputNode === void 0 ? void 0 : outputNode.onConnectionsChainChange) === null || _h === void 0 ? void 0 : _h.call(outputNode);
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
computeSize(out) {
|
||||
|
||||
+2
-2
@@ -245,8 +245,8 @@ class Rgthree {
|
||||
fireEvent(event, data) {
|
||||
if (this.eventsToFns.has(event)) {
|
||||
for (let fn of this.eventsToFns.get(event)) {
|
||||
const event = new Event(data);
|
||||
fn(event);
|
||||
const e = new CustomEvent(event, { detail: data });
|
||||
fn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-18
@@ -275,46 +275,53 @@ export function filterOutPassthroughNodes(nodes, passThroughFollowing = PassThro
|
||||
return nodes.filter((n) => !shouldPassThrough(n, passThroughFollowing));
|
||||
}
|
||||
export function getConnectedInputNodes(startNode, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
|
||||
return getConnectedNodes(startNode, IoDirection.INPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
|
||||
return getConnectedNodesInfo(startNode, IoDirection.INPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
|
||||
}
|
||||
export function getConnectedInputNodesAndFilterPassThroughs(startNode, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
|
||||
return filterOutPassthroughNodes(getConnectedInputNodes(startNode, currentNode, slot, passThroughFollowing), passThroughFollowing);
|
||||
}
|
||||
export function getConnectedOutputNodes(startNode, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
|
||||
return getConnectedNodes(startNode, IoDirection.OUTPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
|
||||
return getConnectedNodesInfo(startNode, IoDirection.OUTPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
|
||||
}
|
||||
export function getConnectedOutputNodesAndFilterPassThroughs(startNode, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
|
||||
return filterOutPassthroughNodes(getConnectedOutputNodes(startNode, currentNode, slot, passThroughFollowing), passThroughFollowing);
|
||||
}
|
||||
export function getConnectedNodes(startNode, dir = IoDirection.INPUT, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
|
||||
var _a, _b;
|
||||
export function getConnectedNodesInfo(startNode, dir = IoDirection.INPUT, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL, originTravelFromSlot) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
currentNode = currentNode || startNode;
|
||||
let rootNodes = [];
|
||||
const slotsToRemove = [];
|
||||
if (startNode === currentNode || shouldPassThrough(currentNode, passThroughFollowing)) {
|
||||
let linkIds;
|
||||
if (dir == IoDirection.OUTPUT) {
|
||||
linkIds = ((_a = currentNode.outputs) === null || _a === void 0 ? void 0 : _a.flatMap((i) => i.links)) || [];
|
||||
}
|
||||
else {
|
||||
linkIds = ((_b = currentNode.inputs) === null || _b === void 0 ? void 0 : _b.map((i) => i.link)) || [];
|
||||
}
|
||||
if (typeof slot == "number" && slot > -1) {
|
||||
if (linkIds[slot]) {
|
||||
linkIds = [linkIds[slot]];
|
||||
if (slot != null && slot > -1) {
|
||||
linkIds = (_b = (_a = currentNode.outputs[slot]) === null || _a === void 0 ? void 0 : _a.links) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
linkIds = ((_c = currentNode.outputs) === null || _c === void 0 ? void 0 : _c.flatMap((i) => i.links)) || [];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (slot != null && slot > -1) {
|
||||
linkIds = [(_e = (_d = currentNode.inputs[slot]) === null || _d === void 0 ? void 0 : _d.link) !== null && _e !== void 0 ? _e : -1].filter(i => i > -1);
|
||||
}
|
||||
else {
|
||||
linkIds = ((_f = currentNode.inputs) === null || _f === void 0 ? void 0 : _f.map((i) => i.link)) || [];
|
||||
}
|
||||
}
|
||||
let graph = app.graph;
|
||||
for (const linkId of linkIds) {
|
||||
const link = (linkId != null && graph.links[linkId]);
|
||||
let link = null;
|
||||
if (typeof linkId == "number") {
|
||||
link = graph.links[linkId];
|
||||
}
|
||||
if (!link) {
|
||||
continue;
|
||||
}
|
||||
const travelFromSlot = dir == IoDirection.OUTPUT ? link.origin_slot : link.target_slot;
|
||||
const connectedId = dir == IoDirection.OUTPUT ? link.target_id : link.origin_id;
|
||||
const originSlot = dir == IoDirection.OUTPUT ? link.target_slot : link.origin_slot;
|
||||
const travelToSlot = dir == IoDirection.OUTPUT ? link.target_slot : link.origin_slot;
|
||||
originTravelFromSlot = originTravelFromSlot != null ? originTravelFromSlot : travelFromSlot;
|
||||
const originNode = graph.getNodeById(connectedId);
|
||||
if (!link) {
|
||||
console.error("No connected node found... weird");
|
||||
@@ -324,10 +331,10 @@ export function getConnectedNodes(startNode, dir = IoDirection.INPUT, currentNod
|
||||
console.log(`${startNode.title} (${startNode.id}) seems to have two links to ${originNode.title} (${originNode.id}). One may be stale: ${linkIds.join(", ")}`);
|
||||
}
|
||||
else {
|
||||
rootNodes.push({ node: originNode, slot: originSlot });
|
||||
rootNodes.push({ node: originNode, travelFromSlot, travelToSlot, originTravelFromSlot });
|
||||
if (shouldPassThrough(originNode, passThroughFollowing)) {
|
||||
for (const foundNode of getConnectedNodes(startNode, dir, originNode)) {
|
||||
if (!rootNodes.includes(foundNode)) {
|
||||
for (const foundNode of getConnectedNodesInfo(startNode, dir, originNode, undefined, undefined, originTravelFromSlot)) {
|
||||
if (!rootNodes.map(n => n.node).includes(foundNode.node)) {
|
||||
rootNodes.push(foundNode);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user