Add change trigger when PS history changes and triggers prompt so auto queue change mode can be used
This commit is contained in:
+25
-13
@@ -1,3 +1,5 @@
|
||||
import os
|
||||
import shutil
|
||||
from server import PromptServer
|
||||
from aiohttp import web, WSMsgType
|
||||
import json
|
||||
@@ -61,6 +63,7 @@ class PhotoshopInstance:
|
||||
self.wsCallsManager = WSCallsManager(ws)
|
||||
self.destroyed = False
|
||||
self.layers = []
|
||||
self.push_data = {}
|
||||
self.get_img_state_id = None
|
||||
self.last_get_img_id = None
|
||||
self.send_img_state_id = None
|
||||
@@ -87,7 +90,9 @@ class PhotoshopInstance:
|
||||
|
||||
if msg.type == WSMsgType.TEXT:
|
||||
payload = json.loads(msg.data)
|
||||
|
||||
if 'push_data' in payload:
|
||||
push_data = payload['push_data']
|
||||
self.push_data.update(push_data)
|
||||
if 'call_id' in payload:
|
||||
call_id = payload['call_id']
|
||||
if 'error' in payload:
|
||||
@@ -107,6 +112,9 @@ class PhotoshopInstance:
|
||||
finally:
|
||||
print('Photoshop Disconnected')
|
||||
PhotoshopInstance.instance = None
|
||||
|
||||
def get_push_state_id(self):
|
||||
return self.push_data.get('history_state_id', None)
|
||||
|
||||
async def get_layers(self):
|
||||
result = await self.wsCallsManager.call('get_layers', {})
|
||||
@@ -123,8 +131,11 @@ class PhotoshopInstance:
|
||||
self.last_get_img_id = id
|
||||
return id
|
||||
|
||||
def is_get_image_changed(self):
|
||||
current_id = _invoke_async(self.get_active_history_state_id())
|
||||
async def is_get_image_changed(self):
|
||||
push_state_id = self.get_push_state_id()
|
||||
if push_state_id is not None:
|
||||
return self.get_img_state_id != push_state_id
|
||||
current_id = await self.get_active_history_state_id()
|
||||
return self.get_img_state_id != current_id
|
||||
|
||||
async def send_images(self, image_ids, layer_name=""):
|
||||
@@ -139,7 +150,7 @@ class PhotoshopInstance:
|
||||
|
||||
async def get_active_history_state_id(self):
|
||||
result = await self.wsCallsManager.call('get_active_history_state_id', {})
|
||||
id = result['history_state_id']
|
||||
id = result.get('history_state_id', None)
|
||||
return id
|
||||
|
||||
async def destroy(self):
|
||||
@@ -258,7 +269,7 @@ class GetImageFromPhotoshopLayerNode:
|
||||
if (PhotoshopInstance.instance is None):
|
||||
return np.random.rand()
|
||||
else:
|
||||
return PhotoshopInstance.instance.is_get_image_changed()
|
||||
return _invoke_async(PhotoshopInstance.instance.get_active_history_state_id())
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -376,15 +387,16 @@ class SendImageToPhotoshopSetLayerNode:
|
||||
threading.Thread(target=lambda: asyncio.run(PhotoshopInstance.instance.send_images(image_ids=ret, layer_name=layer_name))).start()
|
||||
return (None,)
|
||||
|
||||
loop = None
|
||||
def _invoke_async(call):
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
task = loop.create_task(call)
|
||||
loop.run_until_complete(task)
|
||||
result = task.result()
|
||||
loop.close()
|
||||
return result
|
||||
return asyncio.run(call)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/sd-ppp/checkchanges")
|
||||
async def fetch_customnode_mappings(request):
|
||||
is_changed = False
|
||||
if (PhotoshopInstance.instance is not None):
|
||||
is_changed = await PhotoshopInstance.instance.is_get_image_changed()
|
||||
return web.json_response({'is_changed': is_changed}, content_type='application/json')
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
'Get Image From Photoshop Layer': GetImageFromPhotoshopLayerNode,
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
import { api } from "../../scripts/api.js"
|
||||
|
||||
console.log("[sd-ppp]", "Loading js extension");
|
||||
app.registerExtension({
|
||||
name: "Comfy.SD-PPP",
|
||||
init() {
|
||||
},
|
||||
async setup() {
|
||||
setInterval(checkChanges, 1000);
|
||||
},
|
||||
});
|
||||
|
||||
const SDPPPNodes = [
|
||||
'Get Image From Photoshop Layer',
|
||||
'Send Images To Photoshop',
|
||||
'Send Images To Photoshop Set Layer',
|
||||
]
|
||||
async function checkChanges() {
|
||||
const currentState = app.graph.serialize();
|
||||
const mode0NodeTypes = currentState.nodes.filter(node => node.mode == 0).map(node => node.type);
|
||||
const containsSDPPPNodes = mode0NodeTypes.some(nodeType => SDPPPNodes.includes(nodeType));
|
||||
if (!containsSDPPPNodes) return;
|
||||
const res = await api.fetchApi(`/sd-ppp/checkchanges`);
|
||||
const json = await res.json()
|
||||
if (!json.is_changed) return;
|
||||
api.dispatchEvent(new CustomEvent("graphChanged"));
|
||||
}
|
||||
Vendored
+91
-8
@@ -88,8 +88,10 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");
|
||||
/* harmony import */ var _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../system/ComfyConnection */ "./src/system/ComfyConnection.js");
|
||||
/* harmony import */ var uxp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! uxp */ "uxp");
|
||||
/* harmony import */ var uxp__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(uxp__WEBPACK_IMPORTED_MODULE_2__);
|
||||
/* harmony import */ var _system_HistoryChecker__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../system/HistoryChecker */ "./src/system/HistoryChecker.js");
|
||||
/* harmony import */ var uxp__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! uxp */ "uxp");
|
||||
/* harmony import */ var uxp__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(uxp__WEBPACK_IMPORTED_MODULE_3__);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -106,8 +108,18 @@ class Main extends react__WEBPACK_IMPORTED_MODULE_0__.Component {
|
||||
isConnected: instance?.isConnected,
|
||||
comfyURL: instance ? instance.comfyURL : ''
|
||||
});
|
||||
if (instance?.isConnected) {
|
||||
const hc = _system_HistoryChecker__WEBPACK_IMPORTED_MODULE_2__["default"].createInstance();
|
||||
hc.setChangeCallback(historyId => {
|
||||
instance.pushData({
|
||||
history_state_id: historyId
|
||||
});
|
||||
});
|
||||
} else {
|
||||
_system_HistoryChecker__WEBPACK_IMPORTED_MODULE_2__["default"].instance?.destroy();
|
||||
}
|
||||
});
|
||||
uxp__WEBPACK_IMPORTED_MODULE_2__.storage.secureStorage.getItem('comfyURL').then(value => {
|
||||
uxp__WEBPACK_IMPORTED_MODULE_3__.storage.secureStorage.getItem('comfyURL').then(value => {
|
||||
if (!value) return;
|
||||
this.setState({
|
||||
comfyURL: Buffer.from(value).toString()
|
||||
@@ -284,6 +296,19 @@ class ComfyConnection {
|
||||
this.comfyURL = comfyURL.replace(/\/*$/, '');
|
||||
this.connect();
|
||||
}
|
||||
pushData(data) {
|
||||
if (!this.socket || this.socket.readyState != WebSocket.OPEN) {
|
||||
console.error('Connection not open');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.socket.send(JSON.stringify({
|
||||
push_data: data
|
||||
}));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
async onMessage(event) {
|
||||
console.log("Message from comfy ", event.data);
|
||||
try {
|
||||
@@ -415,13 +440,15 @@ class ComfyConnection {
|
||||
});
|
||||
} else if (payload.action == 'get_active_history_state_id') {
|
||||
try {
|
||||
const historyStates = photoshop__WEBPACK_IMPORTED_MODULE_0__.app.activeDocument.historyStates;
|
||||
const historyState = historyStates[historyStates.length - 1];
|
||||
let result = {};
|
||||
const historyStates = photoshop__WEBPACK_IMPORTED_MODULE_0__.app.activeDocument?.historyStates;
|
||||
if (historyStates && historyStates.length > 0) {
|
||||
const historyState = historyStates[historyStates.length - 1];
|
||||
result.history_state_id = historyState.id;
|
||||
}
|
||||
this.socket.send(JSON.stringify({
|
||||
call_id: payload.call_id,
|
||||
result: {
|
||||
history_state_id: historyState.id
|
||||
}
|
||||
result: result
|
||||
}));
|
||||
} catch (e) {
|
||||
this.socket.send(JSON.stringify({
|
||||
@@ -473,6 +500,62 @@ class ComfyConnection {
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./src/system/HistoryChecker.js":
|
||||
/*!**************************************!*\
|
||||
!*** ./src/system/HistoryChecker.js ***!
|
||||
\**************************************/
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var photoshop__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! photoshop */ "photoshop");
|
||||
/* harmony import */ var photoshop__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(photoshop__WEBPACK_IMPORTED_MODULE_0__);
|
||||
|
||||
class HistoryChecker {
|
||||
static instance = null;
|
||||
static createInstance() {
|
||||
if (HistoryChecker.instance) {
|
||||
return HistoryChecker.instance;
|
||||
}
|
||||
return new HistoryChecker();
|
||||
}
|
||||
constructor() {
|
||||
HistoryChecker.instance = this;
|
||||
this.lastCheckId = -1;
|
||||
this.changeCallback = null;
|
||||
// this.timer = setInterval(() => {
|
||||
// this.checkHistoryState();
|
||||
// }, 1000)
|
||||
photoshop__WEBPACK_IMPORTED_MODULE_0__.action.addNotificationListener("historyStateChanged", () => {
|
||||
this.checkHistoryState();
|
||||
});
|
||||
}
|
||||
destroy() {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
this.changeCallback = null;
|
||||
HistoryChecker.instance = null;
|
||||
}
|
||||
setChangeCallback(callback) {
|
||||
this.changeCallback = callback;
|
||||
}
|
||||
checkHistoryState() {
|
||||
const historyStates = photoshop__WEBPACK_IMPORTED_MODULE_0__.app.activeDocument?.historyStates;
|
||||
if (!historyStates || historyStates.length == 0) return;
|
||||
const historyState = historyStates[historyStates.length - 1];
|
||||
const historyId = historyState.id;
|
||||
if (this.lastCheckId == historyId) return;
|
||||
this.lastCheckId = historyId;
|
||||
if (this.changeCallback) this.changeCallback(historyId);
|
||||
}
|
||||
}
|
||||
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (HistoryChecker);
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./src/system/jimp.min.js":
|
||||
/*!********************************!*\
|
||||
!*** ./src/system/jimp.min.js ***!
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import ComfyConnection from "../system/ComfyConnection";
|
||||
import HistoryChecker from "../system/HistoryChecker";
|
||||
import { storage } from "uxp";
|
||||
|
||||
export default class Main extends React.Component {
|
||||
@@ -16,6 +17,14 @@ export default class Main extends React.Component {
|
||||
isConnected: instance?.isConnected,
|
||||
comfyURL: instance ? instance.comfyURL : ''
|
||||
})
|
||||
if (instance?.isConnected) {
|
||||
const hc = HistoryChecker.createInstance();
|
||||
hc.setChangeCallback((historyId) => {
|
||||
instance.pushData({history_state_id: historyId})
|
||||
});
|
||||
} else {
|
||||
HistoryChecker.instance?.destroy();
|
||||
}
|
||||
});
|
||||
storage.secureStorage.getItem('comfyURL').then((value) => {
|
||||
if (!value) return
|
||||
|
||||
@@ -131,6 +131,18 @@ class ComfyConnection {
|
||||
this.connect();
|
||||
}
|
||||
|
||||
pushData(data) {
|
||||
if (!this.socket || this.socket.readyState != WebSocket.OPEN) {
|
||||
console.error('Connection not open');
|
||||
return;
|
||||
}
|
||||
try{
|
||||
this.socket.send(JSON.stringify({
|
||||
push_data: data,
|
||||
}));
|
||||
} catch (e) { console.error(e) }
|
||||
}
|
||||
|
||||
async onMessage(event) {
|
||||
console.log("Message from comfy ", event.data);
|
||||
try {
|
||||
@@ -280,14 +292,16 @@ class ComfyConnection {
|
||||
|
||||
} else if (payload.action == 'get_active_history_state_id') {
|
||||
try {
|
||||
const historyStates = app.activeDocument.historyStates;
|
||||
const historyState = historyStates[historyStates.length - 1];
|
||||
let result = {};
|
||||
const historyStates = app.activeDocument?.historyStates;
|
||||
if (historyStates && historyStates.length > 0) {
|
||||
const historyState = historyStates[historyStates.length - 1];
|
||||
result.history_state_id = historyState.id;
|
||||
}
|
||||
this.socket.send(
|
||||
JSON.stringify({
|
||||
call_id: payload.call_id,
|
||||
result: {
|
||||
history_state_id: historyState.id,
|
||||
}
|
||||
result: result
|
||||
})
|
||||
)
|
||||
} catch (e) {
|
||||
@@ -326,6 +340,7 @@ class ComfyConnection {
|
||||
this._isConnected = false;
|
||||
ComfyConnection._callConnectStateChange();
|
||||
});
|
||||
|
||||
socket.addEventListener('error', (event) => {
|
||||
console.log("Connection error", event);
|
||||
this.reconnectTimer = setTimeout(() => {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import {app, action} from "photoshop";
|
||||
|
||||
class HistoryChecker {
|
||||
static instance = null;
|
||||
static createInstance() {
|
||||
if (HistoryChecker.instance) {
|
||||
return HistoryChecker.instance;
|
||||
}
|
||||
return new HistoryChecker();
|
||||
}
|
||||
constructor() {
|
||||
HistoryChecker.instance = this;
|
||||
this.lastCheckId = -1;
|
||||
this.changeCallback = null;
|
||||
// this.timer = setInterval(() => {
|
||||
// this.checkHistoryState();
|
||||
// }, 1000)
|
||||
action.addNotificationListener("historyStateChanged", () => {
|
||||
this.checkHistoryState();
|
||||
});
|
||||
}
|
||||
|
||||
destroy() {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
this.changeCallback = null;
|
||||
HistoryChecker.instance = null;
|
||||
}
|
||||
|
||||
setChangeCallback(callback) {
|
||||
this.changeCallback = callback;
|
||||
}
|
||||
|
||||
checkHistoryState() {
|
||||
const historyStates = app.activeDocument?.historyStates;
|
||||
if (!historyStates || historyStates.length == 0) return;
|
||||
const historyState = historyStates[historyStates.length - 1];
|
||||
const historyId = historyState.id;
|
||||
if (this.lastCheckId == historyId) return;
|
||||
this.lastCheckId = historyId;
|
||||
if (this.changeCallback)
|
||||
this.changeCallback(historyId);
|
||||
}
|
||||
}
|
||||
|
||||
export default HistoryChecker;
|
||||
Reference in New Issue
Block a user