tsc lint fmt
This commit is contained in:
@ -163,7 +163,7 @@ export function App() {
|
|||||||
videoRef,
|
videoRef,
|
||||||
canvasRef,
|
canvasRef,
|
||||||
mediaStream: null,
|
mediaStream: null,
|
||||||
authToken: token ?? null,
|
authToken: token,
|
||||||
pool,
|
pool,
|
||||||
zoomToFit: true,
|
zoomToFit: true,
|
||||||
},
|
},
|
||||||
|
@ -280,6 +280,11 @@ export class CameraControls {
|
|||||||
>[0]
|
>[0]
|
||||||
|
|
||||||
const cb = ({ data, type }: CallBackParam) => {
|
const cb = ({ data, type }: CallBackParam) => {
|
||||||
|
// We're reconnecting, so ignore this init proces.
|
||||||
|
if (this.old) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const camSettings = data.settings
|
const camSettings = data.settings
|
||||||
this.camera.position.set(
|
this.camera.position.set(
|
||||||
camSettings.pos.x,
|
camSettings.pos.x,
|
||||||
@ -291,6 +296,7 @@ export class CameraControls {
|
|||||||
camSettings.center.y,
|
camSettings.center.y,
|
||||||
camSettings.center.z
|
camSettings.center.z
|
||||||
)
|
)
|
||||||
|
|
||||||
const orientation = new Quaternion(
|
const orientation = new Quaternion(
|
||||||
camSettings.orientation.x,
|
camSettings.orientation.x,
|
||||||
camSettings.orientation.y,
|
camSettings.orientation.y,
|
||||||
|
@ -14,6 +14,7 @@ import { PATHS } from 'lib/paths'
|
|||||||
import { IndexLoaderData } from 'lib/types'
|
import { IndexLoaderData } from 'lib/types'
|
||||||
import { err, reportRejection, trap } from 'lib/trap'
|
import { err, reportRejection, trap } from 'lib/trap'
|
||||||
import { getArtifactOfTypes } from 'lang/std/artifactGraph'
|
import { getArtifactOfTypes } from 'lang/std/artifactGraph'
|
||||||
|
import { clearSceneAndBustCache } from 'lang/wasm'
|
||||||
import { ViewControlContextMenu } from './ViewControlMenu'
|
import { ViewControlContextMenu } from './ViewControlMenu'
|
||||||
import { commandBarActor, useCommandBarState } from 'machines/commandBarMachine'
|
import { commandBarActor, useCommandBarState } from 'machines/commandBarMachine'
|
||||||
import { useSelector } from '@xstate/react'
|
import { useSelector } from '@xstate/react'
|
||||||
@ -67,18 +68,20 @@ export const EngineStream = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const play = () => {
|
const play = () => {
|
||||||
engineStreamActor.send({
|
engineStreamActor.send({
|
||||||
type: EngineStreamTransition.Play,
|
type: EngineStreamTransition.Play,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
engineCommandManager.addEventListener(
|
engineCommandManager.addEventListener(
|
||||||
EngineCommandManagerEvents.SceneReady,
|
EngineCommandManagerEvents.SceneReady,
|
||||||
play
|
play
|
||||||
)
|
)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
engineCommandManager.tearDown()
|
||||||
engineCommandManager.removeEventListener(
|
engineCommandManager.removeEventListener(
|
||||||
EngineCommandManagerEvents.SceneReady,
|
EngineCommandManagerEvents.SceneReady,
|
||||||
play
|
play
|
||||||
@ -87,6 +90,7 @@ export const EngineStream = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (engineStreamState.value === EngineStreamState.Reconfiguring) return
|
||||||
const video = engineStreamState.context.videoRef?.current
|
const video = engineStreamState.context.videoRef?.current
|
||||||
if (!video) return
|
if (!video) return
|
||||||
const canvas = engineStreamState.context.canvasRef?.current
|
const canvas = engineStreamState.context.canvasRef?.current
|
||||||
@ -123,10 +127,8 @@ export const EngineStream = () => {
|
|||||||
// On settings change, reconfigure the engine. When paused this gets really tricky,
|
// On settings change, reconfigure the engine. When paused this gets really tricky,
|
||||||
// and also requires onMediaStream to be set!
|
// and also requires onMediaStream to be set!
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (engineStreamState.value === EngineStreamState.Playing) {
|
|
||||||
startOrReconfigureEngine()
|
startOrReconfigureEngine()
|
||||||
}
|
}, Object.values(settingsEngine))
|
||||||
}, [settings.context, engineStreamState.value])
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to execute code when the file changes
|
* Subscribe to execute code when the file changes
|
||||||
@ -135,8 +137,8 @@ export const EngineStream = () => {
|
|||||||
*/
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (engineCommandManager.engineConnection?.isReady() && file?.path) {
|
if (engineCommandManager.engineConnection?.isReady() && file?.path) {
|
||||||
console.log('execute on file change')
|
console.log('file changed, executing code')
|
||||||
void kclManager.executeCode(true).catch(trap)
|
kclManager.executeCode(true).catch(trap)
|
||||||
}
|
}
|
||||||
}, [file?.path, engineCommandManager.engineConnection])
|
}, [file?.path, engineCommandManager.engineConnection])
|
||||||
|
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
|
import { uuidv4 } from 'lib/utils'
|
||||||
import { makeDefaultPlanes, clearSceneAndBustCache } from 'lang/wasm'
|
import { makeDefaultPlanes, clearSceneAndBustCache } from 'lang/wasm'
|
||||||
import { MutableRefObject } from 'react'
|
import { MutableRefObject } from 'react'
|
||||||
import { setup, assign, fromPromise } from 'xstate'
|
import { setup, assign, fromPromise } from 'xstate'
|
||||||
import { createActorContext } from '@xstate/react'
|
import { createActorContext } from '@xstate/react'
|
||||||
import { kclManager, sceneInfra, engineCommandManager } from 'lib/singletons'
|
import { kclManager, sceneInfra, engineCommandManager } from 'lib/singletons'
|
||||||
import { trap } from 'lib/trap'
|
import { trap } from 'lib/trap'
|
||||||
|
import { Vector3, Vector4 } from 'three'
|
||||||
|
|
||||||
export enum EngineStreamState {
|
export enum EngineStreamState {
|
||||||
Off = 'off',
|
Off = 'off',
|
||||||
On = 'on',
|
On = 'on',
|
||||||
WaitForMediaStream = 'wait-for-media-stream',
|
WaitForMediaStream = 'wait-for-media-stream',
|
||||||
Playing = 'playing',
|
Playing = 'playing',
|
||||||
|
Reconfiguring = 'reconfiguring',
|
||||||
Paused = 'paused',
|
Paused = 'paused',
|
||||||
// The is the state in-between Paused and Playing *specifically that order*.
|
// The is the state in-between Paused and Playing *specifically that order*.
|
||||||
Resuming = 'resuming',
|
Resuming = 'resuming',
|
||||||
@ -25,7 +28,7 @@ export enum EngineStreamTransition {
|
|||||||
|
|
||||||
export interface EngineStreamContext {
|
export interface EngineStreamContext {
|
||||||
pool: string | null
|
pool: string | null
|
||||||
authToken: string | null
|
authToken: string | undefined
|
||||||
mediaStream: MediaStream | null
|
mediaStream: MediaStream | null
|
||||||
videoRef: MutableRefObject<HTMLVideoElement | null>
|
videoRef: MutableRefObject<HTMLVideoElement | null>
|
||||||
canvasRef: MutableRefObject<HTMLCanvasElement | null>
|
canvasRef: MutableRefObject<HTMLCanvasElement | null>
|
||||||
@ -44,6 +47,23 @@ export function getDimensions(streamWidth: number, streamHeight: number) {
|
|||||||
return { width: quadWidth, height: quadHeight }
|
return { width: quadWidth, height: quadHeight }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function holdOntoVideoFrameInCanvas(
|
||||||
|
video: HTMLVideoElement,
|
||||||
|
canvas: HTMLCanvasElement
|
||||||
|
) {
|
||||||
|
video.pause()
|
||||||
|
canvas.width = video.videoWidth
|
||||||
|
canvas.height = video.videoHeight
|
||||||
|
canvas.style.width = video.videoWidth + 'px'
|
||||||
|
canvas.style.height = video.videoHeight + 'px'
|
||||||
|
canvas.style.display = 'block'
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
if (!ctx) return
|
||||||
|
|
||||||
|
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
|
||||||
|
}
|
||||||
|
|
||||||
const engineStreamMachine = setup({
|
const engineStreamMachine = setup({
|
||||||
types: {
|
types: {
|
||||||
context: {} as EngineStreamContext,
|
context: {} as EngineStreamContext,
|
||||||
@ -69,7 +89,6 @@ const engineStreamMachine = setup({
|
|||||||
canvas.style.display = 'none'
|
canvas.style.display = 'none'
|
||||||
|
|
||||||
await sceneInfra.camControls.restoreCameraPosition()
|
await sceneInfra.camControls.restoreCameraPosition()
|
||||||
await clearSceneAndBustCache(kclManager.engineCommandManager)
|
|
||||||
|
|
||||||
video.srcObject = mediaStream
|
video.srcObject = mediaStream
|
||||||
await video.play()
|
await video.play()
|
||||||
@ -91,36 +110,76 @@ const engineStreamMachine = setup({
|
|||||||
const canvas = context.canvasRef.current
|
const canvas = context.canvasRef.current
|
||||||
if (!canvas) return
|
if (!canvas) return
|
||||||
|
|
||||||
canvas.width = video.videoWidth
|
holdOntoVideoFrameInCanvas(video, canvas)
|
||||||
canvas.height = video.videoHeight
|
|
||||||
canvas.style.width = video.videoWidth + 'px'
|
|
||||||
canvas.style.height = video.videoHeight + 'px'
|
|
||||||
canvas.style.display = 'block'
|
|
||||||
|
|
||||||
const ctx = canvas.getContext('2d')
|
|
||||||
if (!ctx) return
|
|
||||||
|
|
||||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
|
|
||||||
|
|
||||||
// Make sure we're on the next frame for no flickering between canvas
|
// Make sure we're on the next frame for no flickering between canvas
|
||||||
// and the video elements.
|
// and the video elements.
|
||||||
window.requestAnimationFrame(() => {
|
window.requestAnimationFrame(
|
||||||
|
() =>
|
||||||
|
void (async () => {
|
||||||
video.style.display = 'none'
|
video.style.display = 'none'
|
||||||
|
|
||||||
// Destroy the media stream only. We will re-establish it. We could
|
// Destroy the media stream. We will re-establish it. We could
|
||||||
// leave everything at pausing, preventing video decoders from running
|
// leave everything at pausing, preventing video decoders from running
|
||||||
// but we can do even better by significantly reducing network
|
// but we can do even better by significantly reducing network
|
||||||
// cards also.
|
// cards also.
|
||||||
context.mediaStream?.getVideoTracks()[0].stop()
|
context.mediaStream?.getVideoTracks()[0].stop()
|
||||||
video.srcObject = null
|
video.srcObject = null
|
||||||
|
|
||||||
|
const reqDefaultCameraGetSettings =
|
||||||
|
await engineCommandManager.sendSceneCommand({
|
||||||
|
// CameraControls subscribes to default_camera_get_settings response events
|
||||||
|
// firing this at connection ensure the camera's are synced initially
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_get_settings',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
reqDefaultCameraGetSettings === null ||
|
||||||
|
!reqDefaultCameraGetSettings.success
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if (
|
||||||
|
!('modeling_response' in reqDefaultCameraGetSettings.resp.data)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if (
|
||||||
|
reqDefaultCameraGetSettings.resp.data.modeling_response.type ===
|
||||||
|
'empty'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
'settings' in
|
||||||
|
reqDefaultCameraGetSettings.resp.data.modeling_response.data
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
const center =
|
||||||
|
reqDefaultCameraGetSettings.resp.data.modeling_response.data
|
||||||
|
.settings.center
|
||||||
|
const pos =
|
||||||
|
reqDefaultCameraGetSettings.resp.data.modeling_response.data
|
||||||
|
.settings.pos
|
||||||
|
|
||||||
sceneInfra.camControls.old = {
|
sceneInfra.camControls.old = {
|
||||||
camera: sceneInfra.camControls.camera.clone(),
|
camera: sceneInfra.camControls.camera.clone(),
|
||||||
target: sceneInfra.camControls.target.clone(),
|
target: new Vector3(center.x, center.y, center.z),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sceneInfra.camControls.old.camera.position.set(
|
||||||
|
pos.x,
|
||||||
|
pos.y,
|
||||||
|
pos.z
|
||||||
|
)
|
||||||
|
|
||||||
engineCommandManager.tearDown({ idleMode: true })
|
engineCommandManager.tearDown({ idleMode: true })
|
||||||
})
|
})()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
[EngineStreamTransition.StartOrReconfigureEngine]: fromPromise(
|
[EngineStreamTransition.StartOrReconfigureEngine]: fromPromise(
|
||||||
@ -134,6 +193,9 @@ const engineStreamMachine = setup({
|
|||||||
const video = context.videoRef.current
|
const video = context.videoRef.current
|
||||||
if (!video) return
|
if (!video) return
|
||||||
|
|
||||||
|
const canvas = context.canvasRef.current
|
||||||
|
if (!canvas) return
|
||||||
|
|
||||||
const { width, height } = getDimensions(
|
const { width, height } = getDimensions(
|
||||||
window.innerWidth,
|
window.innerWidth,
|
||||||
window.innerHeight
|
window.innerHeight
|
||||||
@ -151,10 +213,20 @@ const engineStreamMachine = setup({
|
|||||||
|
|
||||||
engineCommandManager.settings = settingsNext
|
engineCommandManager.settings = settingsNext
|
||||||
|
|
||||||
|
// If we don't pause there could be a really bad flicker
|
||||||
|
// on reconfiguration (resize, for example)
|
||||||
|
holdOntoVideoFrameInCanvas(video, canvas)
|
||||||
|
canvas.style.display = 'block'
|
||||||
|
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
video.style.display = 'none'
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
setMediaStream: event.onMediaStream,
|
setMediaStream: event.onMediaStream,
|
||||||
setIsStreamReady: (isStreamReady) =>
|
setIsStreamReady: (isStreamReady) => {
|
||||||
event.setAppState({ isStreamReady }),
|
video.style.display = 'block'
|
||||||
|
canvas.style.display = 'none'
|
||||||
|
event.setAppState({ isStreamReady })
|
||||||
|
},
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
token: context.authToken,
|
token: context.authToken,
|
||||||
@ -173,6 +245,7 @@ const engineStreamMachine = setup({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -215,11 +288,23 @@ const engineStreamMachine = setup({
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
|
[EngineStreamTransition.StartOrReconfigureEngine]: {
|
||||||
|
target: EngineStreamState.Reconfiguring,
|
||||||
|
},
|
||||||
[EngineStreamTransition.Pause]: {
|
[EngineStreamTransition.Pause]: {
|
||||||
target: EngineStreamState.Paused,
|
target: EngineStreamState.Paused,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[EngineStreamState.Reconfiguring]: {
|
||||||
|
invoke: {
|
||||||
|
src: EngineStreamTransition.StartOrReconfigureEngine,
|
||||||
|
input: (args) => args,
|
||||||
|
onDone: {
|
||||||
|
target: EngineStreamState.Playing,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
[EngineStreamState.Paused]: {
|
[EngineStreamState.Paused]: {
|
||||||
invoke: {
|
invoke: {
|
||||||
src: EngineStreamTransition.Pause,
|
src: EngineStreamTransition.Pause,
|
||||||
|
@ -839,6 +839,11 @@ class EngineConnection extends EventTarget {
|
|||||||
|
|
||||||
this.engineCommandManager.inSequence = 1
|
this.engineCommandManager.inSequence = 1
|
||||||
|
|
||||||
|
// Bust the cache before anything
|
||||||
|
;(async () => {
|
||||||
|
await clearSceneAndBustCache(kclManager.engineCommandManager)
|
||||||
|
})().catch(reportRejection)
|
||||||
|
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent(EngineConnectionEvents.Opened, { detail: this })
|
new CustomEvent(EngineConnectionEvents.Opened, { detail: this })
|
||||||
)
|
)
|
||||||
@ -1801,7 +1806,6 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.engineConnection?.tearDown(opts)
|
this.engineConnection?.tearDown(opts)
|
||||||
this.engineConnection = undefined
|
|
||||||
|
|
||||||
// Our window.engineCommandManager.tearDown assignment causes this case to happen which is
|
// Our window.engineCommandManager.tearDown assignment causes this case to happen which is
|
||||||
// only really for tests.
|
// only really for tests.
|
||||||
@ -1812,6 +1816,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.engineCommandManager.engineConnection = null
|
this.engineCommandManager.engineConnection = null
|
||||||
}
|
}
|
||||||
|
this.engineConnection = undefined
|
||||||
}
|
}
|
||||||
async startNewSession() {
|
async startNewSession() {
|
||||||
this.responseMap = {}
|
this.responseMap = {}
|
||||||
|
Reference in New Issue
Block a user