Skip to content

Simulator runtime controls design

Context

The simulator page currently lets developers paste mapHex, pathHex, and roomProperties and preview the rendered map. It does not expose the SDK runtime layer, so developers cannot validate visibility toggles, room selection, interaction flags, or measurement settings without editing code.

This design adds a dedicated runtime control experience to the simulator while keeping the map preview large and the UI maintainable.

Goals

  • Cover every field in RuntimeConfig.
  • Make runtime changes apply in real time through mapApi.updateRuntime().
  • Represent field dependencies explicitly instead of exposing a flat form.
  • Prefer direct manipulation when the map already provides the right affordance.
  • Keep unsupported runtime fields visible but clearly disabled.

Non-goals

  • Do not add full editing workflows for forbidden zones, carpets, furniture, waypoints, or spots in this iteration.
  • Do not add a raw JSON editor as the primary runtime editing surface.
  • Do not persist runtime state across page reloads in this iteration.

Option 1: flat runtime form

Render every runtime field in a single long form with basic controls.

  • Pros: fastest to build.
  • Cons: poor dependency handling, weak discoverability, scales badly.

Option 2: runtime as a separate tab

Add a Runtime tab next to Map, Path, and Room.

  • Pros: clear separation from source data.
  • Cons: weak link between runtime controls and live map interaction.

Keep source data input and runtime controls separate. Add a dedicated Runtime panel in the left control column, and keep the right column focused on the large map preview.

  • Pros: clear mental model, strong map-control linkage, scales well as more runtime fields and future config panels are added.
  • Cons: more initial design and state management work.

This design uses option 3.

Page information architecture

The simulator stays in a two-column layout.

  • Left column:
    • Data panel for Map, Path, and Room
    • Runtime panel for all runtime controls
    • Inspector panel for runtime snapshot and live state
  • Right column:
    • large map preview
    • light runtime summary overlay

The runtime panel is not merged into the existing source-data tabs. Source data answers "what is rendered"; runtime answers "how it behaves right now."

Runtime group design

Group runtime fields by behavior instead of by raw type.

Visibility

This group contains direct visibility toggles and uses a compact switch matrix.

  • showPath
  • showRobot
  • showChargingStation
  • showRoomName
  • showRoomType
  • showRoomProperty
  • showRoomOrder
  • showRoomFloorType
  • showCarpet
  • showDetectedObjects
  • showChargingStationRing
  • showRobotRing
  • showRobotSleepAnimation
  • showRobotPulseCircle

Room selection

This is the highest-value interaction group and gets a dedicated sub-panel.

  • enableRoomSelection
  • roomSelectionMode
  • selectRoomIds
  • roomPropertyFoldIds
  • dividingRoomId

Key behavior:

  • When enableRoomSelection is false, dependent controls remain visible but disabled with a clear reason.
  • selectRoomIds supports two synchronized input channels:
    • room checklist in the panel
    • direct room clicking on the map
  • In checkmark mode, the panel uses a checkbox list.
  • In order mode, the panel shows ordered selected rooms and preserves order in selectRoomIds.
  • dividingRoomId uses a room dropdown, not a free number field.
  • roomPropertyFoldIds uses room multi-select, not raw array input.

Interaction

  • enableInteraction
  • enableMapClickCapture

Key behavior:

  • enableInteraction is the parent switch.
  • When enableInteraction is false, enableMapClickCapture is disabled and automatically normalized to false.
  • Captured click coordinates appear in the inspector as a read-only result.

Geometry and measurement

  • mapRotation
  • unit
  • unitLabel

Key behavior:

  • mapRotation uses a slider plus numeric input.
  • unit uses a segmented control or select.
  • unitLabel follows the default unit mapping until the user customizes it.

Editing state

  • editingForbiddenSweepZoneIds
  • editingForbiddenMopZoneIds
  • editingCleanZoneIds
  • editingVirtualWallIds
  • editingSpotIds
  • editingWayPointIds
  • editingCarpetIds
  • editingFurnitureIds
  • selectedCarpetIds

This group is visible but collapsed by default. Fields are disabled when the simulator lacks the supporting dataset or editing workflow.

Human-friendly behaviors

The runtime console needs a few usability features so it feels like a real debug surface rather than a schema viewer.

  • Keep a light "modified" indicator when runtime differs from defaults.
  • Provide safe presets such as Default, Selection Debug, Minimal, and Labels Off.
  • Show the current runtime snapshot as formatted JSON for copy-and-compare workflows.
  • Show why a control is disabled, not only that it is disabled.
  • Derive room labels from parsed map rooms and prefer roomProperties names when available.

State model

Split state into three layers.

Source data state

Mutable source inputs:

  • mapHex
  • pathHex
  • roomProperties

This layer keeps its current render-and-cache flow.

Derived map state

Read-only values produced from parsed data and current map support:

  • availableRooms
  • parsedMapData
  • parsedPathData
  • mapType
  • runtimeSupportMatrix
  • capturedMapClick

Runtime state

Mutable runtime state managed separately from source data:

  • runtimeDraft
  • optional runtimeApplied snapshot for diagnostics

Runtime changes call updateRuntime(partial) and do not re-run map decoding.

Normalization rules

Runtime state must stay valid as source data changes.

  • Keep selectRoomIds when enableRoomSelection is off, but disable the UI.
  • Force enableMapClickCapture to false when enableInteraction is false.
  • Reset dividingRoomId to -1 if the room no longer exists.
  • Filter invalid room IDs from selectRoomIds and roomPropertyFoldIds.
  • Preserve selection order in order mode.
  • Keep custom unitLabel if the user has overridden it.

Error handling

Runtime updates use light feedback instead of full render errors.

  • If updateRuntime() fails, show a runtime-level error status and keep the last applied state.
  • If normalization removes invalid values, show a small informational status describing the change.
  • Unsupported fields stay visible and disabled rather than hidden.

Component boundaries

Add runtime support without re-centralizing the simulator into one file.

  • MapPlayground.vue: layout orchestration only
  • useMapPlayground.ts: page-level state aggregation
  • useRuntimePlayground.ts: runtime draft, dependencies, presets, snapshot
  • useRuntimeBindings.ts: bridge between UI actions, map callbacks, and mapApi.updateRuntime()
  • SimulatorRuntimePanel.vue: runtime console shell
  • SimulatorRoomSelectionPanel.vue: dedicated room-selection UI
  • SimulatorInspectorPanel.vue: runtime JSON, selected rooms, click capture

Verification

Validate the design with the following outcomes.

  • Every RuntimeConfig field appears in the runtime console.
  • Runtime changes update the map through updateRuntime() without full redraw.
  • Room selection stays synchronized between panel and map.
  • Invalid room-linked values are normalized after source data changes.
  • Unsupported fields are visible, disabled, and labeled with the reason.
  • The map preview remains visually dominant on desktop and mobile layouts.

Next steps

Write an implementation plan that phases the runtime console into composables and components without destabilizing the existing simulator page.

最后更新于: