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 () => {
toSync(() => {
const promises = [
new Promise(() => kclManager.defaultSelectionFilter(selection)),
]
const promises = [kclManager.defaultSelectionFilter(selection)]
if (!kclManager._isAstEmpty(kclManager.ast)) {
promises.push(kclManager.hidePlanes())
}
@ -130,7 +128,10 @@ function CommandBarSelectionInput({
// Set selection filter if needed, and reset it when the component unmounts
useEffect(() => {
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])
return (

View File

@ -8,6 +8,8 @@ import {
getSelectionCountByType,
} from '@src/lib/selections'
import { kclManager } from '@src/lib/singletons'
import { reportRejection } from '@src/lib/trap'
import { toSync } from '@src/lib/utils'
import {
commandBarActor,
useCommandBarState,
@ -64,7 +66,10 @@ export default function CommandBarSelectionMixedInput({
// Set selection filter if needed, and reset it when the component unmounts
useEffect(() => {
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])
function handleChange() {

View File

@ -211,6 +211,22 @@ export const ModelingMachineProvider = ({
.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 }) => {
if (event.type !== 'Set mouse state') return {}
const nextSegmentHoverMap = () => {

View File

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

View File

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

File diff suppressed because one or more lines are too long