From 1597762374b9f6ceb1ecda7c83c81876d9c02b01 Mon Sep 17 00:00:00 2001 From: Wolfger Schramm <wolfger@spearwolf.de> Date: Wed, 20 Mar 2024 16:20:51 +0100 Subject: [PATCH] minor refactorings --- packages/shadow-ents/src/entities/Kernel.ts | 13 ++++++- .../shadow-objects/TestImage2OnCanvas2D.js | 38 ++++++++++++------- .../src/shadow-objects/TestImageOnCanvas2D.js | 34 +++++++++++------ packages/vfx/src/shadow-objects/VfxDisplay.js | 12 ++++-- 4 files changed, 67 insertions(+), 30 deletions(-) diff --git a/packages/shadow-ents/src/entities/Kernel.ts b/packages/shadow-ents/src/entities/Kernel.ts index 6595957..0e66326 100644 --- a/packages/shadow-ents/src/entities/Kernel.ts +++ b/packages/shadow-ents/src/entities/Kernel.ts @@ -171,6 +171,7 @@ export class Kernel extends Eventize { createShadowObjects(token: string, entityEntry?: EntityEntry) { return this.registry.findConstructors(token)?.map((constructor) => { + const unsubscribe = new Set<() => any>(); const shadowObject = eventize( new constructor( entityEntry?.entity != null @@ -189,13 +190,21 @@ export class Kernel extends Eventize { return entityEntry.entity.getPropertyReader(name); }, - // TODO onDestroy <- shadow-object - // TODO onEvent ? (auto destroy subscription) + onDestroy(callback: () => any) { + unsubscribe.add(callback); + }, } : undefined, ), ); + shadowObject.once(onDestroy, () => { + console.log('destroy shadow-object', shadowObject, Array.from(unsubscribe)); + for (const callback of unsubscribe) { + callback(); + } + }); + if (entityEntry) { // We want to keep track which shadow-objects are created by which constructors. // This will allow us to destroy the shadow-objects at a later time when we change the token. diff --git a/packages/vfx/src/shadow-objects/TestImage2OnCanvas2D.js b/packages/vfx/src/shadow-objects/TestImage2OnCanvas2D.js index 871ebee..6cb3ba0 100644 --- a/packages/vfx/src/shadow-objects/TestImage2OnCanvas2D.js +++ b/packages/vfx/src/shadow-objects/TestImage2OnCanvas2D.js @@ -1,23 +1,35 @@ -export function TestImage2OnCanvas2D({entity}) { +export function TestImage2OnCanvas2D() { const [r, g, b] = [Math.floor(Math.random() * 255), Math.floor(Math.random() * 255), Math.floor(Math.random() * 255)]; const fillStyle0 = `rgb(${r} ${g} ${b})`; const fillStyle1 = `rgb(${255 - r} ${255 - g} ${255 - b})`; - let ctx = null; + let canvas; + let ctx; - entity.on('onRenderFrame', ({canvas}) => { - ctx ??= canvas.getContext('2d'); + return { + onRenderFrame(params) { + canvas ??= params.canvas; + ctx ??= canvas.getContext('2d'); - const [w, h] = [canvas.width, canvas.height]; - const halfH = Math.floor(h / 2); - const halfW = Math.floor(w / 2); + const [w, h] = [canvas.width, canvas.height]; + const halfH = Math.floor(h / 2); + const halfW = Math.floor(w / 2); - ctx.clearRect(0, 0, w, h); + ctx.clearRect(0, 0, w, h); - ctx.fillStyle = fillStyle0; - ctx.fillRect(0, 0, halfW, halfH); + ctx.fillStyle = fillStyle0; + ctx.fillRect(0, 0, halfW, halfH); - ctx.fillStyle = fillStyle1; - ctx.fillRect(0, halfH, halfW, h - halfH); - }); + ctx.fillStyle = fillStyle1; + ctx.fillRect(0, halfH, halfW, h - halfH); + }, + + onDestroy() { + if (canvas && ctx) { + ctx.fillStyle = 'red'; + const halfW = Math.floor(canvas.width / 2); + ctx.fillRect(0, 0, halfW, canvas.height); + } + }, + }; } diff --git a/packages/vfx/src/shadow-objects/TestImageOnCanvas2D.js b/packages/vfx/src/shadow-objects/TestImageOnCanvas2D.js index ea06743..8f0d3e7 100644 --- a/packages/vfx/src/shadow-objects/TestImageOnCanvas2D.js +++ b/packages/vfx/src/shadow-objects/TestImageOnCanvas2D.js @@ -1,26 +1,36 @@ -export function TestImageOnCanvas2D({entity, useContext}) { +export function TestImageOnCanvas2D({entity, useContext, onDestroy}) { const [r, g, b] = [Math.floor(Math.random() * 255), Math.floor(Math.random() * 255), Math.floor(Math.random() * 255)]; const fillStyle0 = `rgb(${r} ${g} ${b})`; const fillStyle1 = `rgb(${255 - r} ${255 - g} ${255 - b})`; let ctx = null; + let consoleCount = 0; + useContext('canvasSize')((size) => { - console.debug(`[TestImageOnCanvas2D] ${entity.uuid} canvas size changed to`, size); + if (consoleCount++ < 3) { + console.debug(`[TestImageOnCanvas2D] ${entity.uuid} canvas size changed to`, size); + } }); - entity.on('onRenderFrame', ({canvas}) => { - ctx ??= canvas.getContext('2d'); + console.log(`[TestImageOnCanvas2D] ${entity.uuid} Ready.`); + + onDestroy(() => { + console.log(`[TestImageOnCanvas2D] ${entity.uuid} Thank you for the fish.`); + }); - const [w, h] = [canvas.width, canvas.height]; - const halfH = Math.floor(h / 2); + return { + onRenderFrame({canvas}) { + ctx ??= canvas.getContext('2d'); - ctx.fillStyle = fillStyle0; - ctx.fillRect(0, 0, w, halfH); + const [w, h] = [canvas.width, canvas.height]; + const halfH = Math.floor(h / 2); - ctx.fillStyle = fillStyle1; - ctx.fillRect(0, halfH, w, h - halfH); - }); + ctx.fillStyle = fillStyle0; + ctx.fillRect(0, 0, w, halfH); - console.debug(`[TestImageOnCanvas2D] ${entity.uuid} ready`); + ctx.fillStyle = fillStyle1; + ctx.fillRect(0, halfH, w, h - halfH); + }, + }; } diff --git a/packages/vfx/src/shadow-objects/VfxDisplay.js b/packages/vfx/src/shadow-objects/VfxDisplay.js index 7c94ca4..ca3df95 100644 --- a/packages/vfx/src/shadow-objects/VfxDisplay.js +++ b/packages/vfx/src/shadow-objects/VfxDisplay.js @@ -1,4 +1,4 @@ -import {createEffect, createSignal} from '@spearwolf/signalize'; +import {createEffect, createSignal, destroySignal} from '@spearwolf/signalize'; import {FrameLoop} from '../shared/FrameLoop.js'; import {OffscreenCanvas, StartFrameLoop, StopFrameLoop} from '../shared/constants.js'; @@ -20,7 +20,7 @@ export class VfxDisplay { return this.isRunning && this.canvas != null && this.canvas.width > 0 && this.canvas.height > 0; } - constructor({entity, useContext, useProperty, provideContext}) { + constructor({entity, useContext, useProperty, provideContext, onDestroy}) { this.entity = entity; // TODO use shared vfx.canvas|multiViewRenderer -------- @@ -41,7 +41,7 @@ export class VfxDisplay { const getCanvasHeight = useProperty('canvasHeight'); const getPixelRatio = useProperty('pixelRatio'); - createEffect(() => { + const [, unsubscribe] = createEffect(() => { const canvas = getCanvas(); if (canvas) { const w = getCanvasWidth(); @@ -76,6 +76,12 @@ export class VfxDisplay { enumerable: true, }, }); + + onDestroy(() => { + console.log('[VfxDisplay] onDestroy: bye, bye!'); + unsubscribe(); + destroySignal(getCanvasSize); + }); } onViewEvent(type, data) {