Delete js/active_model.js
This commit is contained in:
@@ -1,624 +0,0 @@
|
||||
// --- Loading js/active_model.js --- v2-dynamic-inputs
|
||||
import { app } from "/scripts/app.js"; // Виправлено шлях на абсолютний
|
||||
|
||||
// Цільовий тип вузла, який ми шукаємо
|
||||
const TARGET_NODE_TYPE = "ModelParamsPipe";
|
||||
// Режими роботи вузлів ComfyUI/LiteGraph
|
||||
const MODE_ALWAYS = 0; // Завжди активний
|
||||
const MODE_BYPASS = 4; // Режим обходу (Bypass)
|
||||
const NODE_TITLE = "Active Model"; // Змінено заголовок
|
||||
const NODE_TYPE = "ActiveModel"; // І тип
|
||||
|
||||
class ActiveModel {
|
||||
|
||||
// Налаштування для LiteGraph
|
||||
constructor() {
|
||||
// Цей вузол є переважно контейнером для дій
|
||||
this.properties = {};
|
||||
// Спробуємо знайти та вивести вузли одразу при створенні
|
||||
this.logTargetNodeNames();
|
||||
}
|
||||
|
||||
// Статичні властивості для визначення типу вузла
|
||||
static title = "Active Model";
|
||||
static type = "ActiveModel"; // Унікальний тип для цього вузла
|
||||
|
||||
// Функція для пошуку та логування імен цільових вузлів
|
||||
logTargetNodeNames() {
|
||||
const nodes = app.graph._nodes.filter(node => node.type === TARGET_NODE_TYPE);
|
||||
return nodes; // Повертаємо для можливого використання в onAction
|
||||
}
|
||||
|
||||
// Метод для встановлення режиму для всіх знайдених цільових вузлів
|
||||
setHubsMode(mode) {
|
||||
const nodes = this.logTargetNodeNames();
|
||||
if (nodes.length === 0) {
|
||||
return; // Виходимо, якщо немає цільових вузлів
|
||||
}
|
||||
const modeStr = mode === MODE_ALWAYS ? "ALWAYS" : (mode === MODE_BYPASS ? "BYPASS" : mode);
|
||||
|
||||
let changed = false;
|
||||
for (const node of nodes) {
|
||||
if (node.mode !== mode) {
|
||||
node.mode = mode;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Спрощена обробка дій для тестування
|
||||
onAction(action) {
|
||||
// Просто логуємо знайдені вузли ще раз при виклику дії
|
||||
this.logTargetNodeNames();
|
||||
}
|
||||
|
||||
// Цей вузол не виконує обчислень, тому onExecute може бути порожнім
|
||||
onExecute() {
|
||||
// console.log(`[${ActiveModel.title}] Executed (likely no-op).`);
|
||||
}
|
||||
|
||||
// Статичний метод для налаштування та реєстрації вузла
|
||||
static setUp(clazz) {
|
||||
// Явно встановлюємо статичні властивості, які потрібні LiteGraph
|
||||
clazz.title = ActiveModel.title;
|
||||
clazz.type = ActiveModel.type;
|
||||
clazz.title_mode = LiteGraph.NORMAL_TITLE;
|
||||
clazz.collapsable = true;
|
||||
clazz.size = [240, 50];
|
||||
clazz.category = "MultiModel"; // Змінюємо категорію на основну
|
||||
|
||||
try {
|
||||
// Реєструємо сам клас
|
||||
LiteGraph.registerNodeType(clazz.type, clazz);
|
||||
} catch (e) {
|
||||
console.error(`[${ActiveModel.title}] Node type registration via setUp FAILED:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Визначаємо дії, доступні в контекстному меню
|
||||
ActiveModel.exposedActions = ["Log Hub Names", "Enable All Hubs", "Bypass All Hubs", "Toggle All Hubs"];
|
||||
// Визначаємо статичні властивості title та type тут, щоб вони були доступні для setUp
|
||||
ActiveModel.title = "Active Model";
|
||||
ActiveModel.type = "ActiveModel";
|
||||
|
||||
// --- Допоміжні функції --- //
|
||||
|
||||
// Функція пошуку цільових вузлів (тепер отримує їх з сервісу)
|
||||
function findTargetNodes() {
|
||||
return HubNodesService.getHubNodes();
|
||||
}
|
||||
|
||||
// Функція зміни режиму ОДНОГО вузла
|
||||
function setHubMode(targetNode, mode) {
|
||||
if (!targetNode) return;
|
||||
const currentMode = targetNode.mode;
|
||||
const modeStr = mode === MODE_ALWAYS ? "ON" : "OFF";
|
||||
|
||||
// Якщо ми вмикаємо вузол (MODE_ALWAYS), і при цьому поточний режим НЕ MODE_ALWAYS
|
||||
// (тобто вузол був вимкнений, а тепер ми його вмикаємо)
|
||||
if (mode === MODE_ALWAYS && currentMode !== MODE_ALWAYS) {
|
||||
// Потрібно перевірити, чи є інші активні вузли, і вимкнути їх
|
||||
const allHubNodes = HubNodesService.getHubNodes();
|
||||
const otherActiveNodes = allHubNodes.filter(n => n.id !== targetNode.id && n.mode === MODE_ALWAYS);
|
||||
|
||||
if (otherActiveNodes.length > 0) {
|
||||
otherActiveNodes.forEach(node => {
|
||||
node.mode = MODE_BYPASS;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Змінюємо режим цільового вузла, незалежно від того, чи є інші активні вузли
|
||||
if (currentMode !== mode) {
|
||||
targetNode.mode = mode;
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Нова функція для оновлення віджетів у всіх байпасерах для конкретного вузла
|
||||
function updateAllBypasserWidgets(targetNode) {
|
||||
if (!targetNode) return;
|
||||
|
||||
const bypassers = HubNodesService.bypasserNodes;
|
||||
|
||||
bypassers.forEach(bypasser => {
|
||||
if (!bypasser || !bypasser.widgets) return;
|
||||
|
||||
const widgetName = `hub_${targetNode.id}`;
|
||||
const widget = bypasser.widgets.find(w => w.name === widgetName);
|
||||
|
||||
if (widget) {
|
||||
// Оновлюємо значення віджета
|
||||
const isBypassed = targetNode.mode === MODE_BYPASS;
|
||||
const newValue = !isBypassed;
|
||||
|
||||
// Оновлюємо також заголовок, щоб він відповідав новому формату
|
||||
const newLabel = `${targetNode.title || '(Untitled)'}`;
|
||||
|
||||
let changed = false;
|
||||
|
||||
if (widget.value !== newValue) {
|
||||
widget.value = newValue;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (widget.label !== newLabel) {
|
||||
widget.label = newLabel;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
bypasser.graph.setDirtyCanvas(true, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- Сервіс для керування вузлами --- //
|
||||
const HubNodesService = {
|
||||
hubNodes: [],
|
||||
bypasserNodes: [],
|
||||
updateTimeout: null,
|
||||
updateDelay: 100,
|
||||
app: null, // Додано для доступу до app
|
||||
|
||||
registerBypasserNode(node) {
|
||||
if (!this.bypasserNodes.find(n => n.id === node.id)) {
|
||||
this.bypasserNodes.push(node);
|
||||
this.scheduleUpdate(`registerBypasser_${node.id}`);
|
||||
}
|
||||
},
|
||||
|
||||
unregisterBypasserNode(node) {
|
||||
const index = this.bypasserNodes.findIndex(n => n.id === node.id);
|
||||
if (index !== -1) {
|
||||
this.bypasserNodes.splice(index, 1);
|
||||
// Оновлення не потрібне при видаленні самого байпасера
|
||||
} else {
|
||||
console.log(`[HubNodesService] Node ID ${node.id} not found for unregistration.`);
|
||||
}
|
||||
},
|
||||
|
||||
getHubNodes() {
|
||||
return [...this.hubNodes];
|
||||
},
|
||||
|
||||
// --- Нові методи для сповіщень від Hub --- //
|
||||
notifyHubAdded(node) {
|
||||
if (!node) return;
|
||||
if (!this.hubNodes.find(n => n.id === node.id)) {
|
||||
this.hubNodes.push(node);
|
||||
this.hubNodes.sort((a, b) => a.id - b.id); // Підтримуємо сортування
|
||||
this.scheduleUpdate(`notifyHubAdded_${node.id}`);
|
||||
} else {
|
||||
console.log(`[HubNodesService] Hub node ID ${node.id} already exists.`);
|
||||
}
|
||||
},
|
||||
|
||||
notifyHubRemoved(node) {
|
||||
if (!node) return;
|
||||
const index = this.hubNodes.findIndex(n => n.id === node.id);
|
||||
if (index !== -1) {
|
||||
this.hubNodes.splice(index, 1);
|
||||
this.scheduleUpdate(`notifyHubRemoved_${node.id}`);
|
||||
} else {
|
||||
console.log(`[HubNodesService] Hub node ID ${node.id} not found for removal notification.`);
|
||||
}
|
||||
},
|
||||
|
||||
notifyHubRenamed(node) {
|
||||
if (!node) return;
|
||||
this.scheduleUpdate(`notifyHubRenamed_${node.id}`);
|
||||
},
|
||||
// --- Кінець нових методів --- //
|
||||
|
||||
scheduleUpdate(reason = "unknown") {
|
||||
if (this.updateTimeout) {
|
||||
clearTimeout(this.updateTimeout);
|
||||
}
|
||||
this.updateTimeout = setTimeout(() => {
|
||||
this.updateTimeout = null;
|
||||
this.bypasserNodes.forEach(node => {
|
||||
if (node.refreshWidgets) {
|
||||
node.refreshWidgets();
|
||||
} else {
|
||||
console.warn(`[HubNodesService] Bypasser node ID: ${node.id} missing refreshWidgets method.`);
|
||||
}
|
||||
});
|
||||
}, this.updateDelay);
|
||||
}
|
||||
};
|
||||
|
||||
app.registerExtension({
|
||||
name: "MultiModel.ActiveModel.ServiceDriven", // Оновлено назву розширення
|
||||
|
||||
setup(appInstance) {
|
||||
// Реєструємо сервіс, щоб він був доступний іншим розширенням
|
||||
appInstance.HubNodesService = HubNodesService;
|
||||
HubNodesService.app = appInstance;
|
||||
|
||||
// Додаємо перехоплення onNodeAdded для відстеження додавання нашої ноди
|
||||
if (appInstance.graph && !appInstance.graph._activemodel_onNodeAdded_attached) {
|
||||
const origNodeAdded = appInstance.graph.onNodeAdded;
|
||||
|
||||
appInstance.graph.onNodeAdded = function(node) {
|
||||
// Спочатку викликаємо оригінальний обробник
|
||||
if (origNodeAdded) {
|
||||
origNodeAdded.call(this, node);
|
||||
}
|
||||
|
||||
// Перевіряємо, чи це наша нода ActiveModel
|
||||
if (node.type === NODE_TYPE) {
|
||||
// Викликаємо обробку ноди для додавання віджетів
|
||||
const extension = appInstance.extensions.find(ext => ext.name === "MultiModel.ActiveModel.ServiceDriven");
|
||||
if (extension) {
|
||||
// Конфігуруємо ноду
|
||||
extension.loadedGraphNode(node, appInstance);
|
||||
|
||||
// Оновлюємо віджети з невеликою затримкою
|
||||
setTimeout(() => {
|
||||
if (node.refreshWidgets) {
|
||||
node.refreshWidgets();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
appInstance.graph._activemodel_onNodeAdded_attached = true;
|
||||
}
|
||||
|
||||
// Початкове сканування потрібне, щоб знайти вузли, які вже існують при завантаженні
|
||||
setTimeout(() => {
|
||||
// Знаходимо існуючі Hub та Bypasser ноди і реєструємо їх
|
||||
let initialHubsFound = 0;
|
||||
let initialBypassersFound = 0;
|
||||
appInstance.graph._nodes.forEach(node => {
|
||||
if (node.type === TARGET_NODE_TYPE) {
|
||||
HubNodesService.notifyHubAdded(node);
|
||||
initialHubsFound++;
|
||||
} else if (node.type === NODE_TYPE) {
|
||||
// Реєстрація bypasser'а відбувається також у loadedGraphNode,
|
||||
// але продублюємо тут на випадок проблем з порядком
|
||||
HubNodesService.registerBypasserNode(node);
|
||||
initialBypassersFound++;
|
||||
|
||||
// Додаємо додаткову ініціалізацію для вже існуючих Bypasser нод
|
||||
this.loadedGraphNode(node, appInstance);
|
||||
}
|
||||
});
|
||||
|
||||
// Додаємо окремий виклик для оновлення віджетів для всіх bypassers з більшою затримкою
|
||||
if (initialBypassersFound > 0) {
|
||||
setTimeout(() => {
|
||||
HubNodesService.bypasserNodes.forEach(node => {
|
||||
if (node && node.refreshWidgets) {
|
||||
node.refreshWidgets();
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
}, 500);
|
||||
},
|
||||
|
||||
// loadedGraphNode тепер відповідає ТІЛЬКИ за конфігурацію САМОГО ActiveModel
|
||||
loadedGraphNode(node, appInstance) {
|
||||
if (node.type === NODE_TYPE) {
|
||||
node.app = appInstance;
|
||||
node.IS_BYPASSER_NODE = true;
|
||||
delete node.onAction; // Видаляємо, бо додамо getActions
|
||||
|
||||
// Визначаємо refreshWidgets
|
||||
node.refreshWidgets = function() {
|
||||
const targetNodes = findTargetNodes(); // Отримуємо з сервісу
|
||||
|
||||
// Додаємо детальну діагностику
|
||||
if (targetNodes.length === 0) {
|
||||
console.log(`[${NODE_TITLE} ID: ${this.id}] No target nodes found. HubNodesService state:`,
|
||||
{hubNodesCount: HubNodesService.hubNodes.length,
|
||||
bypassersCount: HubNodesService.bypasserNodes.length});
|
||||
} else {
|
||||
console.log(`[${NODE_TITLE} ID: ${this.id}] Target nodes details:`,
|
||||
targetNodes.map(n => ({id: n.id, title: n.title, mode: n.mode})));
|
||||
}
|
||||
|
||||
// --- Подальша логіка залишається ТАКОЮ Ж САМОЮ, як і раніше ---
|
||||
// (Порівняння віджетів, додавання, видалення, оновлення)
|
||||
const currentWidgets = this.widgets ? [...this.widgets] : [];
|
||||
let widgetsChanged = false;
|
||||
const activeWidgetNames = new Set();
|
||||
|
||||
// Add/Update widgets
|
||||
targetNodes.forEach(targetNode => {
|
||||
if (!targetNode) {
|
||||
return; // Пропускаємо невалідні ноди
|
||||
}
|
||||
const widgetName = `hub_${targetNode.id}`;
|
||||
// Прибираємо ID ноди з заголовка
|
||||
const widgetLabel = `${targetNode.title || '(Untitled)'}`;
|
||||
const isBypassed = targetNode.mode === MODE_BYPASS;
|
||||
const widgetValue = !isBypassed;
|
||||
|
||||
activeWidgetNames.add(widgetName);
|
||||
|
||||
let existingWidget = this.widgets?.find(w => w.name === widgetName);
|
||||
|
||||
if (existingWidget) {
|
||||
let labelChanged = false;
|
||||
if (existingWidget.label !== widgetLabel) {
|
||||
existingWidget.label = widgetLabel;
|
||||
labelChanged = true;
|
||||
}
|
||||
if (existingWidget.value !== widgetValue) {
|
||||
existingWidget.value = widgetValue;
|
||||
widgetsChanged = true;
|
||||
}
|
||||
if (labelChanged) widgetsChanged = true;
|
||||
|
||||
if (!existingWidget.callback) {
|
||||
existingWidget.callback = (value) => {
|
||||
// Нова логіка: якщо перемикач вмикається, вимикаємо всі інші
|
||||
// якщо вимикається - просто вимикаємо
|
||||
const nodeToChange = app.graph.getNodeById(targetNode.id);
|
||||
if (nodeToChange) setHubMode(nodeToChange, value ? MODE_ALWAYS : MODE_BYPASS);
|
||||
};
|
||||
widgetsChanged = true;
|
||||
}
|
||||
} else {
|
||||
this.addWidget(
|
||||
"toggle", widgetName, widgetValue,
|
||||
(value) => {
|
||||
// Нова логіка: дозволяємо будь-які переключення
|
||||
const nodeToChange = app.graph.getNodeById(targetNode.id);
|
||||
if (nodeToChange) setHubMode(nodeToChange, value ? MODE_ALWAYS : MODE_BYPASS);
|
||||
else this.refreshWidgets();
|
||||
},
|
||||
{ on: "ON", off: "OFF" }
|
||||
);
|
||||
this.widgets[this.widgets.length - 1].label = widgetLabel;
|
||||
widgetsChanged = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Remove outdated widgets
|
||||
let removedWidgets = false;
|
||||
if (this.widgets) {
|
||||
for (let i = this.widgets.length - 1; i >= 0; i--) {
|
||||
const widget = this.widgets[i];
|
||||
if (widget.name?.startsWith("hub_") && !activeWidgetNames.has(widget.name)) {
|
||||
this.widgets.splice(i, 1);
|
||||
widgetsChanged = true;
|
||||
removedWidgets = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resize node only if widgets were added/removed
|
||||
if (widgetsChanged) {
|
||||
// ... (логіка зміни розміру залишається такою ж) ...
|
||||
const baseHeight = LiteGraph.NODE_TITLE_HEIGHT + 5;
|
||||
const widgetHeight = LiteGraph.NODE_WIDGET_HEIGHT;
|
||||
const spacing = 4;
|
||||
const hubWidgets = this.widgets?.filter(w => w.name?.startsWith("hub_")) || [];
|
||||
const numWidgets = hubWidgets.length;
|
||||
const requiredHeight = baseHeight + numWidgets * (widgetHeight + spacing) + (numWidgets > 0 ? spacing : 0);
|
||||
const computedSize = this.computeSize();
|
||||
const newHeight = Math.max(computedSize[1], requiredHeight);
|
||||
if (Math.abs(this.size[1] - newHeight) > 2 || removedWidgets) {
|
||||
this.size[1] = newHeight;
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
} else if (widgetsChanged) {
|
||||
this.graph.setDirtyCanvas(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Перевірка на кількість активних вузлів після оновлення віджетів
|
||||
setTimeout(() => {
|
||||
const activeNodes = targetNodes.filter(node => node.mode === MODE_ALWAYS);
|
||||
|
||||
// Якщо більше одного активного вузла, залишаємо тільки перший
|
||||
// Але не активуємо автоматично вузли, якщо всі вимкнені
|
||||
if (activeNodes.length > 1) {
|
||||
// Залишаємо перший вузол активним, інші вимикаємо
|
||||
for (let i = 1; i < activeNodes.length; i++) {
|
||||
setHubMode(activeNodes[i], MODE_BYPASS);
|
||||
|
||||
// Оновлюємо відповідний віджет
|
||||
const widgetName = `hub_${activeNodes[i].id}`;
|
||||
const widget = this.widgets?.find(w => w.name === widgetName);
|
||||
if (widget) {
|
||||
widget.value = false;
|
||||
}
|
||||
}
|
||||
this.graph.setDirtyCanvas(true, false);
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
// Визначаємо дії для контекстного меню
|
||||
node.getActions = function() {
|
||||
const actions = [];
|
||||
if (this.widgets?.some(w => w.name.startsWith("hub_"))) {
|
||||
actions.push({ name: "Activate First Hub", callback: () => this.setAllHubsMode(MODE_ALWAYS) });
|
||||
actions.push({ name: "Switch To Next Hub", callback: () => this.toggleAllHubsMode() });
|
||||
}
|
||||
actions.push({ name: "Log Hub Names (Console)", callback: () => this.logTargetNodeNames() });
|
||||
return actions;
|
||||
};
|
||||
node.logTargetNodeNames = function() { // Додаємо метод до екземпляра
|
||||
const nodes = HubNodesService.getHubNodes();
|
||||
};
|
||||
|
||||
// Оновлений метод для встановлення режиму всіх хабів
|
||||
node.setAllHubsMode = function(mode) {
|
||||
const hubNodes = HubNodesService.getHubNodes();
|
||||
|
||||
if (hubNodes.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === MODE_ALWAYS) {
|
||||
// Активуємо тільки перший вузол, інші вимикаємо
|
||||
hubNodes.forEach((node, index) => {
|
||||
const newMode = index === 0 ? MODE_ALWAYS : MODE_BYPASS;
|
||||
|
||||
if (node.mode !== newMode) {
|
||||
node.mode = newMode;
|
||||
updateAllBypasserWidgets(node);
|
||||
}
|
||||
});
|
||||
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
} else if (mode === MODE_BYPASS) {
|
||||
// Якщо режим BYPASS, вимикаємо всі вузли
|
||||
hubNodes.forEach(node => {
|
||||
if (node.mode !== MODE_BYPASS) {
|
||||
node.mode = MODE_BYPASS;
|
||||
updateAllBypasserWidgets(node);
|
||||
}
|
||||
});
|
||||
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
};
|
||||
|
||||
// Оновлений метод для перемикання вузлів
|
||||
node.toggleAllHubsMode = function() {
|
||||
const hubNodes = HubNodesService.getHubNodes();
|
||||
|
||||
if (hubNodes.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Перевіряємо, чи є хоча б один активний вузол
|
||||
const activeNodes = hubNodes.filter(n => n.mode === MODE_ALWAYS);
|
||||
|
||||
if (activeNodes.length === 0) {
|
||||
// Якщо немає активних вузлів, активуємо перший
|
||||
if (hubNodes.length > 0) {
|
||||
const node = hubNodes[0];
|
||||
node.mode = MODE_ALWAYS;
|
||||
updateAllBypasserWidgets(node);
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
} else {
|
||||
// Якщо є активний вузол, знаходимо його індекс і активуємо наступний
|
||||
const activeNode = activeNodes[0];
|
||||
const currentIndex = hubNodes.findIndex(n => n.id === activeNode.id);
|
||||
|
||||
// Вимикаємо поточний активний вузол
|
||||
activeNode.mode = MODE_BYPASS;
|
||||
updateAllBypasserWidgets(activeNode);
|
||||
|
||||
// Знаходимо наступний вузол (або переходимо до першого, якщо це останній)
|
||||
const nextIndex = (currentIndex + 1) % hubNodes.length;
|
||||
const nextNode = hubNodes[nextIndex];
|
||||
|
||||
// Активуємо наступний вузол
|
||||
nextNode.mode = MODE_ALWAYS;
|
||||
updateAllBypasserWidgets(nextNode);
|
||||
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
};
|
||||
|
||||
// Реєстрація/видалення самого bypasser'а в сервісі
|
||||
node.onAdded = function() {
|
||||
if (appInstance.HubNodesService) { // Перевіряємо наявність сервісу
|
||||
appInstance.HubNodesService.registerBypasserNode(this);
|
||||
} else {
|
||||
console.error(`[${NODE_TITLE} ID: ${this.id}] Cannot register bypasser, HubNodesService not found!`);
|
||||
}
|
||||
};
|
||||
node.onRemoved = function() {
|
||||
if (appInstance.HubNodesService) {
|
||||
appInstance.HubNodesService.unregisterBypasserNode(this);
|
||||
} else {
|
||||
console.error(`[${NODE_TITLE} ID: ${this.id}] Cannot unregister bypasser, HubNodesService not found!`);
|
||||
}
|
||||
};
|
||||
|
||||
// Початкове оновлення віджетів для цього конкретного вузла
|
||||
setTimeout(() => { if (node.refreshWidgets) node.refreshWidgets(); }, 50);
|
||||
}
|
||||
},
|
||||
|
||||
getExtraMenuOptions(_, options) {
|
||||
options.push({
|
||||
content: "Add Active Model",
|
||||
callback: () => {
|
||||
const node = LiteGraph.createNode(NODE_TYPE);
|
||||
// Записуємо текст для коментаря, щоб показати функціональність
|
||||
node.properties.desc = "Controls the flow of Model Parameters Pipe Hubs";
|
||||
app.graph.add(node);
|
||||
|
||||
// Розміщення вузла в центрі видимої області
|
||||
const canvas = app.canvas;
|
||||
const visible_rect = canvas.visible_area;
|
||||
node.pos[0] = visible_rect[0] + visible_rect[2] * 0.5 - node.size[0] * 0.5;
|
||||
node.pos[1] = visible_rect[1] + visible_rect[3] * 0.5 - node.size[1] * 0.5;
|
||||
|
||||
// Явно налаштуємо ноду після створення з меню
|
||||
if (app.HubNodesService) {
|
||||
// Отримуємо розширення
|
||||
const extension = app.extensions.find(ext => ext.name === "MultiModel.ActiveModel.ServiceDriven");
|
||||
if (extension) {
|
||||
// Конфігуруємо ноду
|
||||
extension.loadedGraphNode(node, app);
|
||||
|
||||
// Оновлюємо віджети з затримкою
|
||||
setTimeout(() => {
|
||||
if (node.refreshWidgets) {
|
||||
node.refreshWidgets();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
nodeRegistered(type, clazz) {
|
||||
if (type === NODE_TYPE) {
|
||||
try {
|
||||
ActiveModel.setUp(clazz);
|
||||
} catch (e) {
|
||||
console.error(`[${NODE_TITLE}] Error in additional node setup:`, e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Додаємо обробники створення ноди для максимального покриття
|
||||
nodeCreated(node) {
|
||||
if (node && node.type === NODE_TYPE) {
|
||||
this.loadedGraphNode(node, app);
|
||||
|
||||
// Запускаємо оновлення віджетів з затримкою
|
||||
setTimeout(() => {
|
||||
if (node.refreshWidgets) {
|
||||
node.refreshWidgets();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
|
||||
onNodeAdded(node) {
|
||||
if (node && node.type === NODE_TYPE) {
|
||||
this.loadedGraphNode(node, app);
|
||||
|
||||
// Запускаємо оновлення віджетів з затримкою
|
||||
setTimeout(() => {
|
||||
if (node.refreshWidgets) {
|
||||
node.refreshWidgets();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[${NODE_TITLE}] JS file loaded`);
|
||||
Reference in New Issue
Block a user