Skip to content

Commit 00b4300

Browse files
#7808 Throttle mousemove to improve dragging performance in sketching (#7812)
* throttle mousemove events to avoid executeAstMock to be invoked while a previous one is still running * Update snapshots * Update snapshots --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 037a29f commit 00b4300

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed
1.5 KB
Loading

src/clientSideScene/sceneEntities.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,7 @@ export class SceneEntities {
11851185
)
11861186
}
11871187
},
1188-
onMove: (args) => {
1188+
onMove: async (args) => {
11891189
const expressionIndex = Number(sketchEntryNodePath[1][0])
11901190
const activeSegmentsInCorrectExpression = Object.values(
11911191
this.activeSegments
@@ -1196,7 +1196,7 @@ export class SceneEntities {
11961196
activeSegmentsInCorrectExpression[
11971197
activeSegmentsInCorrectExpression.length - 1
11981198
]
1199-
this.onDragSegment({
1199+
await this.onDragSegment({
12001200
intersection2d: args.intersectionPoint.twoD,
12011201
object,
12021202
intersects: args.intersects,
@@ -2576,7 +2576,7 @@ export class SceneEntities {
25762576
} else if (addingNewSegmentStatus === 'added') {
25772577
const pathToNodeForNewSegment = pathToNode.slice(0, pathToNodeIndex)
25782578
pathToNodeForNewSegment.push([pipeIndex - 2, 'index'])
2579-
this.onDragSegment({
2579+
await this.onDragSegment({
25802580
sketchNodePaths,
25812581
sketchEntryNodePath: pathToNodeForNewSegment,
25822582
object: selected,
@@ -2588,7 +2588,7 @@ export class SceneEntities {
25882588
return
25892589
}
25902590

2591-
this.onDragSegment({
2591+
await this.onDragSegment({
25922592
object: selected,
25932593
intersection2d: intersectionPoint.twoD,
25942594
intersects,
@@ -2817,7 +2817,7 @@ export class SceneEntities {
28172817
return intersection2d
28182818
}
28192819

2820-
onDragSegment({
2820+
async onDragSegment({
28212821
object,
28222822
intersection2d: _intersection2d,
28232823
sketchEntryNodePath,
@@ -3074,17 +3074,19 @@ export class SceneEntities {
30743074
: this.prepareTruncatedAst(sketchNodePaths || [], modifiedAst)
30753075
if (trap(info, { suppress: true })) return
30763076
const { truncatedAst } = info
3077-
;(async () => {
3077+
try {
30783078
const code = recast(modifiedAst)
30793079
if (trap(code)) return
30803080
if (!draftInfo)
30813081
// don't want to mod the user's code yet as they have't committed to the change yet
30823082
// plus this would be the truncated ast being recast, it would be wrong
30833083
this.codeManager.updateCodeEditor(code)
3084+
30843085
const { execState } = await executeAstMock({
30853086
ast: truncatedAst,
30863087
rustContext: this.rustContext,
30873088
})
3089+
30883090
const variables = execState.variables
30893091
const sketchesInfo = getSketchesInfo({
30903092
sketchNodePaths,
@@ -3138,7 +3140,9 @@ export class SceneEntities {
31383140
)
31393141
}
31403142
this.sceneInfra.overlayCallbacks(callbacks)
3141-
})().catch(reportRejection)
3143+
} catch (e) {
3144+
reportRejection(e)
3145+
}
31423146
}
31433147

31443148
/**

src/clientSideScene/sceneInfra.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,24 @@ export class SceneInfra {
449449
intersection: planeIntersects[0],
450450
}
451451
}
452+
453+
public mouseMoveThrottling = true // Can be turned off for debugging
454+
private _processingMouseMove = false
455+
private _lastUnprocessedMouseEvent: MouseEvent | undefined
456+
452457
onMouseMove = async (mouseEvent: MouseEvent) => {
458+
if (this.mouseMoveThrottling) {
459+
// Throttle mouse move events to help with performance.
460+
// Without this a new call to executeAstMock() is made by SceneEntities/onDragSegment() while the
461+
// previous one is still running, causing multiple wasm calls to be running at the same time.
462+
// Here we simply ignore the mouse move event if we are already processing one, until the processing is done.
463+
if (this._processingMouseMove) {
464+
this._lastUnprocessedMouseEvent = mouseEvent
465+
return
466+
}
467+
this._processingMouseMove = true
468+
}
469+
453470
this.currentMouseVector.x = (mouseEvent.clientX / window.innerWidth) * 2 - 1
454471
this.currentMouseVector.y =
455472
-(mouseEvent.clientY / window.innerHeight) * 2 + 1
@@ -473,18 +490,19 @@ export class SceneInfra {
473490
planeIntersectPoint.twoD &&
474491
planeIntersectPoint.threeD
475492
) {
493+
const selected = this.selected
476494
await this.onDragCallback({
477495
mouseEvent,
478496
intersectionPoint: {
479497
twoD: planeIntersectPoint.twoD,
480498
threeD: planeIntersectPoint.threeD,
481499
},
482500
intersects,
483-
selected: this.selected.object,
501+
selected: selected.object,
484502
})
485503
this.updateMouseState({
486504
type: 'isDragging',
487-
on: this.selected.object,
505+
on: selected.object,
488506
})
489507
}
490508
} else if (
@@ -545,6 +563,17 @@ export class SceneInfra {
545563
if (!this.selected) this.updateMouseState({ type: 'idle' })
546564
}
547565
}
566+
567+
if (this.mouseMoveThrottling) {
568+
this._processingMouseMove = false
569+
const lastUnprocessedMouseEvent = this._lastUnprocessedMouseEvent
570+
if (lastUnprocessedMouseEvent) {
571+
// Another mousemove happened during the time this callback was processing
572+
// -> process that event now
573+
this._lastUnprocessedMouseEvent = undefined
574+
void this.onMouseMove(lastUnprocessedMouseEvent)
575+
}
576+
}
548577
}
549578

550579
raycastRing = (

0 commit comments

Comments
 (0)