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 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');
};

View File

@ -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;
};