tidy(ui): clean up CanvasFilter class

This commit is contained in:
psychedelicious 2024-08-22 14:43:00 +10:00
parent fee293e289
commit c54bc32ef6
2 changed files with 57 additions and 47 deletions

View File

@ -7,8 +7,7 @@ import { IMAGE_FILTERS, imageDTOToImageObject } from 'features/controlLayers/sto
import { atom } from 'nanostores'; import { atom } from 'nanostores';
import type { Logger } from 'roarr'; import type { Logger } from 'roarr';
import { getImageDTO } from 'services/api/endpoints/images'; import { getImageDTO } from 'services/api/endpoints/images';
import { queueApi } from 'services/api/endpoints/queue'; import type { BatchConfig, ImageDTO } from 'services/api/types';
import type { BatchConfig } from 'services/api/types';
import type { InvocationCompleteEvent } from 'services/events/types'; import type { InvocationCompleteEvent } from 'services/events/types';
import { assert } from 'tsafe'; import { assert } from 'tsafe';
@ -58,33 +57,14 @@ export class CanvasFilter {
} }
const config = this.$config.get(); const config = this.$config.get();
this.log.trace({ config }, 'Previewing filter'); this.log.trace({ config }, 'Previewing filter');
const dispatch = this.manager.stateApi._store.dispatch;
const rect = adapter.transformer.getRelativeRect(); const rect = adapter.transformer.getRelativeRect();
const imageDTO = await adapter.renderer.rasterize({ rect }); 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 nodeId = getPrefixedId('filter_node');
const filterNode = IMAGE_FILTERS[config.type].buildNode(imageDTO, config as never); const batch = this.buildBatchConfig(imageDTO, config, nodeId);
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,
},
};
// Listen for the filter processing completion event // Listen for the filter processing completion event
const listener = async (event: InvocationCompleteEvent) => { 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; return;
} }
this.manager.socket.off('invocation_complete', listener); this.manager.socket.off('invocation_complete', listener);
@ -108,14 +88,10 @@ export class CanvasFilter {
this.manager.socket.on('invocation_complete', listener); 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); this.$isProcessing.set(true);
dispatch( this.manager.stateApi.enqueueBatch(batch);
queueApi.endpoints.enqueueBatch.initiate(enqueueBatchArg, {
fixedCacheKey: 'enqueueBatch',
})
);
}; };
applyFilter = () => { applyFilter = () => {
@ -162,6 +138,32 @@ export class CanvasFilter {
this.$isProcessing.set(false); 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 = () => { destroy = () => {
this.log.trace('Destroying filter'); this.log.trace('Destroying filter');
}; };

View File

@ -47,6 +47,8 @@ import type {
import { RGBA_BLACK } from 'features/controlLayers/store/types'; import { RGBA_BLACK } from 'features/controlLayers/store/types';
import type { WritableAtom } from 'nanostores'; import type { WritableAtom } from 'nanostores';
import { atom } 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'; import { $lastCanvasProgressEvent } from 'services/events/setEventListeners';
type EntityStateAndAdapter = type EntityStateAndAdapter =
@ -76,58 +78,64 @@ type EntityStateAndAdapter =
}; };
export class CanvasStateApi { export class CanvasStateApi {
_store: AppStore; store: AppStore;
manager: CanvasManager; manager: CanvasManager;
constructor(store: AppStore, manager: CanvasManager) { constructor(store: AppStore, manager: CanvasManager) {
this._store = store; this.store = store;
this.manager = manager; this.manager = manager;
} }
// Reminder - use arrow functions to avoid binding issues // Reminder - use arrow functions to avoid binding issues
getState = () => { getState = () => {
return this._store.getState().canvasV2; return this.store.getState().canvasV2;
}; };
resetEntity = (arg: EntityIdentifierPayload) => { resetEntity = (arg: EntityIdentifierPayload) => {
this._store.dispatch(entityReset(arg)); this.store.dispatch(entityReset(arg));
}; };
setEntityPosition = (arg: EntityMovedPayload) => { setEntityPosition = (arg: EntityMovedPayload) => {
this._store.dispatch(entityMoved(arg)); this.store.dispatch(entityMoved(arg));
}; };
addBrushLine = (arg: EntityBrushLineAddedPayload) => { addBrushLine = (arg: EntityBrushLineAddedPayload) => {
this._store.dispatch(entityBrushLineAdded(arg)); this.store.dispatch(entityBrushLineAdded(arg));
}; };
addEraserLine = (arg: EntityEraserLineAddedPayload) => { addEraserLine = (arg: EntityEraserLineAddedPayload) => {
this._store.dispatch(entityEraserLineAdded(arg)); this.store.dispatch(entityEraserLineAdded(arg));
}; };
addRect = (arg: EntityRectAddedPayload) => { addRect = (arg: EntityRectAddedPayload) => {
this._store.dispatch(entityRectAdded(arg)); this.store.dispatch(entityRectAdded(arg));
}; };
rasterizeEntity = (arg: EntityRasterizedPayload) => { rasterizeEntity = (arg: EntityRasterizedPayload) => {
this._store.dispatch(entityRasterized(arg)); this.store.dispatch(entityRasterized(arg));
}; };
setSelectedEntity = (arg: EntityIdentifierPayload) => { setSelectedEntity = (arg: EntityIdentifierPayload) => {
this._store.dispatch(entitySelected(arg)); this.store.dispatch(entitySelected(arg));
}; };
setGenerationBbox = (bbox: Rect) => { setGenerationBbox = (bbox: Rect) => {
this._store.dispatch(bboxChanged(bbox)); this.store.dispatch(bboxChanged(bbox));
}; };
setBrushWidth = (width: number) => { setBrushWidth = (width: number) => {
this._store.dispatch(brushWidthChanged(width)); this.store.dispatch(brushWidthChanged(width));
}; };
setEraserWidth = (width: number) => { setEraserWidth = (width: number) => {
this._store.dispatch(eraserWidthChanged(width)); this.store.dispatch(eraserWidthChanged(width));
}; };
setTool = (tool: Tool) => { setTool = (tool: Tool) => {
this._store.dispatch(toolChanged(tool)); this.store.dispatch(toolChanged(tool));
}; };
setToolBuffer = (toolBuffer: Tool | null) => { setToolBuffer = (toolBuffer: Tool | null) => {
this._store.dispatch(toolBufferChanged(toolBuffer)); this.store.dispatch(toolBufferChanged(toolBuffer));
}; };
setFill = (fill: RgbaColor) => { 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 = () => { getBbox = () => {
return this.getState().bbox; return this.getState().bbox;
}; };