feat(runtime): provide shared animation scheduler per app, dispose on teardown
This commit is contained in:
@@ -20,6 +20,7 @@ import { createRoot, emitLayoutListeners, type TuiRoot, type TuiNode } from "./h
|
|||||||
import { attachYoga, detachYoga } from "./host/yoga.ts";
|
import { attachYoga, detachYoga } from "./host/yoga.ts";
|
||||||
import { buildNodeOps } from "./host/node-ops.ts";
|
import { buildNodeOps } from "./host/node-ops.ts";
|
||||||
import { createCommitScheduler } from "./scheduler.ts";
|
import { createCommitScheduler } from "./scheduler.ts";
|
||||||
|
import { createAnimationScheduler } from "./animation-scheduler.ts";
|
||||||
import { paint, paintIsolated } from "./paint/paint.ts";
|
import { paint, paintIsolated } from "./paint/paint.ts";
|
||||||
import { findStatics } from "./paint/static-channel.ts";
|
import { findStatics } from "./paint/static-channel.ts";
|
||||||
import { createFrameWriter } from "./io/frame-writer.ts";
|
import { createFrameWriter } from "./io/frame-writer.ts";
|
||||||
@@ -28,6 +29,7 @@ import {
|
|||||||
AppContextKey,
|
AppContextKey,
|
||||||
FocusContextKey,
|
FocusContextKey,
|
||||||
StdinContextKey,
|
StdinContextKey,
|
||||||
|
AnimationSchedulerKey,
|
||||||
type AppContext,
|
type AppContext,
|
||||||
type CursorPosition,
|
type CursorPosition,
|
||||||
type FocusContext,
|
type FocusContext,
|
||||||
@@ -171,6 +173,7 @@ export function createApp(root: Component, rootProps?: RootProps | null): TuiApp
|
|||||||
let mountedGetLastOutput: (() => string) | null = null;
|
let mountedGetLastOutput: (() => string) | null = null;
|
||||||
let mountedRestoreConsole: (() => void) | null = null;
|
let mountedRestoreConsole: (() => void) | null = null;
|
||||||
let mountedScheduler: ReturnType<typeof createCommitScheduler> | null = null;
|
let mountedScheduler: ReturnType<typeof createCommitScheduler> | null = null;
|
||||||
|
let mountedAnimationScheduler: ReturnType<typeof createAnimationScheduler> | null = null;
|
||||||
let mountedCommit: (() => void) | null = null;
|
let mountedCommit: (() => void) | null = null;
|
||||||
let mountedAlternateScreen = false;
|
let mountedAlternateScreen = false;
|
||||||
let mountedClear: (() => void) | null = null;
|
let mountedClear: (() => void) | null = null;
|
||||||
@@ -248,6 +251,10 @@ export function createApp(root: Component, rootProps?: RootProps | null): TuiApp
|
|||||||
} catch {
|
} catch {
|
||||||
// Vue's unmount may throw on double-unmount; swallow for idempotency.
|
// Vue's unmount may throw on double-unmount; swallow for idempotency.
|
||||||
}
|
}
|
||||||
|
// Dispose the animation scheduler after Vue unmount: each useAnimation's
|
||||||
|
// onScopeDispose has already unsubscribed, so this is an idempotent backstop.
|
||||||
|
mountedAnimationScheduler?.dispose();
|
||||||
|
mountedAnimationScheduler = null;
|
||||||
if (mountedKittyController) {
|
if (mountedKittyController) {
|
||||||
mountedKittyController.dispose();
|
mountedKittyController.dispose();
|
||||||
mountedKittyController = null;
|
mountedKittyController = null;
|
||||||
@@ -615,6 +622,9 @@ export function createApp(root: Component, rootProps?: RootProps | null): TuiApp
|
|||||||
baseApp.provide(AppContextKey, appContext);
|
baseApp.provide(AppContextKey, appContext);
|
||||||
baseApp.provide(FocusContextKey, focusContext);
|
baseApp.provide(FocusContextKey, focusContext);
|
||||||
baseApp.provide(StdinContextKey, stdinController);
|
baseApp.provide(StdinContextKey, stdinController);
|
||||||
|
const animationScheduler = createAnimationScheduler();
|
||||||
|
mountedAnimationScheduler = animationScheduler;
|
||||||
|
baseApp.provide(AnimationSchedulerKey, animationScheduler);
|
||||||
if (typeof __VUE_TUI_DEV__ !== "undefined" && __VUE_TUI_DEV__) {
|
if (typeof __VUE_TUI_DEV__ !== "undefined" && __VUE_TUI_DEV__) {
|
||||||
baseApp.provide(DevStateKey, devState);
|
baseApp.provide(DevStateKey, devState);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user