@lightningjs/renderer
Advanced tools
Comparing version 0.7.2 to 0.7.3
@@ -67,1 +67,8 @@ /** | ||
} | ||
/** | ||
* Event payload for when a frame tick event is emitted by the Stage | ||
*/ | ||
export interface FrameTickPayload { | ||
time: number; | ||
delta: number; | ||
} |
@@ -87,2 +87,5 @@ /* | ||
} | ||
if (this.delayFor <= 0 && this.progress === 0) { | ||
this.emit('start', {}); | ||
} | ||
this.progress += dt / duration; | ||
@@ -89,0 +92,0 @@ if (this.progress > 1) { |
@@ -7,2 +7,7 @@ import type { AnimationControllerState, IAnimationController } from '../../common/IAnimationController.js'; | ||
private animation; | ||
startedPromise: Promise<void> | null; | ||
/** | ||
* If this is null, then the animation hasn't started yet. | ||
*/ | ||
startedResolve: ((scope?: any) => void) | null; | ||
stoppedPromise: Promise<void> | null; | ||
@@ -19,5 +24,8 @@ /** | ||
restore(): IAnimationController; | ||
waitUntilStarted(): Promise<void>; | ||
waitUntilStopped(): Promise<void>; | ||
private makeStartedPromise; | ||
private makeStoppedPromise; | ||
private started; | ||
private finished; | ||
} |
@@ -23,2 +23,7 @@ /* | ||
animation; | ||
startedPromise = null; | ||
/** | ||
* If this is null, then the animation hasn't started yet. | ||
*/ | ||
startedResolve = null; | ||
stoppedPromise = null; | ||
@@ -36,2 +41,4 @@ /** | ||
start() { | ||
this.makeStartedPromise(); | ||
this.animation.once('start', this.started.bind(this)); | ||
this.makeStoppedPromise(); | ||
@@ -66,2 +73,8 @@ this.animation.once('finished', this.finished.bind(this)); | ||
} | ||
waitUntilStarted() { | ||
this.makeStartedPromise(); | ||
const promise = this.startedPromise; | ||
assertTruthy(promise); | ||
return promise; | ||
} | ||
waitUntilStopped() { | ||
@@ -73,2 +86,9 @@ this.makeStoppedPromise(); | ||
} | ||
makeStartedPromise() { | ||
if (this.startedResolve === null) { | ||
this.startedPromise = new Promise((resolve) => { | ||
this.startedResolve = resolve; | ||
}); | ||
} | ||
} | ||
makeStoppedPromise() { | ||
@@ -81,2 +101,8 @@ if (this.stoppedResolve === null) { | ||
} | ||
started() { | ||
assertTruthy(this.startedResolve); | ||
// resolve promise (and pass current this to continue to the chain) | ||
this.startedResolve(this); | ||
this.startedResolve = null; | ||
} | ||
finished() { | ||
@@ -83,0 +109,0 @@ assertTruthy(this.stoppedResolve); |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ import { WebGlCoreShader, } from '../WebGlCoreShader.js'; |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ import { ShaderEffect, } from './ShaderEffect.js'; |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -10,3 +10,3 @@ import { WebGlCoreRenderer } from './renderers/webgl/WebGlCoreRenderer.js'; | ||
import { ContextSpy } from './lib/ContextSpy.js'; | ||
import type { FpsUpdatePayload } from '../common/CommonTypes.js'; | ||
import type { FpsUpdatePayload, FrameTickPayload } from '../common/CommonTypes.js'; | ||
export interface StageOptions { | ||
@@ -28,2 +28,3 @@ rootId: number; | ||
export type StageFpsUpdateHandler = (stage: Stage, fpsData: FpsUpdatePayload) => void; | ||
export type StageFrameTickHandler = (stage: Stage, frameTickData: FrameTickPayload) => void; | ||
export declare class Stage extends EventEmitter { | ||
@@ -30,0 +31,0 @@ readonly options: StageOptions; |
@@ -142,2 +142,6 @@ /* | ||
: this.currentFrameTime - this.lastFrameTime; | ||
this.emit('frameTick', { | ||
time: this.currentFrameTime, | ||
delta: this.deltaTime, | ||
}); | ||
// step animation | ||
@@ -144,0 +148,0 @@ animationManager.update(this.deltaTime); |
@@ -1,2 +0,2 @@ | ||
import type { FpsUpdatePayload } from '../common/CommonTypes.js'; | ||
import type { FpsUpdatePayload, FrameTickPayload } from '../common/CommonTypes.js'; | ||
import type { INode, INodeWritableProps, ITextNode, ITextNodeWritableProps } from './INode.js'; | ||
@@ -22,2 +22,3 @@ import type { RendererMain, RendererMainSettings } from './RendererMain.js'; | ||
onFpsUpdate(fpsData: FpsUpdatePayload): void; | ||
onFrameTick(frameTickData: FrameTickPayload): void; | ||
} |
@@ -7,3 +7,9 @@ import type { INode, INodeAnimatableProps, INodeWritableProps, ITextNode, ITextNodeWritableProps } from './INode.js'; | ||
private root; | ||
private canvas; | ||
private height; | ||
private width; | ||
private scaleX; | ||
private scaleY; | ||
constructor(canvas: HTMLCanvasElement, settings: RendererMainSettings); | ||
setRootPosition(): void; | ||
createDiv(node: INode | ITextNode, properties: INodeWritableProps | ITextNodeWritableProps): HTMLElement; | ||
@@ -10,0 +16,0 @@ createNode(driver: ICoreDriver, properties: INodeWritableProps): INode; |
import {} from './RendererMain.js'; | ||
const stylePropertyMap = { | ||
alpha: () => 'opacity', | ||
x: () => 'left', | ||
y: () => 'top', | ||
width: () => 'width', | ||
height: () => 'height', | ||
alpha: (v) => { | ||
if (v === 1) { | ||
return null; | ||
} | ||
return { prop: 'opacity', value: `${v}` }; | ||
}, | ||
x: (x) => { | ||
return { prop: 'left', value: `${x}px` }; | ||
}, | ||
y: (y) => { | ||
return { prop: 'top', value: `${y}px` }; | ||
}, | ||
width: (w) => { | ||
if (w === 0) { | ||
return null; | ||
} | ||
return { prop: 'width', value: `${w}px` }; | ||
}, | ||
height: (h) => { | ||
if (h === 0) { | ||
return null; | ||
} | ||
return { prop: 'height', value: `${h}px` }; | ||
}, | ||
zIndex: () => 'zIndex', | ||
@@ -22,20 +41,41 @@ fontFamily: () => 'font-family', | ||
clipping: (v) => { | ||
if (v === false) { | ||
return null; | ||
} | ||
return { prop: 'overflow', value: v ? 'hidden' : 'visible' }; | ||
}, | ||
rotation: (v) => { | ||
if (v === 0) { | ||
return null; | ||
} | ||
return { prop: 'transform', value: `rotate(${v}rad)` }; | ||
}, | ||
scale: (v) => { | ||
if (v === 1) { | ||
return null; | ||
} | ||
return { prop: 'transform', value: `scale(${v})` }; | ||
}, | ||
scaleX: (v) => { | ||
if (v === 1) { | ||
return null; | ||
} | ||
return { prop: 'transform', value: `scaleX(${v})` }; | ||
}, | ||
scaleY: (v) => { | ||
if (v === 1) { | ||
return null; | ||
} | ||
return { prop: 'transform', value: `scaleY(${v})` }; | ||
}, | ||
src: (v) => { | ||
if (!v) { | ||
return null; | ||
} | ||
return { prop: 'background-image', value: `url(${v})` }; | ||
}, | ||
color: (v) => { | ||
if (v === 0) { | ||
return null; | ||
} | ||
return { prop: 'color', value: convertColorToRgba(v) }; | ||
@@ -65,4 +105,11 @@ }, | ||
export class Inspector { | ||
root; | ||
root = null; | ||
canvas = null; | ||
height = 1080; | ||
width = 1920; | ||
scaleX = 1; | ||
scaleY = 1; | ||
constructor(canvas, settings) { | ||
if (import.meta.env.PROD) | ||
return; | ||
if (!settings) { | ||
@@ -72,17 +119,42 @@ throw new Error('settings is required'); | ||
// calc dimensions based on the devicePixelRatio | ||
const height = Math.ceil(settings.appHeight ?? 1080 / (settings.deviceLogicalPixelRatio ?? 1)); | ||
const width = Math.ceil(settings.appWidth ?? 1900 / (settings.deviceLogicalPixelRatio ?? 1)); | ||
this.height = Math.ceil(settings.appHeight ?? 1080 / (settings.deviceLogicalPixelRatio ?? 1)); | ||
this.width = Math.ceil(settings.appWidth ?? 1900 / (settings.deviceLogicalPixelRatio ?? 1)); | ||
this.scaleX = settings.deviceLogicalPixelRatio ?? 1; | ||
this.scaleY = settings.deviceLogicalPixelRatio ?? 1; | ||
this.canvas = canvas; | ||
this.root = document.createElement('div'); | ||
this.setRootPosition(); | ||
document.body.appendChild(this.root); | ||
//listen for changes on canvas | ||
const mutationObserver = new MutationObserver(this.setRootPosition.bind(this)); | ||
mutationObserver.observe(canvas, { | ||
attributes: true, | ||
childList: false, | ||
subtree: false, | ||
}); | ||
// Create a ResizeObserver to watch for changes in the element's size | ||
const resizeObserver = new ResizeObserver(this.setRootPosition.bind(this)); | ||
resizeObserver.observe(canvas); | ||
//listen for changes on window | ||
window.addEventListener('resize', this.setRootPosition.bind(this)); | ||
console.warn('Inspector is enabled, this will impact performance'); | ||
} | ||
setRootPosition() { | ||
if (this.root === null || this.canvas === null) { | ||
return; | ||
} | ||
// get the world position of the canvas object, so we can match the inspector to it | ||
const rect = this.canvas.getBoundingClientRect(); | ||
const top = document.documentElement.scrollTop + rect.top; | ||
const left = document.documentElement.scrollLeft + rect.left; | ||
this.root.id = 'root'; | ||
this.root.style.left = '0'; | ||
this.root.style.top = '0'; | ||
this.root.style.width = `${width}px`; | ||
this.root.style.height = `${height}px`; | ||
this.root.style.left = `${left}px`; | ||
this.root.style.top = `${top}px`; | ||
this.root.style.width = `${this.width}px`; | ||
this.root.style.height = `${this.height}px`; | ||
this.root.style.position = 'absolute'; | ||
this.root.style.transformOrigin = '0 0 0'; | ||
this.root.style.transform = `scale(${settings.deviceLogicalPixelRatio ?? 1},${settings.deviceLogicalPixelRatio ?? 1})`; | ||
this.root.style.transform = `scale(${this.scaleX}, ${this.scaleY})`; | ||
this.root.style.overflow = 'hidden'; | ||
this.root.style.zIndex = '-65535'; | ||
document.body.appendChild(this.root); | ||
console.warn('Inspector is enabled, this will impact performance'); | ||
this.root.style.zIndex = '-65534'; | ||
} | ||
@@ -104,2 +176,4 @@ createDiv(node, properties) { | ||
const div = this.createDiv(node, properties); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any | ||
div.node = node; | ||
return this.createProxy(node, div); | ||
@@ -147,3 +221,3 @@ } | ||
value) { | ||
if (!value) { | ||
if (this.root === null || value === undefined || value === null) { | ||
return; | ||
@@ -181,6 +255,10 @@ } | ||
const mappedStyleResponse = stylePropertyMap[property]?.(value); | ||
if (mappedStyleResponse === null) { | ||
return; | ||
} | ||
if (typeof mappedStyleResponse === 'string') { | ||
div.style.setProperty(mappedStyleResponse, String(value)); | ||
return; | ||
} | ||
else if (typeof mappedStyleResponse === 'object') { | ||
if (typeof mappedStyleResponse === 'object') { | ||
div.style.setProperty(mappedStyleResponse.prop, mappedStyleResponse.value); | ||
@@ -195,6 +273,14 @@ } | ||
} | ||
// custom data properties | ||
// Needs https://github.com/lightning-js/renderer/pull/178 to be merged | ||
// if (property === 'data') { | ||
// for (const key in value) { | ||
// // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
// div.setAttribute(`data-${key}`, String(value[key])); | ||
// } | ||
// return; | ||
// } | ||
} | ||
// simple animation handler | ||
animateNode(div, node, props, settings) { | ||
console.log('animateNode', props, settings); | ||
const { duration = 1000, delay = 0, | ||
@@ -201,0 +287,0 @@ // easing = 'linear', |
@@ -189,2 +189,13 @@ import type { ShaderMap } from '../core/CoreShaderManager.js'; | ||
numImageWorkers?: number; | ||
/** | ||
* Enable inspector | ||
* | ||
* @remarks | ||
* When enabled the renderer will spawn a inspector. The inspector will | ||
* replicate the state of the Nodes created in the renderer and allow | ||
* inspection of the state of the nodes. | ||
* | ||
* @defaultValue `false` (disabled) | ||
*/ | ||
enableInspector?: boolean; | ||
} | ||
@@ -220,2 +231,3 @@ /** | ||
readonly settings: Readonly<Required<RendererMainSettings>>; | ||
private inspector; | ||
private nodes; | ||
@@ -222,0 +234,0 @@ private nextTextureId; |
@@ -22,2 +22,3 @@ /* | ||
import { EventEmitter } from '../common/EventEmitter.js'; | ||
import { Inspector } from './Inspector.js'; | ||
/** | ||
@@ -52,2 +53,3 @@ * The Renderer Main API | ||
settings; | ||
inspector = null; | ||
nodes = new Map(); | ||
@@ -83,5 +85,6 @@ nextTextureId = 1; | ||
enableContextSpy: settings.enableContextSpy ?? false, | ||
enableInspector: settings.enableInspector ?? false, | ||
}; | ||
this.settings = resolvedSettings; | ||
const { appWidth, appHeight, deviceLogicalPixelRatio, devicePhysicalPixelRatio, } = resolvedSettings; | ||
const { appWidth, appHeight, deviceLogicalPixelRatio, devicePhysicalPixelRatio, enableInspector, } = resolvedSettings; | ||
const releaseCallback = (textureId) => { | ||
@@ -124,3 +127,9 @@ this.driver.releaseTexture(textureId); | ||
}; | ||
driver.onFrameTick = (frameTickData) => { | ||
this.emit('frameTick', frameTickData); | ||
}; | ||
targetEl.appendChild(canvas); | ||
if (enableInspector && !import.meta.env.PROD) { | ||
this.inspector = new Inspector(canvas, resolvedSettings); | ||
} | ||
} | ||
@@ -155,2 +164,5 @@ /** | ||
createNode(props) { | ||
if (this.inspector) { | ||
return this.inspector.createNode(this.driver, this.resolveNodeDefaults(props)); | ||
} | ||
return this.driver.createNode(this.resolveNodeDefaults(props)); | ||
@@ -196,2 +208,5 @@ } | ||
}; | ||
if (this.inspector) { | ||
return this.inspector.createTextNode(this.driver, data); | ||
} | ||
return this.driver.createTextNode(data); | ||
@@ -262,2 +277,5 @@ } | ||
destroyNode(node) { | ||
if (this.inspector) { | ||
this.inspector.destroyNode(node); | ||
} | ||
return this.driver.destroyNode(node); | ||
@@ -264,0 +282,0 @@ } |
@@ -5,3 +5,3 @@ import type { ICoreDriver } from '../../main-api/ICoreDriver.js'; | ||
import { MainOnlyTextNode } from './MainOnlyTextNode.js'; | ||
import type { FpsUpdatePayload } from '../../common/CommonTypes.js'; | ||
import type { FpsUpdatePayload, FrameTickPayload } from '../../common/CommonTypes.js'; | ||
export declare class MainCoreDriver implements ICoreDriver { | ||
@@ -20,2 +20,3 @@ private root; | ||
onFpsUpdate(fpsData: FpsUpdatePayload): void; | ||
onFrameTick(frameTickData: FrameTickPayload): void; | ||
} |
@@ -21,3 +21,3 @@ /* | ||
import { MainOnlyNode, getNewId } from './MainOnlyNode.js'; | ||
import { Stage } from '../../core/Stage.js'; | ||
import { Stage, } from '../../core/Stage.js'; | ||
import { MainOnlyTextNode } from './MainOnlyTextNode.js'; | ||
@@ -59,2 +59,5 @@ import { loadCoreExtension } from '../utils.js'; | ||
})); | ||
this.stage.on('frameTick', ((stage, frameTickData) => { | ||
this.onFrameTick(frameTickData); | ||
})); | ||
} | ||
@@ -101,3 +104,6 @@ createNode(props) { | ||
} | ||
onFrameTick(frameTickData) { | ||
throw new Error('Method not implemented.'); | ||
} | ||
} | ||
//# sourceMappingURL=MainCoreDriver.js.map |
import type { INode, INodeWritableProps, ITextNode, ITextNodeWritableProps } from '../../main-api/INode.js'; | ||
import type { ICoreDriver } from '../../main-api/ICoreDriver.js'; | ||
import type { RendererMain, RendererMainSettings } from '../../main-api/RendererMain.js'; | ||
import type { FpsUpdatePayload } from '../../common/CommonTypes.js'; | ||
import type { FpsUpdatePayload, FrameTickPayload } from '../../common/CommonTypes.js'; | ||
export interface ThreadXRendererSettings { | ||
@@ -24,2 +24,3 @@ coreWorkerUrl: string; | ||
onFpsUpdate(fps: FpsUpdatePayload): void; | ||
onFrameTick(frameTickData: FrameTickPayload): void; | ||
} |
@@ -60,2 +60,6 @@ /* | ||
} | ||
// Forward frameTick events from the renderer worker's Stage to RendererMain | ||
if (isThreadXRendererMessage('frameTick', message)) { | ||
this.onFrameTick(message.frameTickData); | ||
} | ||
}, | ||
@@ -219,3 +223,6 @@ }); | ||
} | ||
onFrameTick(frameTickData) { | ||
throw new Error('Method not implemented.'); | ||
} | ||
} | ||
//# sourceMappingURL=ThreadXCoreDriver.js.map |
@@ -1,2 +0,2 @@ | ||
import type { FpsUpdatePayload } from '../../common/CommonTypes.js'; | ||
import type { FpsUpdatePayload, FrameTickPayload } from '../../common/CommonTypes.js'; | ||
/** | ||
@@ -46,2 +46,9 @@ * @module | ||
/** | ||
* A message sent from the renderer worker to the main worker to update the FPS | ||
*/ | ||
export interface ThreadXRendererFrameTickMessage extends ThreadXRendererMessage { | ||
type: 'frameTick'; | ||
frameTickData: FrameTickPayload; | ||
} | ||
/** | ||
* A map of message types to message shapes | ||
@@ -53,2 +60,3 @@ */ | ||
fpsUpdate: ThreadXRendererFpsUpdateMessage; | ||
frameTick: ThreadXRendererFrameTickMessage; | ||
} | ||
@@ -55,0 +63,0 @@ /** |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
{ | ||
"name": "@lightningjs/renderer", | ||
"version": "0.7.2", | ||
"version": "0.7.3", | ||
"description": "Lightning 3 Renderer", | ||
@@ -63,7 +63,8 @@ "type": "module", | ||
"NOTICE", | ||
"README.md" | ||
"README.md", | ||
"scripts" | ||
], | ||
"packageManager": "pnpm@8.9.2", | ||
"engines": { | ||
"npm": "please-use-pnpm", | ||
"npm": ">= 10.0.0", | ||
"pnpm": ">= 8.9.2", | ||
@@ -73,2 +74,3 @@ "node": ">= 20.9.0" | ||
"scripts": { | ||
"preinstall": "node scripts/please-use-pnpm.js", | ||
"start": "cd examples && pnpm start", | ||
@@ -75,0 +77,0 @@ "start:prod": "cd examples && pnpm start:prod", |
@@ -0,0 +0,0 @@ # Lightning 3 Renderer (Beta) |
@@ -106,1 +106,9 @@ /* | ||
} | ||
/** | ||
* Event payload for when a frame tick event is emitted by the Stage | ||
*/ | ||
export interface FrameTickPayload { | ||
time: number; | ||
delta: number; | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -115,2 +115,6 @@ /* | ||
if (this.delayFor <= 0 && this.progress === 0) { | ||
this.emit('start', {}); | ||
} | ||
this.progress += dt / duration; | ||
@@ -117,0 +121,0 @@ |
@@ -29,2 +29,8 @@ /* | ||
export class CoreAnimationController implements IAnimationController { | ||
startedPromise: Promise<void> | null = null; | ||
/** | ||
* If this is null, then the animation hasn't started yet. | ||
*/ | ||
startedResolve: ((scope?: any) => void) | null = null; | ||
stoppedPromise: Promise<void> | null = null; | ||
@@ -46,2 +52,5 @@ /** | ||
start(): IAnimationController { | ||
this.makeStartedPromise(); | ||
this.animation.once('start', this.started.bind(this)); | ||
this.makeStoppedPromise(); | ||
@@ -82,2 +91,9 @@ this.animation.once('finished', this.finished.bind(this)); | ||
waitUntilStarted(): Promise<void> { | ||
this.makeStartedPromise(); | ||
const promise = this.startedPromise; | ||
assertTruthy(promise); | ||
return promise; | ||
} | ||
waitUntilStopped(): Promise<void> { | ||
@@ -90,2 +106,10 @@ this.makeStoppedPromise(); | ||
private makeStartedPromise(): void { | ||
if (this.startedResolve === null) { | ||
this.startedPromise = new Promise((resolve) => { | ||
this.startedResolve = resolve; | ||
}); | ||
} | ||
} | ||
private makeStoppedPromise(): void { | ||
@@ -99,2 +123,9 @@ if (this.stoppedResolve === null) { | ||
private started(): void { | ||
assertTruthy(this.startedResolve); | ||
// resolve promise (and pass current this to continue to the chain) | ||
this.startedResolve(this); | ||
this.startedResolve = null; | ||
} | ||
private finished(): void { | ||
@@ -101,0 +132,0 @@ assertTruthy(this.stoppedResolve); |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ import { |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ import type { |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -36,3 +36,6 @@ /* | ||
import { ContextSpy } from './lib/ContextSpy.js'; | ||
import type { FpsUpdatePayload } from '../common/CommonTypes.js'; | ||
import type { | ||
FpsUpdatePayload, | ||
FrameTickPayload, | ||
} from '../common/CommonTypes.js'; | ||
@@ -61,2 +64,7 @@ export interface StageOptions { | ||
export type StageFrameTickHandler = ( | ||
stage: Stage, | ||
frameTickData: FrameTickPayload, | ||
) => void; | ||
const bufferMemory = 2e6; | ||
@@ -196,2 +204,6 @@ const autoStart = true; | ||
this.emit('frameTick', { | ||
time: this.currentFrameTime, | ||
delta: this.deltaTime, | ||
}); | ||
// step animation | ||
@@ -198,0 +210,0 @@ animationManager.update(this.deltaTime); |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ interface ImportMetaEnv { |
@@ -20,4 +20,7 @@ /* | ||
import type { FpsUpdatePayload } from '../common/CommonTypes.js'; | ||
import type { | ||
FpsUpdatePayload, | ||
FrameTickPayload, | ||
} from '../common/CommonTypes.js'; | ||
import type { | ||
INode, | ||
@@ -62,2 +65,4 @@ INodeWritableProps, | ||
onFpsUpdate(fpsData: FpsUpdatePayload): void; | ||
onFrameTick(frameTickData: FrameTickPayload): void; | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -41,2 +41,3 @@ /* | ||
import { EventEmitter } from '../common/EventEmitter.js'; | ||
import { Inspector } from './Inspector.js'; | ||
@@ -242,2 +243,14 @@ /** | ||
numImageWorkers?: number; | ||
/** | ||
* Enable inspector | ||
* | ||
* @remarks | ||
* When enabled the renderer will spawn a inspector. The inspector will | ||
* replicate the state of the Nodes created in the renderer and allow | ||
* inspection of the state of the nodes. | ||
* | ||
* @defaultValue `false` (disabled) | ||
*/ | ||
enableInspector?: boolean; | ||
} | ||
@@ -274,2 +287,3 @@ | ||
readonly settings: Readonly<Required<RendererMainSettings>>; | ||
private inspector: Inspector | null = null; | ||
private nodes: Map<number, INode> = new Map(); | ||
@@ -314,2 +328,3 @@ private nextTextureId = 1; | ||
enableContextSpy: settings.enableContextSpy ?? false, | ||
enableInspector: settings.enableInspector ?? false, | ||
}; | ||
@@ -323,2 +338,3 @@ this.settings = resolvedSettings; | ||
devicePhysicalPixelRatio, | ||
enableInspector, | ||
} = resolvedSettings; | ||
@@ -377,3 +393,11 @@ | ||
driver.onFrameTick = (frameTickData) => { | ||
this.emit('frameTick', frameTickData); | ||
}; | ||
targetEl.appendChild(canvas); | ||
if (enableInspector && !import.meta.env.PROD) { | ||
this.inspector = new Inspector(canvas, resolvedSettings); | ||
} | ||
} | ||
@@ -410,2 +434,9 @@ | ||
createNode(props: Partial<INodeWritableProps>): INode { | ||
if (this.inspector) { | ||
return this.inspector.createNode( | ||
this.driver, | ||
this.resolveNodeDefaults(props), | ||
); | ||
} | ||
return this.driver.createNode(this.resolveNodeDefaults(props)); | ||
@@ -453,2 +484,6 @@ } | ||
if (this.inspector) { | ||
return this.inspector.createTextNode(this.driver, data); | ||
} | ||
return this.driver.createTextNode(data); | ||
@@ -525,2 +560,6 @@ } | ||
destroyNode(node: INode) { | ||
if (this.inspector) { | ||
this.inspector.destroyNode(node); | ||
} | ||
return this.driver.destroyNode(node); | ||
@@ -527,0 +566,0 @@ } |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -28,3 +28,7 @@ /* | ||
import { MainOnlyNode, getNewId } from './MainOnlyNode.js'; | ||
import { Stage, type StageFpsUpdateHandler } from '../../core/Stage.js'; | ||
import { | ||
Stage, | ||
type StageFpsUpdateHandler, | ||
type StageFrameTickHandler, | ||
} from '../../core/Stage.js'; | ||
import type { | ||
@@ -36,3 +40,6 @@ RendererMain, | ||
import { loadCoreExtension } from '../utils.js'; | ||
import type { FpsUpdatePayload } from '../../common/CommonTypes.js'; | ||
import type { | ||
FpsUpdatePayload, | ||
FrameTickPayload, | ||
} from '../../common/CommonTypes.js'; | ||
@@ -85,2 +92,6 @@ export class MainCoreDriver implements ICoreDriver { | ||
}) satisfies StageFpsUpdateHandler); | ||
this.stage.on('frameTick', ((stage, frameTickData) => { | ||
this.onFrameTick(frameTickData); | ||
}) satisfies StageFrameTickHandler); | ||
} | ||
@@ -135,3 +146,7 @@ | ||
} | ||
onFrameTick(frameTickData: FrameTickPayload) { | ||
throw new Error('Method not implemented.'); | ||
} | ||
//#endregion | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -45,3 +45,6 @@ /* | ||
import { ThreadXMainTextNode } from './ThreadXMainTextNode.js'; | ||
import type { FpsUpdatePayload } from '../../common/CommonTypes.js'; | ||
import type { | ||
FpsUpdatePayload, | ||
FrameTickPayload, | ||
} from '../../common/CommonTypes.js'; | ||
@@ -86,2 +89,7 @@ export interface ThreadXRendererSettings { | ||
} | ||
// Forward frameTick events from the renderer worker's Stage to RendererMain | ||
if (isThreadXRendererMessage('frameTick', message)) { | ||
this.onFrameTick(message.frameTickData); | ||
} | ||
}, | ||
@@ -274,3 +282,7 @@ }); | ||
} | ||
onFrameTick(frameTickData: FrameTickPayload): void { | ||
throw new Error('Method not implemented.'); | ||
} | ||
//#endregion | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -20,3 +20,6 @@ /* | ||
import type { FpsUpdatePayload } from '../../common/CommonTypes.js'; | ||
import type { | ||
FpsUpdatePayload, | ||
FrameTickPayload, | ||
} from '../../common/CommonTypes.js'; | ||
@@ -74,2 +77,11 @@ /** | ||
/** | ||
* A message sent from the renderer worker to the main worker to update the FPS | ||
*/ | ||
export interface ThreadXRendererFrameTickMessage | ||
extends ThreadXRendererMessage { | ||
type: 'frameTick'; | ||
frameTickData: FrameTickPayload; | ||
} | ||
/** | ||
* A map of message types to message shapes | ||
@@ -81,2 +93,3 @@ */ | ||
fpsUpdate: ThreadXRendererFpsUpdateMessage; | ||
frameTick: ThreadXRendererFrameTickMessage; | ||
} | ||
@@ -83,0 +96,0 @@ |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ import { CoreExtension } from '../../exports/core-api.js'; |
@@ -0,0 +0,0 @@ /* |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1700256
425
2
37576
1
4