TickManager listener lifecycle is the root cause of the strict-mode camera-state workaround
#8,892 建立於 2026年5月20日
描述
Problem
The "reset camera state on dispose" block in Editor.ts:411–416 papers over a deeper issue: 'tick' event listeners are added by Editor after TickManager starts, but TickManager.dispose doesn't track or remove them — they're owned by the EventEmitter superclass. On React Strict Mode double-mount, listeners may re-bind to stale closure scopes.
Where
packages/editor/src/lib/editor/managers/TickManager/TickManager.ts:49–55—disposeonly cancels RAF, doesn't unregister listenerspackages/editor/src/lib/editor/Editor.ts:411–416— the workaround comment plusoff('tick', ...)and_setCameraState('idle')reset- Multiple
'tick'listener call sites acrossEditor.ts
Suggested fix
Let TickManager own the listener registry: onTick(cb) returns an unsubscribe, and TickManager.dispose unregisters all of them. Demote editor.inputs.updatePointerVelocity from a privileged hard-coded call inside tick() to an ordinary frame listener registered by InputsManager. Once that's symmetric, the workaround in Editor.ts:411–416 can be removed.
Context
Surfaced during an internal modularity audit of the editor manager classes.