Files
chrmc40 8e3dceae99 ComfyUI-PromptChain
A prompt-authoring and image-iteration suite for ComfyUI.
2026-06-17 19:35:25 -07:00

65 lines
2.3 KiB
JavaScript

// Shared registry of live 3D Poser (PromptChain_PoseStudio) nodes.
//
// pose-studio.js populates this as Poser nodes mount/unmount; main.js reads it
// so each PromptChain node's menubar can gate the "pop the Poser into a panel"
// button (enabled only when a Poser exists) and so the panel knows which Poser
// to dock. A single shared module instead of a window global keeps it
// deterministic regardless of which extension file the loader runs first.
//
// Event-driven: subscribers are notified on add/remove (never polled).
const nodes = new Set();
const listeners = new Set();
let lastActive = null;
function notify() {
for (const cb of listeners) {
try { cb(); } catch (e) { console.error("[PromptChain] pose-registry listener error", e); }
}
}
export const poseRegistry = {
// Called by pose-studio.js on mount.
add(node) {
nodes.add(node);
lastActive = node;
notify();
},
// Called by pose-studio.js on teardown.
remove(node) {
const had = nodes.delete(node);
if (lastActive === node) lastActive = null;
if (had) notify();
},
// Called when a Poser viewport is interacted with, so "which Poser does the
// panel dock" follows the one you last touched. Quiet by design — switching
// focus shouldn't yank an already-open panel onto a different node.
touch(node) {
if (nodes.has(node)) lastActive = node;
},
// The viewport finished its async mount (Three.js loaded, _pcrPose with
// enterDock now exists). add() fired its notify far earlier, before docking
// was possible — so re-notify here, letting an already-open panel dock now.
signalReady(node) {
if (nodes.has(node)) notify();
},
// Every live Poser node — e.g. so a latent-size edit can offer itself to
// each one (they individually re-trace whether that latent feeds them).
all() {
return [...nodes];
},
// The Poser a freshly-opened panel should host: last-interacted if still
// alive, else any live one.
getActive() {
if (lastActive && lastActive._pcrAlive && nodes.has(lastActive)) return lastActive;
for (const n of nodes) if (n._pcrAlive) return n;
return null;
},
get count() { return nodes.size; },
// Returns an unsubscribe fn. Fires on add/remove (gating + open-panel refresh).
subscribe(cb) {
listeners.add(cb);
return () => listeners.delete(cb);
},
};