From 81adce3238ebb7aede76e9874ad7d20c1088dc7a Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:43:27 +1000 Subject: [PATCH] feat(ui): remove inheritance of CanvasObject JS is terrible --- .../controlLayers/konva/CanvasBrushLine.ts | 28 +++++++++---- .../controlLayers/konva/CanvasEntity.ts | 2 +- .../controlLayers/konva/CanvasEraserLine.ts | 27 +++++++++---- .../controlLayers/konva/CanvasImage.ts | 37 +++++++++++------- .../konva/CanvasInteractionRect.ts | 27 ++++++++----- .../controlLayers/konva/CanvasManager.ts | 35 ++++++++++++++++- .../controlLayers/konva/CanvasObject.ts | 39 ------------------- .../controlLayers/konva/CanvasRect.ts | 26 +++++++++---- .../controlLayers/konva/CanvasTransformer.ts | 21 ++++++++-- 9 files changed, 149 insertions(+), 93 deletions(-) delete mode 100644 invokeai/frontend/web/src/features/controlLayers/konva/CanvasObject.ts diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBrushLine.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBrushLine.ts index acafcf3b27..d81a413f83 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBrushLine.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasBrushLine.ts @@ -1,15 +1,22 @@ +import type { JSONObject } from 'common/types'; import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import { deepClone } from 'common/util/deepClone'; import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer'; -import { CanvasObject } from 'features/controlLayers/konva/CanvasObject'; +import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { BrushLine } from 'features/controlLayers/store/types'; import Konva from 'konva'; +import type { Logger } from 'roarr'; -export class CanvasBrushLine extends CanvasObject { - static NAME_PREFIX = 'brush-line'; - static GROUP_NAME = `${CanvasBrushLine.NAME_PREFIX}_group`; - static LINE_NAME = `${CanvasBrushLine.NAME_PREFIX}_line`; +export class CanvasBrushLine { static TYPE = 'brush_line'; + static GROUP_NAME = `${CanvasBrushLine.TYPE}_group`; + static LINE_NAME = `${CanvasBrushLine.TYPE}_line`; + + id: string; + parent: CanvasLayer; + manager: CanvasManager; + log: Logger; + getLoggingContext: (extra?: JSONObject) => JSONObject; state: BrushLine; konva: { @@ -18,10 +25,15 @@ export class CanvasBrushLine extends CanvasObject { }; constructor(state: BrushLine, parent: CanvasLayer) { - super(state.id, parent); - this.log.trace({ state }, 'Creating brush line'); + const { id, strokeWidth, clip, color, points } = state; + this.id = id; + this.parent = parent; + this.manager = parent.manager; - const { strokeWidth, clip, color, points } = state; + this.getLoggingContext = this.manager.buildObjectGetLoggingContext(this); + this.log = this.manager.buildLogger(this.getLoggingContext); + + this.log.trace({ state }, 'Creating brush line'); this.konva = { group: new Konva.Group({ diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity.ts index b9775cd2c1..626704d2be 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity.ts @@ -19,7 +19,7 @@ export abstract class CanvasEntity { getLoggingContext = (extra?: Record) => { return { - ...this.manager._getLoggingContext(), + ...this.manager.getLoggingContext(), layerId: this.id, ...extra, }; diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEraserLine.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEraserLine.ts index 64e7595f0e..1fe08559cb 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEraserLine.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEraserLine.ts @@ -1,16 +1,23 @@ +import type { JSONObject } from 'common/types'; import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import { deepClone } from 'common/util/deepClone'; import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer'; -import { CanvasObject } from 'features/controlLayers/konva/CanvasObject'; +import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { EraserLine } from 'features/controlLayers/store/types'; import { RGBA_RED } from 'features/controlLayers/store/types'; import Konva from 'konva'; +import type { Logger } from 'roarr'; -export class CanvasEraserLine extends CanvasObject { - static NAME_PREFIX = 'eraser-line'; - static GROUP_NAME = `${CanvasEraserLine.NAME_PREFIX}_group`; - static LINE_NAME = `${CanvasEraserLine.NAME_PREFIX}_line`; +export class CanvasEraserLine { static TYPE = 'eraser_line'; + static GROUP_NAME = `${CanvasEraserLine.TYPE}_group`; + static LINE_NAME = `${CanvasEraserLine.TYPE}_line`; + + id: string; + parent: CanvasLayer; + manager: CanvasManager; + log: Logger; + getLoggingContext: (extra?: JSONObject) => JSONObject; state: EraserLine; konva: { @@ -19,10 +26,14 @@ export class CanvasEraserLine extends CanvasObject { }; constructor(state: EraserLine, parent: CanvasLayer) { - super(state.id, parent); - this.log.trace({ state }, 'Creating eraser line'); + const { id, strokeWidth, clip, points } = state; + this.id = id; + this.parent = parent; + this.manager = parent.manager; + this.getLoggingContext = this.manager.buildObjectGetLoggingContext(this); + this.log = this.manager.buildLogger(this.getLoggingContext); - const { strokeWidth, clip, points } = state; + this.log.trace({ state }, 'Creating eraser line'); this.konva = { group: new Konva.Group({ diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasImage.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasImage.ts index 021ced6581..521ccc9434 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasImage.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasImage.ts @@ -1,23 +1,28 @@ +import type { JSONObject } from 'common/types'; import { deepClone } from 'common/util/deepClone'; -import type { CanvasControlAdapter } from 'features/controlLayers/konva/CanvasControlAdapter'; import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer'; -import { CanvasObject } from 'features/controlLayers/konva/CanvasObject'; -import type { CanvasStagingArea } from 'features/controlLayers/konva/CanvasStagingArea'; +import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import { FILTER_MAP } from 'features/controlLayers/konva/filters'; import { loadImage } from 'features/controlLayers/konva/util'; import type { ImageObject } from 'features/controlLayers/store/types'; import { t } from 'i18next'; import Konva from 'konva'; +import type { Logger } from 'roarr'; import { getImageDTO } from 'services/api/endpoints/images'; -export class CanvasImage extends CanvasObject { - static NAME_PREFIX = 'canvas-image'; - static GROUP_NAME = `${CanvasImage.NAME_PREFIX}_group`; - static IMAGE_NAME = `${CanvasImage.NAME_PREFIX}_image`; - static PLACEHOLDER_GROUP_NAME = `${CanvasImage.NAME_PREFIX}_placeholder-group`; - static PLACEHOLDER_RECT_NAME = `${CanvasImage.NAME_PREFIX}_placeholder-rect`; - static PLACEHOLDER_TEXT_NAME = `${CanvasImage.NAME_PREFIX}_placeholder-text`; +export class CanvasImage { static TYPE = 'image'; + static GROUP_NAME = `${CanvasImage.TYPE}_group`; + static IMAGE_NAME = `${CanvasImage.TYPE}_image`; + static PLACEHOLDER_GROUP_NAME = `${CanvasImage.TYPE}_placeholder-group`; + static PLACEHOLDER_RECT_NAME = `${CanvasImage.TYPE}_placeholder-rect`; + static PLACEHOLDER_TEXT_NAME = `${CanvasImage.TYPE}_placeholder-text`; + + id: string; + parent: CanvasLayer; + manager: CanvasManager; + log: Logger; + getLoggingContext: (extra?: JSONObject) => JSONObject; state: ImageObject; konva: { @@ -29,11 +34,15 @@ export class CanvasImage extends CanvasObject { isLoading: boolean; isError: boolean; - constructor(state: ImageObject, parent: CanvasLayer | CanvasStagingArea | CanvasControlAdapter) { - super(state.id, parent); - this.log.trace({ state }, 'Creating image'); + constructor(state: ImageObject, parent: CanvasLayer) { + const { id, width, height, x, y } = state; + this.id = id; + this.parent = parent; + this.manager = parent.manager; + this.getLoggingContext = this.manager.buildObjectGetLoggingContext(this); + this.log = this.manager.buildLogger(this.getLoggingContext); - const { width, height, x, y } = state; + this.log.trace({ state }, 'Creating image'); this.konva = { group: new Konva.Group({ name: CanvasImage.GROUP_NAME, listening: false, x, y }), diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasInteractionRect.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasInteractionRect.ts index 742c8073b1..e65c9cf1a6 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasInteractionRect.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasInteractionRect.ts @@ -1,17 +1,30 @@ -import { nanoid } from '@reduxjs/toolkit'; -import { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer'; -import { CanvasObject } from 'features/controlLayers/konva/CanvasObject'; +import type { JSONObject } from 'common/types'; +import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer'; +import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; +import { getPrefixedId } from 'features/controlLayers/konva/util'; import Konva from 'konva'; +import type { Logger } from 'roarr'; -export class CanvasInteractionRect extends CanvasObject { +export class CanvasInteractionRect { static TYPE = 'interaction_rect'; + id: string; + parent: CanvasLayer; + manager: CanvasManager; + log: Logger; + getLoggingContext: (extra?: JSONObject) => JSONObject; + konva: { rect: Konva.Rect; }; constructor(parent: CanvasLayer) { - super(`${CanvasInteractionRect.TYPE}:${nanoid()}`, parent); + this.id = getPrefixedId(CanvasInteractionRect.TYPE); + this.parent = parent; + this.manager = parent.manager; + + this.getLoggingContext = this.manager.buildObjectGetLoggingContext(this); + this.log = this.manager.buildLogger(this.getLoggingContext); this.konva = { rect: new Konva.Rect({ @@ -62,10 +75,6 @@ export class CanvasInteractionRect extends CanvasObject { return { id: this.id, type: CanvasInteractionRect.TYPE, - x: this.konva.rect.x(), - y: this.konva.rect.y(), - width: this.konva.rect.width(), - height: this.konva.rect.height(), }; }; } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts index ce54d1ba53..06e2be5d77 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts @@ -2,14 +2,21 @@ import type { Store } from '@reduxjs/toolkit'; import { logger } from 'app/logging/logger'; import type { RootState } from 'app/store/store'; import type { JSONObject } from 'common/types'; +import type { CanvasBrushLine } from 'features/controlLayers/konva/CanvasBrushLine'; +import type { CanvasEraserLine } from 'features/controlLayers/konva/CanvasEraserLine'; +import type { CanvasImage } from 'features/controlLayers/konva/CanvasImage'; import { CanvasInitialImage } from 'features/controlLayers/konva/CanvasInitialImage'; +import type { CanvasInteractionRect } from 'features/controlLayers/konva/CanvasInteractionRect'; import { CanvasProgressPreview } from 'features/controlLayers/konva/CanvasProgressPreview'; +import type { CanvasRect } from 'features/controlLayers/konva/CanvasRect'; +import type { CanvasTransformer } from 'features/controlLayers/konva/CanvasTransformer'; import { getCompositeLayerImage, getControlAdapterImage, getGenerationMode, getInitialImage, getInpaintMaskImage, + getPrefixedId, getRegionMaskImage, nanoid, } from 'features/controlLayers/konva/util'; @@ -113,7 +120,7 @@ export class CanvasManager { ...message, context: { ...message.context, - ...this._getLoggingContext(), + ...this.getLoggingContext(), }, }; }); @@ -568,7 +575,7 @@ export class CanvasManager { } } - _getLoggingContext() { + getLoggingContext() { return { // timestamp: new Date().toISOString(), }; @@ -586,6 +593,28 @@ export class CanvasManager { }); } + buildObjectGetLoggingContext = ( + instance: CanvasBrushLine | CanvasEraserLine | CanvasRect | CanvasImage | CanvasTransformer | CanvasInteractionRect + ) => { + return (extra?: JSONObject): JSONObject => { + return { + ...instance.parent.getLoggingContext(), + objectId: instance.id, + ...extra, + }; + }; + }; + + buildEntityGetLoggingContext = (instance: CanvasLayer) => { + return (extra?: JSONObject): JSONObject => { + return { + ...instance.manager.getLoggingContext(), + entityId: instance.id, + ...extra, + }; + }; + }; + logDebugInfo() { // eslint-disable-next-line no-console console.log(this); @@ -594,4 +623,6 @@ export class CanvasManager { console.log(layer); } } + + getPrefixedId = getPrefixedId; } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasObject.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasObject.ts deleted file mode 100644 index 52b84a4cd3..0000000000 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasObject.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { JSONObject } from 'common/types'; -import type { CanvasControlAdapter } from 'features/controlLayers/konva/CanvasControlAdapter'; -import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer'; -import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; -import type { CanvasStagingArea } from 'features/controlLayers/konva/CanvasStagingArea'; -import type { Logger } from 'roarr'; - -export abstract class CanvasObject { - id: string; - - parent: CanvasLayer | CanvasStagingArea | CanvasControlAdapter; - manager: CanvasManager; - log: Logger; - - constructor(id: string, parent: CanvasLayer | CanvasStagingArea | CanvasControlAdapter) { - this.id = id; - this.parent = parent; - this.manager = parent.manager; - this.log = this.manager.buildLogger(this.getLoggingContext); - } - - /** - * Get a serializable representation of the object. - */ - abstract repr(): JSONObject; - - /** - * Get the logging context for this object. - * @param extra Extra data to merge into the context - * @returns The logging context for this object - */ - getLoggingContext = (extra?: Record) => { - return { - ...this.parent.getLoggingContext(), - objectId: this.id, - ...extra, - }; - }; -} diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRect.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRect.ts index fe0b875379..d1503e7402 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRect.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRect.ts @@ -1,15 +1,22 @@ +import type { JSONObject } from 'common/types'; import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import { deepClone } from 'common/util/deepClone'; import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer'; -import { CanvasObject } from 'features/controlLayers/konva/CanvasObject'; +import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { RectShape } from 'features/controlLayers/store/types'; import Konva from 'konva'; +import type { Logger } from 'roarr'; -export class CanvasRect extends CanvasObject { - static NAME_PREFIX = 'canvas-rect'; - static GROUP_NAME = `${CanvasRect.NAME_PREFIX}_group`; - static RECT_NAME = `${CanvasRect.NAME_PREFIX}_rect`; +export class CanvasRect { static TYPE = 'rect'; + static GROUP_NAME = `${CanvasRect.TYPE}_group`; + static RECT_NAME = `${CanvasRect.TYPE}_rect`; + + id: string; + parent: CanvasLayer; + manager: CanvasManager; + log: Logger; + getLoggingContext: (extra?: JSONObject) => JSONObject; state: RectShape; konva: { @@ -18,11 +25,14 @@ export class CanvasRect extends CanvasObject { }; constructor(state: RectShape, parent: CanvasLayer) { - super(state.id, parent); + const { id, x, y, width, height, color } = state; + this.id = id; + this.parent = parent; + this.manager = parent.manager; + this.getLoggingContext = this.manager.buildObjectGetLoggingContext(this); + this.log = this.manager.buildLogger(this.getLoggingContext); this.log.trace({ state }, 'Creating rect'); - const { x, y, width, height, color } = state; - this.konva = { group: new Konva.Group({ name: CanvasRect.GROUP_NAME, listening: false }), rect: new Konva.Rect({ diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTransformer.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTransformer.ts index b42cb093a8..b8022cd0c0 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTransformer.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasTransformer.ts @@ -1,19 +1,32 @@ +import type { JSONObject } from 'common/types'; import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer'; -import { CanvasObject } from 'features/controlLayers/konva/CanvasObject'; -import { nanoid } from 'features/controlLayers/konva/util'; +import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; +import { getPrefixedId } from 'features/controlLayers/konva/util'; import type { Coordinate } from 'features/controlLayers/store/types'; import Konva from 'konva'; +import type { Logger } from 'roarr'; -export class CanvasTransformer extends CanvasObject { +export class CanvasTransformer { static TYPE = 'transformer'; + id: string; + parent: CanvasLayer; + manager: CanvasManager; + log: Logger; + getLoggingContext: (extra?: JSONObject) => JSONObject; + isActive: boolean; konva: { transformer: Konva.Transformer; }; constructor(parent: CanvasLayer) { - super(`${CanvasTransformer.TYPE}:${nanoid()}`, parent); + this.parent = parent; + this.manager = parent.manager; + this.id = getPrefixedId(CanvasTransformer.TYPE); + + this.getLoggingContext = this.manager.buildObjectGetLoggingContext(this); + this.log = this.manager.buildLogger(this.getLoggingContext); this.isActive = false; this.konva = {