From c54bc32ef61b60a6c261a9f2d3fef98b24c2121e Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:43:00 +1000 Subject: [PATCH] tidy(ui): clean up CanvasFilter class --- .../controlLayers/konva/CanvasFilter.ts | 62 ++++++++++--------- .../controlLayers/konva/CanvasStateApi.ts | 42 ++++++++----- 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasFilter.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasFilter.ts index 14c7f706ff..e351ded88e 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasFilter.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasFilter.ts @@ -7,8 +7,7 @@ import { IMAGE_FILTERS, imageDTOToImageObject } from 'features/controlLayers/sto import { atom } from 'nanostores'; import type { Logger } from 'roarr'; import { getImageDTO } from 'services/api/endpoints/images'; -import { queueApi } from 'services/api/endpoints/queue'; -import type { BatchConfig } from 'services/api/types'; +import type { BatchConfig, ImageDTO } from 'services/api/types'; import type { InvocationCompleteEvent } from 'services/events/types'; import { assert } from 'tsafe'; @@ -58,33 +57,14 @@ export class CanvasFilter { } const config = this.$config.get(); this.log.trace({ config }, 'Previewing filter'); - const dispatch = this.manager.stateApi._store.dispatch; const rect = adapter.transformer.getRelativeRect(); const imageDTO = await adapter.renderer.rasterize({ rect }); - // TODO(psyche): I can't get TS to be happy, it thinkgs `config` is `never` but it should be inferred from the generic... I'll just cast it for now - const filterNode = IMAGE_FILTERS[config.type].buildNode(imageDTO, config as never); - const enqueueBatchArg: BatchConfig = { - prepend: true, - batch: { - graph: { - nodes: { - [filterNode.id]: { - ...filterNode, - // Control images are always intermediate - do not save to gallery - // is_intermediate: true, - is_intermediate: false, // false for testing - }, - }, - edges: [], - }, - origin: this.id, - runs: 1, - }, - }; + const nodeId = getPrefixedId('filter_node'); + const batch = this.buildBatchConfig(imageDTO, config, nodeId); // Listen for the filter processing completion event const listener = async (event: InvocationCompleteEvent) => { - if (event.origin !== this.id || event.invocation_source_id !== filterNode.id) { + if (event.origin !== this.id || event.invocation_source_id !== nodeId) { return; } this.manager.socket.off('invocation_complete', listener); @@ -108,14 +88,10 @@ export class CanvasFilter { this.manager.socket.on('invocation_complete', listener); - this.log.trace({ enqueueBatchArg } as SerializableObject, 'Enqueuing filter batch'); + this.log.trace({ batch } as SerializableObject, 'Enqueuing filter batch'); this.$isProcessing.set(true); - dispatch( - queueApi.endpoints.enqueueBatch.initiate(enqueueBatchArg, { - fixedCacheKey: 'enqueueBatch', - }) - ); + this.manager.stateApi.enqueueBatch(batch); }; applyFilter = () => { @@ -162,6 +138,32 @@ export class CanvasFilter { this.$isProcessing.set(false); }; + buildBatchConfig = (imageDTO: ImageDTO, config: FilterConfig, id: string): BatchConfig => { + // TODO(psyche): I can't get TS to be happy, it thinkgs `config` is `never` but it should be inferred from the generic... I'll just cast it for now + const node = IMAGE_FILTERS[config.type].buildNode(imageDTO, config as never); + node.id = id; + const batch: BatchConfig = { + prepend: true, + batch: { + graph: { + nodes: { + [node.id]: { + ...node, + // Control images are always intermediate - do not save to gallery + // is_intermediate: true, + is_intermediate: false, // false for testing + }, + }, + edges: [], + }, + origin: this.id, + runs: 1, + }, + }; + + return batch; + }; + destroy = () => { this.log.trace('Destroying filter'); }; diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts index fedc0b8461..2dd7040e12 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts @@ -47,6 +47,8 @@ import type { import { RGBA_BLACK } from 'features/controlLayers/store/types'; import type { WritableAtom } from 'nanostores'; import { atom } from 'nanostores'; +import { queueApi } from 'services/api/endpoints/queue'; +import type { BatchConfig } from 'services/api/types'; import { $lastCanvasProgressEvent } from 'services/events/setEventListeners'; type EntityStateAndAdapter = @@ -76,58 +78,64 @@ type EntityStateAndAdapter = }; export class CanvasStateApi { - _store: AppStore; + store: AppStore; manager: CanvasManager; constructor(store: AppStore, manager: CanvasManager) { - this._store = store; + this.store = store; this.manager = manager; } // Reminder - use arrow functions to avoid binding issues getState = () => { - return this._store.getState().canvasV2; + return this.store.getState().canvasV2; }; resetEntity = (arg: EntityIdentifierPayload) => { - this._store.dispatch(entityReset(arg)); + this.store.dispatch(entityReset(arg)); }; setEntityPosition = (arg: EntityMovedPayload) => { - this._store.dispatch(entityMoved(arg)); + this.store.dispatch(entityMoved(arg)); }; addBrushLine = (arg: EntityBrushLineAddedPayload) => { - this._store.dispatch(entityBrushLineAdded(arg)); + this.store.dispatch(entityBrushLineAdded(arg)); }; addEraserLine = (arg: EntityEraserLineAddedPayload) => { - this._store.dispatch(entityEraserLineAdded(arg)); + this.store.dispatch(entityEraserLineAdded(arg)); }; addRect = (arg: EntityRectAddedPayload) => { - this._store.dispatch(entityRectAdded(arg)); + this.store.dispatch(entityRectAdded(arg)); }; rasterizeEntity = (arg: EntityRasterizedPayload) => { - this._store.dispatch(entityRasterized(arg)); + this.store.dispatch(entityRasterized(arg)); }; setSelectedEntity = (arg: EntityIdentifierPayload) => { - this._store.dispatch(entitySelected(arg)); + this.store.dispatch(entitySelected(arg)); }; setGenerationBbox = (bbox: Rect) => { - this._store.dispatch(bboxChanged(bbox)); + this.store.dispatch(bboxChanged(bbox)); }; setBrushWidth = (width: number) => { - this._store.dispatch(brushWidthChanged(width)); + this.store.dispatch(brushWidthChanged(width)); }; setEraserWidth = (width: number) => { - this._store.dispatch(eraserWidthChanged(width)); + this.store.dispatch(eraserWidthChanged(width)); }; setTool = (tool: Tool) => { - this._store.dispatch(toolChanged(tool)); + this.store.dispatch(toolChanged(tool)); }; setToolBuffer = (toolBuffer: Tool | null) => { - this._store.dispatch(toolBufferChanged(toolBuffer)); + this.store.dispatch(toolBufferChanged(toolBuffer)); }; setFill = (fill: RgbaColor) => { - return this._store.dispatch(fillChanged(fill)); + return this.store.dispatch(fillChanged(fill)); + }; + enqueueBatch = (batch: BatchConfig) => { + this.store.dispatch( + queueApi.endpoints.enqueueBatch.initiate(batch, { + fixedCacheKey: 'enqueueBatch', + }) + ); }; - getBbox = () => { return this.getState().bbox; };