add gizmo (#738)

* add gizmo

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixups

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix force ast execution

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2023-09-29 12:41:58 -07:00
committed by GitHub
parent 056fa00adc
commit a367be4e2b
4 changed files with 50 additions and 16 deletions

View File

@ -3,6 +3,7 @@ import { _executor } from '../lang/wasm'
import { useStore } from '../useStore'
import { engineCommandManager } from '../lang/std/engineConnection'
import { deferExecution } from 'lib/utils'
import { v4 as uuidv4 } from 'uuid'
export function useSetupEngineManager(
streamRef: React.RefObject<HTMLDivElement>,
@ -12,14 +13,14 @@ export function useSetupEngineManager(
setMediaStream,
setIsStreamReady,
setStreamDimensions,
executeCode,
streamDimensions,
executeCode,
} = useStore((s) => ({
setMediaStream: s.setMediaStream,
setIsStreamReady: s.setIsStreamReady,
setStreamDimensions: s.setStreamDimensions,
executeCode: s.executeCode,
streamDimensions: s.streamDimensions,
executeCode: s.executeCode,
}))
const streamWidth = streamRef?.current?.offsetWidth
@ -40,11 +41,9 @@ export function useSetupEngineManager(
setIsStreamReady,
width: quadWidth,
height: quadHeight,
executeCode,
token,
})
engineCommandManager.waitForReady.then(() => {
executeCode()
})
setStreamDimensions({
streamWidth: quadWidth,
streamHeight: quadHeight,

View File

@ -491,9 +491,11 @@ export class EngineConnection {
this.onDataChannelOpen(this)
this.onEngineConnectionOpen(this)
this.ready = true
this.connecting = false
// Do this after we set the connection is ready to avoid errors when
// we try to send messages before the connection is ready.
this.onEngineConnectionOpen(this)
})
this.unreliableDataChannel.addEventListener('close', (event) => {
@ -586,6 +588,9 @@ export class EngineCommandManager {
outSequence = 1
inSequence = 1
engineConnection?: EngineConnection
// Folks should realize that wait for ready does not get called _everytime_
// the connection resets and restarts, it only gets called the first time.
// Be careful what you put here.
waitForReady: Promise<void> = new Promise(() => {})
private resolveReady = () => {}
@ -609,12 +614,14 @@ export class EngineCommandManager {
setIsStreamReady,
width,
height,
executeCode,
token,
}: {
setMediaStream: (stream: MediaStream) => void
setIsStreamReady: (isStreamReady: boolean) => void
width: number
height: number
executeCode: (code?: string, force?: boolean) => void
token?: string
}) {
if (width === 0 || height === 0) {
@ -637,6 +644,32 @@ export class EngineCommandManager {
onEngineConnectionOpen: () => {
this.resolveReady()
setIsStreamReady(true)
// Make the axis gizmo.
// We do this after the connection opened to avoid a race condition.
// Connected opened is the last thing that happens when the stream
// is ready.
// We also do this here because we want to ensure we create the gizmo
// and execute the code everytime the stream is restarted.
const gizmoId = uuidv4()
this.sendSceneCommand({
type: 'modeling_cmd_req',
cmd_id: gizmoId,
cmd: {
type: 'make_axes_gizmo',
clobber: false,
// If true, axes gizmo will be placed in the corner of the screen.
// If false, it will be placed at the origin of the scene.
gizmo_mode: true,
},
})
// We execute the code here to make sure if the stream was to
// restart in a session, we want to make sure to execute the code.
// We force it to re-execute the code because we want to make sure
// the code is executed everytime the stream is restarted.
// We pass undefined for the code so it reads from the current state.
executeCode(undefined, true)
},
onClose: () => {
setIsStreamReady(false)
@ -733,10 +766,6 @@ export class EngineCommandManager {
this.engineConnection?.send(resizeCmd)
}
handleModelingCommand(message: WebSocketResponse, id: string) {
if (this.engineConnection === undefined) {
return
}
if (message.type !== 'modeling') {
return
}
@ -904,6 +933,11 @@ export class EngineCommandManager {
if (this.engineConnection === undefined) {
return Promise.resolve()
}
if (!this.engineConnection?.isReady()) {
return Promise.resolve()
}
if (
command.type === 'modeling_cmd_req' &&
command.cmd.type !== lastMessage
@ -911,9 +945,6 @@ export class EngineCommandManager {
console.log('sending command', command.cmd.type)
lastMessage = command.cmd.type
}
if (!this.engineConnection?.isReady()) {
return Promise.resolve()
}
if (command.type !== 'modeling_cmd_req') return Promise.resolve()
const cmd = command.cmd
if (

View File

@ -79,6 +79,7 @@ export async function executor(
setMediaStream: () => {},
width: 0,
height: 0,
executeCode: () => {},
})
await engineCommandManager.waitForReady
engineCommandManager.startNewSession()

View File

@ -157,7 +157,7 @@ export interface StoreState {
code: string
setCode: (code: string) => void
deferredSetCode: (code: string) => void
executeCode: (code?: string) => void
executeCode: (code?: string, force?: boolean) => void
formatCode: () => void
programMemory: ProgramMemory
setProgramMemory: (programMemory: ProgramMemory) => void
@ -221,11 +221,12 @@ export const useStore = create<StoreState>()(
editorView.dispatch({ effects: addLineHighlight.of(selection) })
}
},
executeCode: async (code) => {
executeCode: async (code, force) => {
const result = await executeCode({
code: code || get().code,
lastAst: get().ast,
engineCommandManager: engineCommandManager,
force,
})
if (!result.isChange) {
return
@ -511,10 +512,12 @@ async function executeCode({
engineCommandManager,
code,
lastAst,
force,
}: {
code: string
lastAst: Program
engineCommandManager: EngineCommandManager
force?: boolean
}): Promise<
| {
logs: string[]
@ -557,7 +560,7 @@ async function executeCode({
}
// Check if the ast we have is equal to the ast in the storage.
// If it is, we don't need to update the ast.
if (JSON.stringify(ast) === JSON.stringify(lastAst))
if (JSON.stringify(ast) === JSON.stringify(lastAst) && !force)
return { isChange: false }
const { logs, errors, programMemory } = await executeAst({