mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
tidy(ui): abstract worker logic to module
This commit is contained in:
parent
b4d656c203
commit
68fad5cdcc
@ -4,15 +4,14 @@ import type { AppStore } from 'app/store/store';
|
|||||||
import type { SerializableObject } from 'common/types';
|
import type { SerializableObject } from 'common/types';
|
||||||
import { CanvasFilter } from 'features/controlLayers/konva/CanvasFilter';
|
import { CanvasFilter } from 'features/controlLayers/konva/CanvasFilter';
|
||||||
import { CanvasStageModule } from 'features/controlLayers/konva/CanvasStageModule';
|
import { CanvasStageModule } from 'features/controlLayers/konva/CanvasStageModule';
|
||||||
|
import { CanvasWorkerModule } from 'features/controlLayers/konva/CanvasWorkerModule.js';
|
||||||
import {
|
import {
|
||||||
canvasToBlob,
|
canvasToBlob,
|
||||||
canvasToImageData,
|
canvasToImageData,
|
||||||
getImageDataTransparency,
|
getImageDataTransparency,
|
||||||
getPrefixedId,
|
getPrefixedId,
|
||||||
nanoid,
|
|
||||||
previewBlob,
|
previewBlob,
|
||||||
} from 'features/controlLayers/konva/util';
|
} from 'features/controlLayers/konva/util';
|
||||||
import type { Extents, ExtentsResult, GetBboxTask, WorkerLogMessage } from 'features/controlLayers/konva/worker';
|
|
||||||
import type { CanvasV2State, GenerationMode, Rect } from 'features/controlLayers/store/types';
|
import type { CanvasV2State, GenerationMode, Rect } from 'features/controlLayers/store/types';
|
||||||
import type Konva from 'konva';
|
import type Konva from 'konva';
|
||||||
import { LRUCache } from 'lru-cache';
|
import { LRUCache } from 'lru-cache';
|
||||||
@ -48,6 +47,7 @@ export class CanvasManager {
|
|||||||
background: CanvasBackground;
|
background: CanvasBackground;
|
||||||
filter: CanvasFilter;
|
filter: CanvasFilter;
|
||||||
stage: CanvasStageModule;
|
stage: CanvasStageModule;
|
||||||
|
worker: CanvasWorkerModule;
|
||||||
|
|
||||||
log: Logger;
|
log: Logger;
|
||||||
socket: AppSocket;
|
socket: AppSocket;
|
||||||
@ -61,9 +61,6 @@ export class CanvasManager {
|
|||||||
canvasCache = new LRUCache<string, HTMLCanvasElement>({ max: 32 });
|
canvasCache = new LRUCache<string, HTMLCanvasElement>({ max: 32 });
|
||||||
generationModeCache = new LRUCache<string, GenerationMode>({ max: 100 });
|
generationModeCache = new LRUCache<string, GenerationMode>({ max: 100 });
|
||||||
|
|
||||||
_worker: Worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module', name: 'worker' });
|
|
||||||
_tasks: Map<string, { task: GetBboxTask; onComplete: (extents: Extents | null) => void }> = new Map();
|
|
||||||
|
|
||||||
constructor(stage: Konva.Stage, container: HTMLDivElement, store: AppStore, socket: AppSocket) {
|
constructor(stage: Konva.Stage, container: HTMLDivElement, store: AppStore, socket: AppSocket) {
|
||||||
this.id = getPrefixedId(this.type);
|
this.id = getPrefixedId(this.type);
|
||||||
this.path = [this.id];
|
this.path = [this.id];
|
||||||
@ -85,6 +82,7 @@ export class CanvasManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.stage = new CanvasStageModule(stage, container, this);
|
this.stage = new CanvasStageModule(stage, container, this);
|
||||||
|
this.worker = new CanvasWorkerModule(this);
|
||||||
|
|
||||||
this.preview = new CanvasPreview(this);
|
this.preview = new CanvasPreview(this);
|
||||||
this.stage.addLayer(this.preview.getLayer());
|
this.stage.addLayer(this.preview.getLayer());
|
||||||
@ -94,30 +92,6 @@ export class CanvasManager {
|
|||||||
|
|
||||||
this.filter = new CanvasFilter(this);
|
this.filter = new CanvasFilter(this);
|
||||||
|
|
||||||
this._worker.onmessage = (event: MessageEvent<ExtentsResult | WorkerLogMessage>) => {
|
|
||||||
const { type, data } = event.data;
|
|
||||||
if (type === 'log') {
|
|
||||||
if (data.ctx) {
|
|
||||||
this.log[data.level](data.ctx, data.message);
|
|
||||||
} else {
|
|
||||||
this.log[data.level](data.message);
|
|
||||||
}
|
|
||||||
} else if (type === 'extents') {
|
|
||||||
const task = this._tasks.get(data.id);
|
|
||||||
if (!task) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
task.onComplete(data.extents);
|
|
||||||
this._tasks.delete(data.id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this._worker.onerror = (event) => {
|
|
||||||
this.log.error({ message: event.message }, 'Worker error');
|
|
||||||
};
|
|
||||||
this._worker.onmessageerror = () => {
|
|
||||||
this.log.error('Worker message error');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.stateApi.$transformingEntity.set(null);
|
this.stateApi.$transformingEntity.set(null);
|
||||||
this.stateApi.$toolState.set(this.stateApi.getToolState());
|
this.stateApi.$toolState.set(this.stateApi.getToolState());
|
||||||
this.stateApi.$selectedEntityIdentifier.set(this.stateApi.getState().selectedEntityIdentifier);
|
this.stateApi.$selectedEntityIdentifier.set(this.stateApi.getState().selectedEntityIdentifier);
|
||||||
@ -134,16 +108,6 @@ export class CanvasManager {
|
|||||||
this._isDebugging = false;
|
this._isDebugging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBbox(data: Omit<GetBboxTask['data'], 'id'>, onComplete: (extents: Extents | null) => void) {
|
|
||||||
const id = nanoid();
|
|
||||||
const task: GetBboxTask = {
|
|
||||||
type: 'get_bbox',
|
|
||||||
data: { ...data, id },
|
|
||||||
};
|
|
||||||
this._tasks.set(id, { task, onComplete });
|
|
||||||
this._worker.postMessage(task, [data.buffer]);
|
|
||||||
}
|
|
||||||
|
|
||||||
arrangeEntities() {
|
arrangeEntities() {
|
||||||
let zIndex = 0;
|
let zIndex = 0;
|
||||||
|
|
||||||
|
@ -651,7 +651,7 @@ export class CanvasTransformer {
|
|||||||
// We have eraser strokes - we must calculate the bbox using pixel data
|
// We have eraser strokes - we must calculate the bbox using pixel data
|
||||||
const canvas = this.parent.renderer.getCanvas(undefined, { opacity: 1 });
|
const canvas = this.parent.renderer.getCanvas(undefined, { opacity: 1 });
|
||||||
const imageData = canvasToImageData(canvas);
|
const imageData = canvasToImageData(canvas);
|
||||||
this.manager.requestBbox(
|
this.manager.worker.requestBbox(
|
||||||
{ buffer: imageData.data.buffer, width: imageData.width, height: imageData.height },
|
{ buffer: imageData.data.buffer, width: imageData.width, height: imageData.height },
|
||||||
(extents) => {
|
(extents) => {
|
||||||
if (extents) {
|
if (extents) {
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
import type { SerializableObject } from 'common/types';
|
||||||
|
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
||||||
|
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||||
|
import type { Extents, ExtentsResult, GetBboxTask, WorkerLogMessage } from 'features/controlLayers/konva/worker';
|
||||||
|
import type { Logger } from 'roarr';
|
||||||
|
|
||||||
|
export class CanvasWorkerModule {
|
||||||
|
id: string;
|
||||||
|
path: string[];
|
||||||
|
log: Logger;
|
||||||
|
manager: CanvasManager;
|
||||||
|
|
||||||
|
worker: Worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module', name: 'worker' });
|
||||||
|
tasks: Map<string, { task: GetBboxTask; onComplete: (extents: Extents | null) => void }> = new Map();
|
||||||
|
|
||||||
|
constructor(manager: CanvasManager) {
|
||||||
|
this.id = getPrefixedId('worker');
|
||||||
|
this.manager = manager;
|
||||||
|
this.path = this.manager.path.concat(this.id);
|
||||||
|
this.log = this.manager.buildLogger(this.getLoggingContext);
|
||||||
|
this.log.debug('Creating canvas worker');
|
||||||
|
|
||||||
|
this.worker.onmessage = (event: MessageEvent<ExtentsResult | WorkerLogMessage>) => {
|
||||||
|
const { type, data } = event.data;
|
||||||
|
if (type === 'log') {
|
||||||
|
if (data.ctx) {
|
||||||
|
this.log[data.level](data.ctx, data.message);
|
||||||
|
} else {
|
||||||
|
this.log[data.level](data.message);
|
||||||
|
}
|
||||||
|
} else if (type === 'extents') {
|
||||||
|
const task = this.tasks.get(data.id);
|
||||||
|
if (!task) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
task.onComplete(data.extents);
|
||||||
|
this.tasks.delete(data.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.worker.onerror = (event) => {
|
||||||
|
this.log.error({ message: event.message }, 'Worker error');
|
||||||
|
};
|
||||||
|
this.worker.onmessageerror = () => {
|
||||||
|
this.log.error('Worker message error');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
requestBbox(data: Omit<GetBboxTask['data'], 'id'>, onComplete: (extents: Extents | null) => void) {
|
||||||
|
const id = getPrefixedId('bbox_calculation');
|
||||||
|
const task: GetBboxTask = {
|
||||||
|
type: 'get_bbox',
|
||||||
|
data: { ...data, id },
|
||||||
|
};
|
||||||
|
this.tasks.set(id, { task, onComplete });
|
||||||
|
this.worker.postMessage(task, [data.buffer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLoggingContext = (): SerializableObject => {
|
||||||
|
return { ...this.manager.getLoggingContext(), path: this.path.join('.') };
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user