fix(ui): stale state causing race conditions & extraneous renders

This commit is contained in:
psychedelicious 2024-08-20 12:51:46 +10:00
parent fea1711f0c
commit 2e7ae6a07e

View File

@ -58,8 +58,8 @@ export class CanvasManager {
socket: AppSocket; socket: AppSocket;
_store: AppStore; _store: AppStore;
_prevState: CanvasV2State; prevState: CanvasV2State;
_isFirstRender: boolean = true; isFirstRender: boolean = true;
_isDebugging: boolean = false; _isDebugging: boolean = false;
_worker: Worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module', name: 'worker' }); _worker: Worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module', name: 'worker' });
@ -74,7 +74,7 @@ export class CanvasManager {
this.socket = socket; this.socket = socket;
this.stateApi = new CanvasStateApi(this._store, this); this.stateApi = new CanvasStateApi(this._store, this);
this._prevState = this.stateApi.getState(); this.prevState = this.stateApi.getState();
this.log = logger('canvas').child((message) => { this.log = logger('canvas').child((message) => {
return { return {
@ -301,19 +301,22 @@ export class CanvasManager {
render = async () => { render = async () => {
const state = this.stateApi.getState(); const state = this.stateApi.getState();
if (this._prevState === state && !this._isFirstRender) { const isFirstRender = this.isFirstRender;
this.isFirstRender = false;
const prevState = this.prevState;
this.prevState = state;
if (prevState === state && !isFirstRender) {
this.log.trace('No changes detected, skipping render'); this.log.trace('No changes detected, skipping render');
return; return;
} }
if ( if (isFirstRender || state.settings.canvasBackgroundStyle !== prevState.settings.canvasBackgroundStyle) {
this._isFirstRender ||
state.settings.canvasBackgroundStyle !== this._prevState.settings.canvasBackgroundStyle
) {
this.background.render(); this.background.render();
} }
if (this._isFirstRender || state.rasterLayers.entities !== this._prevState.rasterLayers.entities) { if (isFirstRender || state.rasterLayers.entities !== prevState.rasterLayers.entities) {
this.log.debug('Rendering raster layers'); this.log.debug('Rendering raster layers');
for (const entityAdapter of this.rasterLayerAdapters.values()) { for (const entityAdapter of this.rasterLayerAdapters.values()) {
@ -338,7 +341,7 @@ export class CanvasManager {
} }
} }
if (this._isFirstRender || state.controlLayers.entities !== this._prevState.controlLayers.entities) { if (isFirstRender || state.controlLayers.entities !== prevState.controlLayers.entities) {
this.log.debug('Rendering control layers'); this.log.debug('Rendering control layers');
for (const entityAdapter of this.controlLayerAdapters.values()) { for (const entityAdapter of this.controlLayerAdapters.values()) {
@ -364,10 +367,10 @@ export class CanvasManager {
} }
if ( if (
this._isFirstRender || isFirstRender ||
state.regions.entities !== this._prevState.regions.entities || state.regions.entities !== prevState.regions.entities ||
state.tool.selected !== this._prevState.tool.selected || state.tool.selected !== prevState.tool.selected ||
state.selectedEntityIdentifier?.id !== this._prevState.selectedEntityIdentifier?.id state.selectedEntityIdentifier?.id !== prevState.selectedEntityIdentifier?.id
) { ) {
this.log.debug('Rendering regions'); this.log.debug('Rendering regions');
@ -395,10 +398,10 @@ export class CanvasManager {
} }
if ( if (
this._isFirstRender || isFirstRender ||
state.inpaintMask !== this._prevState.inpaintMask || state.inpaintMask !== prevState.inpaintMask ||
state.tool.selected !== this._prevState.tool.selected || state.tool.selected !== prevState.tool.selected ||
state.selectedEntityIdentifier?.id !== this._prevState.selectedEntityIdentifier?.id state.selectedEntityIdentifier?.id !== prevState.selectedEntityIdentifier?.id
) { ) {
this.log.debug('Rendering inpaint mask'); this.log.debug('Rendering inpaint mask');
await this.inpaintMaskAdapter.update({ await this.inpaintMaskAdapter.update({
@ -413,36 +416,26 @@ export class CanvasManager {
this.stateApi.$selectedEntity.set(this.stateApi.getSelectedEntity()); this.stateApi.$selectedEntity.set(this.stateApi.getSelectedEntity());
this.stateApi.$currentFill.set(this.stateApi.getCurrentFill()); this.stateApi.$currentFill.set(this.stateApi.getCurrentFill());
if ( if (isFirstRender || state.bbox !== prevState.bbox || state.tool.selected !== prevState.tool.selected) {
this._isFirstRender ||
state.bbox !== this._prevState.bbox ||
state.tool.selected !== this._prevState.tool.selected
) {
this.log.debug('Rendering generation bbox'); this.log.debug('Rendering generation bbox');
await this.preview.bbox.render(); await this.preview.bbox.render();
} }
if (this._isFirstRender || state.session !== this._prevState.session) { if (isFirstRender || state.session !== prevState.session) {
this.log.debug('Rendering staging area'); this.log.debug('Rendering staging area');
await this.preview.stagingArea.render(); await this.preview.stagingArea.render();
} }
if ( if (
this._isFirstRender || isFirstRender ||
state.rasterLayers.entities !== this._prevState.rasterLayers.entities || state.rasterLayers.entities !== prevState.rasterLayers.entities ||
state.regions.entities !== this._prevState.regions.entities || state.regions.entities !== prevState.regions.entities ||
state.inpaintMask !== this._prevState.inpaintMask || state.inpaintMask !== prevState.inpaintMask ||
state.selectedEntityIdentifier?.id !== this._prevState.selectedEntityIdentifier?.id state.selectedEntityIdentifier?.id !== prevState.selectedEntityIdentifier?.id
) { ) {
this.log.debug('Arranging entities'); this.log.debug('Arranging entities');
await this.arrangeEntities(); await this.arrangeEntities();
} }
this._prevState = state;
if (this._isFirstRender) {
this._isFirstRender = false;
}
}; };
initialize = () => { initialize = () => {
@ -460,8 +453,6 @@ export class CanvasManager {
const unsubscribeRenderer = this._store.subscribe(this.render); const unsubscribeRenderer = this._store.subscribe(this.render);
this.log.debug('First render of konva stage'); this.log.debug('First render of konva stage');
this.preview.tool.render();
this.render();
return () => { return () => {
this.log.debug('Cleaning up konva renderer'); this.log.debug('Cleaning up konva renderer');