File size: 6,723 Bytes
4450790
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { app } from "../../scripts/app.js";
import { BaseCollectorNode } from "./base_node_collector.js";
import { NodeTypesString, stripRgthree } from "./constants.js";
import { PassThroughFollowing, addConnectionLayoutSupport, getConnectedInputNodesAndFilterPassThroughs, getConnectedOutputNodesAndFilterPassThroughs, } from "./utils.js";
class NodeModeRepeater extends BaseCollectorNode {
    constructor(title) {
        super(title);
        this.inputsPassThroughFollowing = PassThroughFollowing.ALL;
        this.comfyClass = NodeTypesString.NODE_MODE_REPEATER;
        this.hasRelayInput = false;
        this.hasTogglerOutput = false;
        this.onConstructed();
    }
    onConstructed() {
        this.addOutput("OPT_CONNECTION", "*", {
            color_on: "#Fc0",
            color_off: "#a80",
        });
        return super.onConstructed();
    }
    configure(info) {
        var _a;
        if ((_a = info.outputs) === null || _a === void 0 ? void 0 : _a.length) {
            info.outputs.length = 1;
        }
        super.configure(info);
    }
    onConnectOutput(outputIndex, inputType, inputSlot, inputNode, inputIndex) {
        let canConnect = !this.hasRelayInput;
        canConnect =
            canConnect && super.onConnectOutput(outputIndex, inputType, inputSlot, inputNode, inputIndex);
        let nextNode = getConnectedOutputNodesAndFilterPassThroughs(this, inputNode)[0] || inputNode;
        return (canConnect &&
            [
                NodeTypesString.FAST_MUTER,
                NodeTypesString.FAST_BYPASSER,
                NodeTypesString.NODE_COLLECTOR,
                NodeTypesString.FAST_ACTIONS_BUTTON,
                NodeTypesString.REROUTE,
                NodeTypesString.RANDOM_UNMUTER,
            ].includes(nextNode.type || ""));
    }
    onConnectInput(inputIndex, outputType, outputSlot, outputNode, outputIndex) {
        var _a;
        let canConnect = (_a = super.onConnectInput) === null || _a === void 0 ? void 0 : _a.call(this, inputIndex, outputType, outputSlot, outputNode, outputIndex);
        let nextNode = getConnectedOutputNodesAndFilterPassThroughs(this, outputNode)[0] || outputNode;
        const isNextNodeRelay = nextNode.type === NodeTypesString.NODE_MODE_RELAY;
        return canConnect && (!isNextNodeRelay || !this.hasTogglerOutput);
    }
    onConnectionsChange(type, slotIndex, isConnected, linkInfo, ioSlot) {
        super.onConnectionsChange(type, slotIndex, isConnected, linkInfo, ioSlot);
        let hasTogglerOutput = false;
        let hasRelayInput = false;
        const outputNodes = getConnectedOutputNodesAndFilterPassThroughs(this);
        for (const outputNode of outputNodes) {
            if ((outputNode === null || outputNode === void 0 ? void 0 : outputNode.type) === NodeTypesString.FAST_MUTER ||
                (outputNode === null || outputNode === void 0 ? void 0 : outputNode.type) === NodeTypesString.FAST_BYPASSER) {
                hasTogglerOutput = true;
                break;
            }
        }
        const inputNodes = getConnectedInputNodesAndFilterPassThroughs(this);
        for (const [index, inputNode] of inputNodes.entries()) {
            if ((inputNode === null || inputNode === void 0 ? void 0 : inputNode.type) === NodeTypesString.NODE_MODE_RELAY) {
                if (hasTogglerOutput) {
                    console.log(`Can't be connected to a Relay if also output to a toggler.`);
                    this.disconnectInput(index);
                }
                else {
                    hasRelayInput = true;
                    if (this.inputs[index]) {
                        this.inputs[index].color_on = "#FC0";
                        this.inputs[index].color_off = "#a80";
                    }
                }
            }
            else {
                inputNode.mode = this.mode;
            }
        }
        this.hasTogglerOutput = hasTogglerOutput;
        this.hasRelayInput = hasRelayInput;
        if (this.hasRelayInput) {
            if (this.outputs[0]) {
                this.disconnectOutput(0);
                this.removeOutput(0);
            }
        }
        else if (!this.outputs[0]) {
            this.addOutput("OPT_CONNECTION", "*", {
                color_on: "#Fc0",
                color_off: "#a80",
            });
        }
    }
    onModeChange(from, to) {
        var _a, _b;
        super.onModeChange(from, to);
        const linkedNodes = getConnectedInputNodesAndFilterPassThroughs(this).filter((node) => node.type !== NodeTypesString.NODE_MODE_RELAY);
        if (linkedNodes.length) {
            for (const node of linkedNodes) {
                if (node.type !== NodeTypesString.NODE_MODE_RELAY) {
                    node.mode = to;
                }
            }
        }
        else if ((_a = app.graph._groups) === null || _a === void 0 ? void 0 : _a.length) {
            for (const group of app.graph._groups) {
                group.recomputeInsideNodes();
                if ((_b = group._nodes) === null || _b === void 0 ? void 0 : _b.includes(this)) {
                    for (const node of group._nodes) {
                        if (node !== this) {
                            node.mode = to;
                        }
                    }
                }
            }
        }
    }
    getHelp() {
        return `
      <p>
        When this node's mode (Mute, Bypass, Active) changes, it will "repeat" that mode to all
        connected input nodes, or, if there are no connected nodes AND it is overlapping a group,
        "repeat" it's mode to all nodes in that group.
      </p>
      <ul>
        <li><p>
          Optionally, connect this mode's output to a ${stripRgthree(NodeTypesString.FAST_MUTER)}
          or ${stripRgthree(NodeTypesString.FAST_BYPASSER)} for a single toggle to quickly
          mute/bypass all its connected nodes.
        </p></li>
        <li><p>
          Optionally, connect a ${stripRgthree(NodeTypesString.NODE_MODE_RELAY)} to this nodes
          inputs to have it automatically toggle its mode. If connected, this will always take
          precedence (and disconnect any connected fast togglers).
        </p></li>
      </ul>
    `;
    }
}
NodeModeRepeater.type = NodeTypesString.NODE_MODE_REPEATER;
NodeModeRepeater.title = NodeTypesString.NODE_MODE_REPEATER;
app.registerExtension({
    name: "rgthree.NodeModeRepeater",
    registerCustomNodes() {
        addConnectionLayoutSupport(NodeModeRepeater, app, [
            ["Left", "Right"],
            ["Right", "Left"],
        ]);
        LiteGraph.registerNodeType(NodeModeRepeater.type, NodeModeRepeater);
        NodeModeRepeater.category = NodeModeRepeater._category;
    },
});