Table of Contents

Execution Page

The Execution page is the run cockpit: the simulation plays here, and every panel on it reads the run. It is the app's landing route — / redirects to /execution — and its Control Tree — two roots, Mission above Program — rides the ?tree= query, so /execution?tree=execution/mission deep-links the Mission editor.

Note

The app says Execution throughout: the route /execution, the REST endpoints (/api/Execution/*), the status hub (/executionStatusHub) and the stored layout (UserConfig.ExecutionDivConfig). The HiAPI engine keeps its own library vocabulary — PlayerCommand (API) and PacePlayer (API) — which is a different codebase's naming, not an inconsistency here.

Key Models

  • LocalProjectService — the project data service the whole page reads.
  • MachiningProject — reached through the displayee bound to the canvas.
  • UserService — per-user configuration, including the stored panel layout.

Layout

Four columns, left to right. The two dock dividers are pixel-sized, so dragging one moves only that dock's edge while the flexible middle absorbs the change.

  • Left dock — the Control Tree over the primary editor panel for the selected tree node. The tree pane opens with a run header pinned above its rows: the Execution Tool Bar — the transport buttons — with the live status badge to its right. The editor panel below holds the editor alone.
  • Main — the RenderingCanvas over the Session Message Panel, stacked as collapsible panels with a draggable divider between them. The canvas panel's header adopts the RenderingCanvas Tool Bar and the Execution Extended RenderingCanvas Tool Bar.
  • Strip Charts — the strip-chart group bar over the three Strip Charts: Availability Chart, Surface Roughness Chart and Color Index Time Chart.
  • Step Info — Sentence Syntax as its own region (an NC sentence need not map to any machining step, so it is not a member of the step-based panels), then the Step Info group bar, then Step Properties, CWE (cutter–workpiece engagement) and the four Cycle-Line Charts.

The four columns are toggled from the app menu bar; the panels inside them collapse in place from their own expansion headers. The canvas stays mounted while collapsed so its rendering connection survives, and its engine is paused rather than torn down. The page itself also stays mounted while the user is on another route: the shell wraps the router view in a keep-alive keyed on the project epoch, so navigating away pauses the canvas but keeps the page — and its connection — alive until the loaded project changes.

Control Tree

The page hosts an execution-scoped Control Tree with two roots and no wrapper node over them: the Mission branch above the Program branch. Node ids keep the execution/ prefix (execution/mission, execution/program/…) because that first segment is the page-scope key — ?tree= routing and the remembered last selection hang off it — not a parent row; a bare ?tree=execution resolves to execution/mission, and a URL with no ?tree= lands on the remembered selection or, failing that, on Mission. Selecting a node fills the primary editor pane below the tree; that pane holds nothing but the selected node's editor.

Run header. The tree pane opens, on this page only, with a row pinned above the tree scroller: the Execution Tool Bar — the page's sole transport, which therefore owns the F5–F8 shortcuts — and, to its right, the status badge fed by /executionStatusHub. It sits inside the pane rather than on the dock's expansion header because that header is shared with General Setup, which renders neither piece. The button strip is the only shrinkable child, so narrowing the tree column scrolls the buttons away while the badge stays in view; the dock keeps the tree row mounted while collapsed, so the transport and its shortcuts survive a collapsed row. The other controls the cockpit needs live where they act — the panel switches on each panel's own expansion header, the column switches on the app menu bar.

Mission (execution/mission) is the editable command list a run executes — the project's PlayerCommand (API), always a list, with nested lists read as sub-trees. Its ItemType registry supplies the tree checkbox that decides whether a command runs. Every row-level structural op lives on the tree rows, not in a panel: each command row carries a drag handle and — revealed on hover and on the selected row — move up / move down / duplicate / delete; every list row, the Mission root included, carries an always-visible + (Add Command) that opens the command catalog and inserts the pick right after that list's focused command (the last selected or last added), else at the list's tail. The one panel-side insert is the Program File editor's multi-pick fan-out: each extra pick becomes a new Program File command right after that command in its own list, and the panel reports the insert range to the host, which treats it as a structural op like any row op — the same busy gate, the same carry-over of index-based ids onto the new siblings, the same rebuild scoped to the owning list. Dropping a dragged row on another command row's edge reorders it within its list or relocates it into the target row's list; dropping on a List row's middle band or on the Mission root row appends it into that list. The host runs all five ops through one path — a busy gate that holds tree selection, the checkboxes and further drags read-only while an op is in flight; the open editor's dirty-switch gate, which can refuse the op: a Script Command with unsaved edits asks Save & switch / Discard / Cancel, while an NC Code editor or a List title sends its pending save without asking, and either one answers no when the user cancels or the save does not land — a refused gate drops the op and toasts that the open editor keeps its unsaved edits, which is why a delete that was already confirmed can still leave its row in place; then the API call, a rebuild scoped to the list it rewrote (the nearest list above both, for a move across lists), then the selection. The selection moves only when it already rode on the acted-on row — that row, or a section or nested entry under it: it follows a moved command, lands on the clone of a duplicated one, and after a delete lands on the nearest surviving entry of that list or, once the list is empty, on the owning list row; a selection riding elsewhere stays on its own re-indexed row, and Add Command never moves it at all — only the Add focus moves, onto the new row, so a run of adds chains in order. The root's own panel is informational — what the tree cannot say: a no-project note while no project is loaded, otherwise the command count and, while it is zero, a prompt to click Add Command; the run-order hint closes it either way. A command node's panel is that kind's own editor (a List shows only its optional Title; its entries are its tree children), and each of the kind's remaining setting groups becomes a section child of the command node. Every command type has its own page under Mission.

Program (execution/program) is the read-only inspection twin of Mission: one node per NC source file the session read, its passes and execution marks filled in from run data rather than typed in. Its nodes, its per-pass line and mark views, and the status changes that rebuild it are on Program Branch.

Selection and URL are synced two ways through the tree query argument: the URL's ?tree= is adopted once the tree is built, and every selection change replaces it. A ?tree= id belonging to another page's tree redirects to that page (routeForTreeId), and /mission lands on /execution?tree=execution/mission.

RenderingCanvas Behavior

The canvas is split across the two sides: the browser component owns a canvas element and its connection, the server owns the displayee.

  1. The browser component opens a SignalR connection to /renderingHub and streams frames. It holds no displayee of its own.
  2. POST /api/Execution/initialize/{connectionId} resolves that connection's engine on the server, binds ProjectDisplayeeService.ExecutionDisplayee to the engine's DispEngine.Displayee unless one is already bound there, and snaps the camera to the home view through SetViewToHomeView().
  3. The displayee receives project data from LocalProjectService.
  4. The connection is per rendering session, so a collapsed canvas keeps its connection and only stops drawing; the engine is paused while the panel is collapsed or the page is off-screen.

Isometric is one of the view presets the user picks from the RenderingCanvas Tool Bar — alongside front, back, right, left, top and bottom — not the load-time view.

Source Code Path

See HiNC App Anatomy for git repository links.

HiNC-2025-webservice (Quasar CLI SPA):

Page, routing and Control Tree:

  • wwwroot-src/src/pages/ExecutionPage.vue — the routed page at /execution: the four columns, their pixel / ratio splitters, the panel-expansion stacks, and the execution-scoped Control Tree host it provides.
  • wwwroot-src/src/router/routes.ts — the / → execution redirect, the execution route, and the /mission redirect to /execution?tree=execution/mission.
  • wwwroot-src/src/router/treeRoutes.ts — migrateLegacyTreeId, which folds legacy ids onto the current ones (a bare execution becomes execution/mission), and routeForTreeId, which runs that migration first and then lands a ?tree= id on the page that owns its first segment.
  • wwwroot-src/src/components/controlTree/useControlTreeHost.ts — the Control Tree state machine: buildExecutionRoots() builds the two roots, execution/mission above execution/program; landingSelection() picks the remembered selection or the first root; the ?tree= sync; the Program branch re-read on every broadcast execution-status change; and the five mission row ops — add, drag move, step, duplicate, delete — through one missionRowOp helper that owns the busy gate, the dirty-switch gate (a refusal drops the op and toasts it), the scoped rebuild and the post-op selection.
  • wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts — the HTML5 drag-and-drop bookkeeping between Mission rows: the edge / into drop modes and the row indicator classes; the move itself is the host's.
  • wwwroot-src/src/components/controlTree/ControlTreeDock.vue — the left dock: the Control Tree row over the primary editor row, each kept mounted while collapsed; the tree row's expansion header is the same on both tree pages, so nothing run-specific rides it.
  • wwwroot-src/src/components/controlTree/ControlTreePanel.vue — the tree pane; on the Execution page it pins the run header — the Execution Tool Bar and the live status badge — above the tree scroller, and renders the Mission rows' drag handle, the hover-revealed row ops and the Add Command + on every list row.
  • wwwroot-src/src/components/controlTree/AddCommandDialog.vue — the search-first command catalog the + opens, fed by GET /api/Mission/command-catalog; one pick per opening.
  • wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue — the primary editor pane shared by both tree pages: it mounts the selected node's registry panel, or one of the three inline root panels it carries for General Setup's equipment roots (Machine Tool, Fixture, Workpiece — object management plus a summary), which no Execution node ever selects; here it shows the registry panel alone, and hands that panel's dirty-switch gate to the host.

Mission branch:

  • wwwroot-src/src/components/controlTree/missionItemTypes.ts — the branch's ItemType registry and the per-command enable ticks.
  • wwwroot-src/src/components/controlTree/MissionRootPanel.vue — the Mission root's informational panel: a no-project note while no project is loaded, otherwise the command count and a “No commands yet” prompt while it is zero, and the run-order hint in every state.
  • wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue — the per-command editor host; a List command shows only its optional Title.
  • wwwroot-src/src/components/controlTree/MissionSectionPanel.vue — one setting section of a command.

Program branch (see the dedicated anatomy page for details):

  • Program Branch — the branch's ItemType registry, its root, file and conversion panels, and the read-only endpoints behind them.

Panels and canvas:

  • wwwroot-src/src/components/RenderingCanvas.vue — the browser canvas and its /renderingHub connection.
  • wwwroot-src/src/components/execution/ExecutionToolBar.vue — the transport controls; the page's one instance, mounted in the tree pane's run header, registers F5–F8.
  • wwwroot-src/src/components/execution/ExecutionExtendedToolBar.vue — the view and rendering-flag controls adopted onto the canvas panel's header.
  • wwwroot-src/src/components/execution/SelectedStepInfoPanel.vue — Step Properties.
  • wwwroot-src/src/components/execution/StepVolumePanel.vue — the CWE panel.
  • wwwroot-src/src/components/execution/SyntaxPiecePanel.vue — Sentence Syntax.
  • wwwroot-src/src/components/execution/SessionMessagePanel.vue — the message panel and its four sink tabs.
  • wwwroot-src/src/components/panels/PanelExpansion.vue and wwwroot-src/src/components/panels/ResizablePanelStack.vue — the collapse-in-place panels and their draggable heights.
  • wwwroot-src/src/layouts/MainLayout.vue — the shell whose keep-alive wrapper, keyed on the project epoch, holds this page mounted across navigation.

Charts (see the dedicated anatomy pages for details):

Shared chart primitives under wwwroot-src/src/components/execution/charts/:

  • wwwroot-src/src/components/execution/charts/UplotChart.vue — thin uplot wrapper with ResizeObserver and reactive data / series / bands bindings.
  • wwwroot-src/src/components/execution/charts/BaseStripChart.vue — strip-chart skeleton: min / max banded series, header aspect picker, wheel / drag / click pointer handlers.
  • wwwroot-src/src/components/execution/charts/BaseCycleLineChart.vue — cycle-line skeleton that takes a fetcher prop and re-fetches when the step selection changes.

Backends:

  • Execution/ExecutionController.cs — POST /api/Execution/start | pause | resume | run-line | run-step | stop | reset; GET status, status/{connectionId}, project-status, selected-step-info and cl-strip-dots; the canvas actions initialize/{connectionId} (binds the displayee and calls SetViewToHomeView) and fit-view/{connectionId}; and the step-volume/{connectionId} family behind the CWE panel.
  • Execution/ExecutionStatusHub.cs + Execution/ExecutionStatusService.cs — /executionStatusHub, the run-state broadcast that drives the transport and the run header's badge.
  • Execution/SessionSinkHub.cs + Execution/SessionSinkBroadcastService.cs — one hub per message sink (/shellMessageHub, /ncDiagnosticHub, /stepDiagnosticHub, /ncManipulationDiagnosticHub), so a client subscribes to exactly the sink it wants.
  • Execution/SelectedStepInfoService.cs — the selected-step payload. It has no hub of its own: the “selection changed” push rides /clStripHub.
  • Execution/ClStripController.cs + Execution/ClStripHub.cs + Execution/ClStripBroadcastService.cs — CL-strip range state and the zoom / pan / select / enter broadcasts.
  • Execution/ExecutionChartsController.cs — the strip-chart and cycle-line-chart data endpoints under /api/execution.
  • Disp/RenderingHub.cs + Disp/RenderingService.cs — the shared /renderingHub every page's RenderingCanvas connects to, keyed per rendering connection id.
  • Disp/ExecutionDisplayee.cs — the server-side displayee bound to the connection's engine.
  • Common/ProjectDisplayeeService.cs — owns the ExecutionDisplayee instance handed to the engine on initialize.

Building an Equivalent Page

Tip

When building an execution cockpit on top of HiAPI:

  1. Create the layout with a RenderingCanvas.
  2. Set up the canvas behavior.
  3. Add the Execution Tool Bar.
  4. Add the Execution Extended RenderingCanvas Tool Bar with the CL-strip, fit-view and rendering-items behaviors.
  5. Reach the page from the navigation menu on Main Panel.
  6. Make it the landing page, with its tool bars.
  7. Build the Session Message Panel and the Selected-Step Info Panel, and put the button that opens the Step Present Dialog on the latter's title bar.

Pages

Ordered as the cockpit reads: the two tool bars — the transport pinned in the Control Tree pane's run header, the extended controls on the canvas panel's header — then the step column and the charts down the side, the menus and dialogs they open, then the two Control-Tree branches the page hosts.

See Also