dream queueing now supported
- Image navigation shortcuts work for all simultaneously (probably not optimal) This is for #89. Some things should be ironed out, such as adding a cancel button for future jobs and an order indicator maybe? Signed-off-by: Victor Seiji Hariki <victorseijih@gmail.com>
This commit is contained in:
parent
e3be9010f2
commit
f279c8457b
2 changed files with 277 additions and 235 deletions
|
@ -1,4 +1,6 @@
|
|||
let blockNewImages = false;
|
||||
let generationQueue = [];
|
||||
let generationAreas = new Set();
|
||||
let generating = false;
|
||||
|
||||
/**
|
||||
|
@ -118,7 +120,50 @@ const _generate = async (
|
|||
bb,
|
||||
drawEvery = 0.2 / request.n_iter
|
||||
) => {
|
||||
const requestCopy = {...request};
|
||||
const requestCopy = JSON.parse(JSON.stringify(request));
|
||||
|
||||
// Block requests to identical areas
|
||||
const areaid = `${bb.x}-${bb.y}-${bb.w}-${bb.h}`;
|
||||
if (generationAreas.has(areaid)) return;
|
||||
generationAreas.add(areaid);
|
||||
|
||||
// Await for queue
|
||||
const waitQueue = async () => {
|
||||
const stopQueueMarchingAnts = march(bb, {style: "#AAF"});
|
||||
|
||||
let qPromise = null;
|
||||
let qResolve = null;
|
||||
await new Promise((finish) => {
|
||||
// Will be this request's (kind of) semaphore
|
||||
qPromise = new Promise((r) => (qResolve = r));
|
||||
generationQueue.push(qPromise);
|
||||
|
||||
// Wait for last generation to end
|
||||
if (generationQueue.length > 1) {
|
||||
(async () => {
|
||||
await generationQueue[generationQueue.length - 2];
|
||||
finish();
|
||||
})();
|
||||
} else {
|
||||
// If this is the first, just continue
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
stopQueueMarchingAnts();
|
||||
|
||||
return {promise: qPromise, resolve: qResolve};
|
||||
};
|
||||
|
||||
const nextQueue = (queueEntry) => {
|
||||
const generationIndex = generationQueue.findIndex(
|
||||
(v) => v === queueEntry.promise
|
||||
);
|
||||
generationQueue.splice(generationIndex, 1);
|
||||
queueEntry.resolve();
|
||||
};
|
||||
|
||||
const initialQ = await waitQueue();
|
||||
|
||||
// Images to select through
|
||||
let at = 0;
|
||||
|
@ -253,6 +298,7 @@ const _generate = async (
|
|||
};
|
||||
|
||||
const makeMore = async () => {
|
||||
const moreQ = await waitQueue();
|
||||
try {
|
||||
stopProgress = _monitorProgress(bb);
|
||||
interruptButton.disabled = false;
|
||||
|
@ -269,6 +315,8 @@ const _generate = async (
|
|||
stopProgress();
|
||||
imageCollection.inputElement.removeChild(interruptButton);
|
||||
}
|
||||
|
||||
nextQueue(moreQ);
|
||||
};
|
||||
|
||||
const discardImg = async () => {
|
||||
|
@ -342,8 +390,9 @@ const _generate = async (
|
|||
stopMarchingAnts();
|
||||
imageCollection.inputElement.removeChild(imageSelectMenu);
|
||||
imageCollection.deleteLayer(layer);
|
||||
blockNewImages = false;
|
||||
keyboard.listen.onkeyclick.clear(onarrow);
|
||||
// Remove area from no-generate list
|
||||
generationAreas.delete(areaid);
|
||||
};
|
||||
|
||||
redraw();
|
||||
|
@ -414,6 +463,8 @@ const _generate = async (
|
|||
saveImg();
|
||||
});
|
||||
imageSelectMenu.appendChild(savebtn);
|
||||
|
||||
nextQueue(initialQ);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -423,7 +474,6 @@ const _generate = async (
|
|||
* @param {*} state
|
||||
*/
|
||||
const dream_generate_callback = async (evn, state) => {
|
||||
if (!blockNewImages) {
|
||||
const bb = getBoundingBox(
|
||||
evn.x,
|
||||
evn.y,
|
||||
|
@ -440,9 +490,6 @@ const dream_generate_callback = async (evn, state) => {
|
|||
request.prompt = document.getElementById("prompt").value;
|
||||
request.negative_prompt = document.getElementById("negPrompt").value;
|
||||
|
||||
// Don't allow another image until is finished
|
||||
blockNewImages = true;
|
||||
|
||||
// Get visible pixels
|
||||
const visibleCanvas = uil.getVisible(bb);
|
||||
|
||||
|
@ -550,7 +597,6 @@ const dream_generate_callback = async (evn, state) => {
|
|||
// Dream
|
||||
_generate("img2img", request, bb);
|
||||
}
|
||||
}
|
||||
};
|
||||
const dream_erase_callback = (evn, state) => {
|
||||
const bb = getBoundingBox(
|
||||
|
@ -606,7 +652,6 @@ function applyOvermask(canvas, ctx, px) {
|
|||
* Image to Image
|
||||
*/
|
||||
const dream_img2img_callback = (evn, state) => {
|
||||
if (!blockNewImages) {
|
||||
const bb = getBoundingBox(
|
||||
evn.x,
|
||||
evn.y,
|
||||
|
@ -632,9 +677,6 @@ const dream_img2img_callback = (evn, state) => {
|
|||
request.prompt = document.getElementById("prompt").value;
|
||||
request.negative_prompt = document.getElementById("negPrompt").value;
|
||||
|
||||
// Don't allow another image until is finished
|
||||
blockNewImages = true;
|
||||
|
||||
// Use img2img
|
||||
|
||||
// Temporary canvas for init image and mask generation
|
||||
|
@ -739,7 +781,6 @@ const dream_img2img_callback = (evn, state) => {
|
|||
|
||||
// Dream
|
||||
_generate("img2img", request, bb);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -181,6 +181,7 @@ const stampTool = () =>
|
|||
saveButton.addEventListener(
|
||||
"click",
|
||||
(evn) => {
|
||||
evn.stopPropagation();
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = resource.image.width;
|
||||
canvas.height = resource.image.height;
|
||||
|
|
Loading…
Reference in a new issue