File size: 6,877 Bytes
583c1c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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;
    },
});