Compare commits

...

4 Commits

Author SHA1 Message Date
10c51896be Merge branch 'main' into safe-reset-scene 2025-04-02 15:20:24 -07:00
34f05b3cf2 updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 09:57:06 -07:00
3c89ac8421 Update src/components/CommandBar/CommandBarSelectionInput.tsx
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-04-02 09:57:06 -07:00
d3f788050c safe reset scene w cache
Signed-off-by: Jess Frazelle <github@jessfraz.com>

fmt

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

get the outcome data back out

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

fmt

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

updates

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

updates

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

remove deferrer

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

move the artifact graph to kclmanager, dont defer

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

updates

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

cleanup xstate stuffs

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

updates

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

updates

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

updates

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

updates

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

fmt

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

updates

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

updates

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

fixes

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

fixes

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

fix tsc

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 09:57:04 -07:00
6 changed files with 101 additions and 88 deletions

View File

@ -81,9 +81,7 @@ function CommandBarSelectionInput({
return () => { return () => {
toSync(() => { toSync(() => {
const promises = [ const promises = [kclManager.defaultSelectionFilter(selection)]
new Promise(() => kclManager.defaultSelectionFilter(selection)),
]
if (!kclManager._isAstEmpty(kclManager.ast)) { if (!kclManager._isAstEmpty(kclManager.ast)) {
promises.push(kclManager.hidePlanes()) promises.push(kclManager.hidePlanes())
} }
@ -130,7 +128,10 @@ function CommandBarSelectionInput({
// Set selection filter if needed, and reset it when the component unmounts // Set selection filter if needed, and reset it when the component unmounts
useEffect(() => { useEffect(() => {
arg.selectionFilter && kclManager.setSelectionFilter(arg.selectionFilter) arg.selectionFilter && kclManager.setSelectionFilter(arg.selectionFilter)
return () => kclManager.defaultSelectionFilter(selection) // TODO: We shouldn't use async here.
return toSync(async () => {
await kclManager.defaultSelectionFilter(selection)
}, reportRejection)
}, [arg.selectionFilter]) }, [arg.selectionFilter])
return ( return (

View File

@ -8,6 +8,8 @@ import {
getSelectionCountByType, getSelectionCountByType,
} from '@src/lib/selections' } from '@src/lib/selections'
import { kclManager } from '@src/lib/singletons' import { kclManager } from '@src/lib/singletons'
import { reportRejection } from '@src/lib/trap'
import { toSync } from '@src/lib/utils'
import { import {
commandBarActor, commandBarActor,
useCommandBarState, useCommandBarState,
@ -64,7 +66,10 @@ export default function CommandBarSelectionMixedInput({
// Set selection filter if needed, and reset it when the component unmounts // Set selection filter if needed, and reset it when the component unmounts
useEffect(() => { useEffect(() => {
arg.selectionFilter && kclManager.setSelectionFilter(arg.selectionFilter) arg.selectionFilter && kclManager.setSelectionFilter(arg.selectionFilter)
return () => kclManager.defaultSelectionFilter(selection) // TODO: We shouldn't use async here.
return toSync(async () => {
await kclManager.defaultSelectionFilter(selection)
}, reportRejection)
}, [arg.selectionFilter]) }, [arg.selectionFilter])
function handleChange() { function handleChange() {

View File

@ -211,6 +211,22 @@ export const ModelingMachineProvider = ({
.catch(reportRejection) .catch(reportRejection)
})().catch(reportRejection) })().catch(reportRejection)
}, },
execute: ({ context: { store } }) => {
// TODO: Remove this async callback. For some reason eslint wouldn't
// let me disable @typescript-eslint/no-misused-promises for the line.
;(async () => {
return kclManager
.executeCode()
.then(() => {
if (engineCommandManager.engineConnection?.idleMode) return
store.videoElement?.play().catch((e) => {
console.warn('Video playing was prevented', e)
})
})
.catch(reportRejection)
})().catch(reportRejection)
},
'Set mouse state': assign(({ context, event }) => { 'Set mouse state': assign(({ context, event }) => {
if (event.type !== 'Set mouse state') return {} if (event.type !== 'Set mouse state') return {}
const nextSegmentHoverMap = () => { const nextSegmentHoverMap = () => {

View File

@ -268,13 +268,14 @@ export const Stream = () => {
if (state.matches('Sketch')) return if (state.matches('Sketch')) return
// Only respect default plane selection if we're on a selection command argument // Only respect default plane selection if we're on a selection command argument
if ( if (
state.matches({ idle: 'showPlanes' }) && !kclManager.defaultPlanesShown &&
!( !(
commandBarState.matches('Gathering arguments') && commandBarState.matches('Gathering arguments') &&
commandBarState.context.currentArgument?.inputType === 'selection' commandBarState.context.currentArgument?.inputType === 'selection'
) )
) )
return return
// If we're mousing up from a camera drag, don't send a select event // If we're mousing up from a camera drag, don't send a select event
if (sceneInfra.camControls.wasDragging === true) return if (sceneInfra.camControls.wasDragging === true) return
@ -295,7 +296,7 @@ export const Stream = () => {
!isNetworkOkay || !isNetworkOkay ||
!videoRef.current || !videoRef.current ||
state.matches('Sketch') || state.matches('Sketch') ||
state.matches({ idle: 'showPlanes' }) || !kclManager.defaultPlanesShown ||
sceneInfra.camControls.wasDragging === true || sceneInfra.camControls.wasDragging === true ||
!btnName(e.nativeEvent).left !btnName(e.nativeEvent).left
) { ) {

View File

@ -53,7 +53,7 @@ import {
sceneInfra, sceneInfra,
} from '@src/lib/singletons' } from '@src/lib/singletons'
import { err, reportRejection } from '@src/lib/trap' import { err, reportRejection } from '@src/lib/trap'
import { deferExecution, isOverlap, uuidv4 } from '@src/lib/utils' import { isOverlap, uuidv4 } from '@src/lib/utils'
interface ExecuteArgs { interface ExecuteArgs {
ast?: Node<Program> ast?: Node<Program>
@ -317,23 +317,44 @@ export class KclManager {
this.artifactGraph = execStateArtifactGraph this.artifactGraph = execStateArtifactGraph
this.artifactIndex = buildArtifactIndex(execStateArtifactGraph) this.artifactIndex = buildArtifactIndex(execStateArtifactGraph)
if (this.artifactGraph.size) { if (this.artifactGraph.size) {
// TODO: we wanna remove this logic from xstate, it is racey // Hide the planes.
// This defer is bullshit but playwright wants it await Promise.all([this.hidePlanes(), this.defaultSelectionFilter()])
// It was like this in engineConnection.ts already } else if (!this.hasErrors()) {
deferExecution((a?: null) => { // Only show the planes if there are no errors.
this.engineCommandManager.modelingSend({ // Show the planes and reset.
type: 'Artifact graph emptied', await this.showAndResetPlanes()
})
}, 200)(null)
} else {
deferExecution((a?: null) => {
this.engineCommandManager.modelingSend({
type: 'Artifact graph populated',
})
}, 200)(null)
} }
} }
private async showAndResetPlanes(): Promise<void> {
await Promise.all([
this.showPlanes(),
this.resetCameraPosition(),
this.engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'set_selection_filter',
filter: ['curve'],
},
}),
])
}
async resetCameraPosition(): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
await this.engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_look_at',
center: { x: 0, y: 0, z: 0 },
vantage: { x: 0, y: -1250, z: 580 },
up: { x: 0, y: 0, z: 1 },
},
})
}
// Some "objects" have the same source range, such as sketch_mode_start and start_path. // Some "objects" have the same source range, such as sketch_mode_start and start_path.
// So when passing a range, we need to also specify the command type // So when passing a range, we need to also specify the command type
private mapRangeToObjectId( private mapRangeToObjectId(
@ -704,8 +725,9 @@ export class KclManager {
return rustContext.defaultPlanes return rustContext.defaultPlanes
} }
showPlanes(all = false) { async showPlanes(all = false): Promise<void> {
if (!this.defaultPlanes) return Promise.all([]) if (!this.defaultPlanes) return
this.defaultPlanesShown = true
const thePromises = [ const thePromises = [
this.engineCommandManager.setPlaneHidden(this.defaultPlanes.xy, false), this.engineCommandManager.setPlaneHidden(this.defaultPlanes.xy, false),
this.engineCommandManager.setPlaneHidden(this.defaultPlanes.yz, false), this.engineCommandManager.setPlaneHidden(this.defaultPlanes.yz, false),
@ -731,11 +753,12 @@ export class KclManager {
) )
) )
} }
return Promise.all(thePromises) await Promise.all(thePromises)
} }
hidePlanes(all = false) { async hidePlanes(all = false): Promise<void> {
if (!this.defaultPlanes) return Promise.all([]) if (!this.defaultPlanes) return
this.defaultPlanesShown = false
const thePromises = [ const thePromises = [
this.engineCommandManager.setPlaneHidden(this.defaultPlanes.xy, true), this.engineCommandManager.setPlaneHidden(this.defaultPlanes.xy, true),
this.engineCommandManager.setPlaneHidden(this.defaultPlanes.yz, true), this.engineCommandManager.setPlaneHidden(this.defaultPlanes.yz, true),
@ -752,15 +775,20 @@ export class KclManager {
this.engineCommandManager.setPlaneHidden(this.defaultPlanes.negXz, true) this.engineCommandManager.setPlaneHidden(this.defaultPlanes.negXz, true)
) )
} }
return Promise.all(thePromises) await Promise.all(thePromises)
} }
/** TODO: this function is hiding unawaited asynchronous work */
defaultSelectionFilter(selectionsToRestore?: Selections) { async defaultSelectionFilter(
setSelectionFilterToDefault(this.engineCommandManager, selectionsToRestore) selectionsToRestore?: Selections
): Promise<void> {
await setSelectionFilterToDefault(
this.engineCommandManager,
selectionsToRestore
)
} }
/** TODO: this function is hiding unawaited asynchronous work */
setSelectionFilter(filter: EntityType_type[]) { async setSelectionFilter(filter: EntityType_type[]): Promise<void> {
setSelectionFilter(filter, this.engineCommandManager) await setSelectionFilter(filter, this.engineCommandManager)
} }
/** /**
@ -801,33 +829,29 @@ const defaultSelectionFilter: EntityType_type[] = [
'object', 'object',
] ]
/** TODO: This function is not synchronous but is currently treated as such */ async function setSelectionFilterToDefault(
function setSelectionFilterToDefault(
engineCommandManager: EngineCommandManager, engineCommandManager: EngineCommandManager,
selectionsToRestore?: Selections selectionsToRestore?: Selections
) { ): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-floating-promises await setSelectionFilter(
setSelectionFilter(
defaultSelectionFilter, defaultSelectionFilter,
engineCommandManager, engineCommandManager,
selectionsToRestore selectionsToRestore
) )
} }
/** TODO: This function is not synchronous but is currently treated as such */ async function setSelectionFilter(
function setSelectionFilter(
filter: EntityType_type[], filter: EntityType_type[],
engineCommandManager: EngineCommandManager, engineCommandManager: EngineCommandManager,
selectionsToRestore?: Selections selectionsToRestore?: Selections
) { ): Promise<void> {
const { engineEvents } = selectionsToRestore const { engineEvents } = selectionsToRestore
? handleSelectionBatch({ ? handleSelectionBatch({
selections: selectionsToRestore, selections: selectionsToRestore,
}) })
: { engineEvents: undefined } : { engineEvents: undefined }
if (!selectionsToRestore || !engineEvents) { if (!selectionsToRestore || !engineEvents) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises await engineCommandManager.sendSceneCommand({
engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req', type: 'modeling_cmd_req',
cmd_id: uuidv4(), cmd_id: uuidv4(),
cmd: { cmd: {
@ -847,7 +871,7 @@ function setSelectionFilter(
} }
}) })
// batch is needed other wise the selection flickers. // batch is needed other wise the selection flickers.
engineCommandManager await engineCommandManager
.sendSceneCommand({ .sendSceneCommand({
type: 'modeling_cmd_batch_req', type: 'modeling_cmd_batch_req',
batch_id: uuidv4(), batch_id: uuidv4(),

File diff suppressed because one or more lines are too long