Agent Skillslichtblick-suite/lichtblick › player-internals

player-internals

GitHub

详解IterablePlayer状态机、Tick循环及数据源迭代架构。涵盖状态转换逻辑、带预算控制的播放循环、防抖状态发射机制,以及序列化/反序列化数据源的包装与缓存层级结构。

.github/skills/player-internals/SKILL.md lichtblick-suite/lichtblick

Trigger Scenarios

询问播放器内部状态机逻辑 分析播放性能或Tick实现 排查数据源迭代与缓存问题

Install

npx skills add lichtblick-suite/lichtblick --skill player-internals -g -y
More Options

Non-standard path

npx skills add https://github.com/lichtblick-suite/lichtblick/tree/develop/.github/skills/player-internals -g -y

Use without installing

npx skills use lichtblick-suite/lichtblick@player-internals

指定 Agent (Claude Code)

npx skills add lichtblick-suite/lichtblick --skill player-internals -a claude-code -g -y

安装 repo 全部 skill

npx skills add lichtblick-suite/lichtblick --all -g -y

预览 repo 内 skill

npx skills add lichtblick-suite/lichtblick --list

SKILL.md

Frontmatter
{
    "name": "player-internals",
    "description": "Deep implementation details of the IterablePlayer state machine, tick loop, and data source iteration patterns."
}

Player Internals Skill

State Machine Detail

preinit ──► initialize ──► start-play ──► idle
                                           │  ▲
                                           ▼  │
                                          play
                                           │
                                           ▼
                                    seek-backfill ──► idle

idle/play ──► reset-playback-iterator ──► idle/play (re-enters)
any ──► close

State Transitions

  • preinit → initialize: triggered the first time playback starts after construction (source supplied via constructor).
  • initialize → start-play: Source initialize() resolved, topics/schemas available
  • start-play → idle: Initial backfill complete, first state emitted
  • idle → play: User presses play or setPlaybackSpeed(speed > 0)
  • play → idle: Reached end of data or user pauses
  • play → seek-backfill: User seeks during playback
  • idle → seek-backfill: User seeks while paused
  • seek-backfill → idle: Backfill messages found, state emitted

Tick Loop Implementation

// Simplified tick loop logic
async #statePlay() {
  const tickStart = performance.now();
  const budgetMs = 300; // Max time per tick before yielding to UI

  while (performance.now() - tickStart < budgetMs) {
    const result = await this.#iterator.next();
    if (result.done) { return "idle"; }

    this.#pendingMessages.push(result.value.msgEvent);

    // Check if we've passed the target wall-clock time
    if (this.#hasReachedPlaybackTarget()) { break; }
  }

  this.#emitState();
  return "play"; // continue playing next tick
}

Debounced State Emission

  • #emitStateImpl() is scheduled via queueMicrotask to coalesce rapid updates
  • State includes: activeData (messages, currentTime, topics), progress (caching status)
  • Only emits if state actually changed (reference equality check on key fields)

Iterator Architecture

There is no concrete DataSource type in this layering. Sources implement one of two interfaces: ISerializedIterableSource (yields raw bytes) or IDeserializedIterableSource (yields decoded MessageEvents). A serialized source must be wrapped by DeserializingIterableSource; an already-deserialized source skips that wrapper.

Concrete source (e.g. McapIndexedIterableSource, RemoteFileReadable-backed, WebSocket, …)
    │  implements ISerializedIterableSource  OR  IDeserializedIterableSource
    ▼
DeserializingIterableSource (ONLY for serialized sources — applies parseChannel-based decode)
    │  packages/suite-base/src/players/IterablePlayer/DeserializingIterableSource.ts
    ▼
CachingIterableSource (LRU block cache, ~600MB budget)
    │
    ▼
BufferedIterableSource (producer-consumer, read-ahead, default { sec: 10 })
    │
    ▼
IterablePlayer (tick loop consumes messages)

⚠️ DeserializingIterableSource is optional — it is only inserted when the underlying source is serialized (ISerializedIterableSource). Sources that already return IDeserializedIterableSource bypass it.

Backfill Strategy

When seeking to time T:

  1. For each subscribed topic, find the last message at or before T
  2. Uses reverse iteration in indexed sources (MCAP) for efficiency
  3. These messages become the "latched" state — panels see them immediately
  4. Critical for panels that display "latest value" (e.g., 3D transforms, image)

Subscription Management

  • Subscriptions are set by panels via MessagePipeline.setSubscriptions()
  • Player diffs new vs old subscriptions to avoid unnecessary re-iteration
  • Topic preloading is separate from active subscriptions (handled by BlockLoader)
  • reset-playback-iterator state: when subscriptions change mid-play, iterator must restart from current time

Performance Critical Paths

  1. Tick loop budget: 300ms cap prevents UI freeze during catch-up
  2. Message accumulation: Messages are batched per tick, not emitted individually
  3. Iterator yielding: await in the loop allows microtask scheduling
  4. Worker sources: Heavy parsing happens in WorkerIterableSource off main thread
  5. Seek optimization: Indexed MCAP enables O(log n) seek via chunk indexes

Version History

  • cab9317 Current 2026-07-24 12:17

Same Skill Collection

.github/skills/3d-rendering/SKILL.md
.github/skills/caching-internals/SKILL.md
.github/skills/deserialization/SKILL.md
.github/skills/e2e-playwright-mcp/SKILL.md
.github/skills/electron-internals/SKILL.md
.github/skills/extensions-internals/SKILL.md
.github/skills/layouts-internals/SKILL.md
.github/skills/mcap-format/SKILL.md
.github/skills/message-path/SKILL.md
.github/skills/message-pipeline/SKILL.md
.github/skills/panel-extension-api/SKILL.md
.github/skills/panel-image/SKILL.md
.github/skills/panel-log/SKILL.md
.github/skills/panel-map/SKILL.md
.github/skills/panel-raw-messages/SKILL.md
.github/skills/panel-state-transitions/SKILL.md
.github/skills/panel-user-scripts/SKILL.md
.github/skills/performance/SKILL.md
.github/skills/plot-internals/SKILL.md
.github/skills/remote-caching/SKILL.md
.github/skills/test-conventions/SKILL.md
.github/skills/theme/SKILL.md
.github/skills/unit-testing/SKILL.md
.github/skills/web-workers/SKILL.md
.github/skills/websocket-connection/SKILL.md

Metadata

Files
0
Version
cab9317
Hash
95ae47ed
Indexed
2026-07-24 12:17

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-09 06:30
浙ICP备14020137号-1 $Carte des visiteurs$