This repository has been archived on 2026-10-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
HiNC-2025-win-desktop-Deploy/App/wwwroot/HiAPI-docsite/anatomy/execution/program.html
T
2026-09-15 01:12:50 +08:00

407 lines
26 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Program Branch | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Program Branch | HiAPI-C# 2025 ">
<link rel="icon" href="../../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../../public/docfx.min.css">
<link rel="stylesheet" href="../../public/main.css">
<meta name="docfx:navrel" content="../../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../../index.html">
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Anatomy-ProgramBranch">
<h1 id="program-branch">Program Branch</h1>
<p>Program is the lower of the two roots of the Execution page's Control Tree, Mission being the upper:
route <code>/execution</code>, Control-Tree path <code>execution/program</code>, one node per NC source file the session
read. It is a
read-only view of a run — the file's text, the passes that went over it, the per-line marks the run
left behind, and the writeback files the run wrote — assembled from session data rather than from
anything typed into it. Its node ids are positional, so an id addresses a node without surviving the
branch growing around it.</p>
<h2 id="program-against-mission">Program Against Mission</h2>
<p>Mission is what a run executes; Program is what the run read. That one difference sets the rest of
the branch:</p>
<ul>
<li>Mission's nodes edit the project. Program's item types declare a panel — and, on the root and the
file node, a child builder — and nothing else: no enable checkbox (the tree hides the tick on
every node that is not a Mission command or an enable-bearing Mission section), none of the row
affordances a Mission row carries (no drag handle, no add, delete, move or duplicate button), and
no counterpart to Mission's one panel-side structural edit, the multi-pick insert of the
<a class="xref" href="mission/NcFileCommand-panel.html">Program File editor</a>.</li>
<li>Mission's shape is authored. Program's shape is a consequence: a subprogram file appears on it
only because a run followed a call into it.</li>
<li>Mission belongs to the project. Program's contents belong to the session — the index behind it is
fed piece by piece as the run executes, and it is dropped when the session ends or the project
changes.</li>
</ul>
<p>Before anything runs the branch is not empty. The server seeds it by walking the mission root-first
through its nested lists — skipping a disabled entry along with everything beneath it — and taking
the NC file of every <strong>Program File</strong> command and the title of every <strong>NC Code</strong> command. It seeds
one placeholder per <em>distinct string</em>, not one per command: both loops append only where no root
already carries that string under the same case-insensitive, slash-normalised comparison the sibling
merge uses, and they share one namespace, so a Program File path and an NC Code title that normalise
alike collapse into one node. A Program File command whose path is still unset is skipped and seeds
nothing. A placeholder carries no invocations, so its panel shows the file's text with no marks and
an empty, disabled pass selector.</p>
<p>The branch carries no transport of its own either. The <a href="execution-tool-bar.html">Execution Tool Bar</a>
sits in the Control Tree pane's run header — above the tree scroller, beside the execution-status
badge, on the Execution page only — so a run can be started, stepped and reset while a program file
is on screen, and the editor pane below the tree shows nothing but the selected node's panel.</p>
<h2 id="the-nodes-the-branch-mints">The Nodes the Branch Mints</h2>
<p>Three item types, each keyed by position rather than by identity.</p>
<p><strong>The branch root</strong> (<code>execution/program</code>) carries the summary panel and the child builder that
fetches everything.</p>
<p><strong>A file node</strong> is one source file as reached through one call edge. The server groups executed
sentences by the file index stamped on them, resolves each invocation's caller from the call-stack
record on the executed piece, and nests the callee's node under the caller's; the same subprogram
called from two different files therefore appears once under each. Sibling nodes merge on a
case-insensitive, slash-normalised path comparison, so repeated passes over one file under one
caller collapse into a single node holding several invocations. Placeholders are appended after the
nodes a run produced, and one whose path a run node already holds is skipped rather than doubled —
that skip is also what keeps an inline command to one node, because the run stamps the command's
title as the path of every piece it plays, so the placeholder and the run node carry the same
string. A later pass flags every root whose path matches an enabled NC Code command's title as
inline; that flag drives three presentational choices — the label prefix, the panel's inline caption
and which missing-text wording it shows — and one behavioural one: the root's child builder matches
a node against the writeback conversions only when the node is not inline, so an inline root is
never stamped with a conversion, never gains the forward links to a converted file, and cannot be
the target a conversion's <em>converted from</em> header jumps back to. The tree label is the path's base
name, prefixed <code>(inline)</code> for an inline node and suffixed with a multiplication sign and a count
when the node holds more than one invocation.</p>
<p><strong>A conversion node</strong> is one NC writeback conversion held by the session, labelled with an arrow and
the written file's base name. Conversion nodes are appended after all file nodes.</p>
<p>A file node's id is its parent's id plus its index among that parent's children
(<code>execution/program/0</code>, <code>execution/program/0/1</code>); a conversion node's is the branch root's id plus
<code>dst-</code> and the conversion's position in the session's list. Both are positional, and the tree those
indices count into grows as a run discovers files, so a <code>?tree=</code> link into this branch names a
position and not a file.</p>
<p>The whole branch costs two requests. The root's child builder takes the file tree in one response
and the conversion list in another, stashes each file's raw subtree on the node it mints, and the
file nodes' builder only maps what is already there — no node fetches for itself. A failed
file-tree request yields an empty branch rather than an error; a failed conversion request leaves
the file tree standing without cross-links.</p>
<h2 id="invocations">Invocations</h2>
<p>An invocation is one pass over one file, keyed on the file index the run stamps onto every executed
sentence. A fresh index is allocated for each top-level play of a file and for every subprogram
call, call repetition and loop or jump re-segmentation, so a file entered or looped over more than
once contributes one invocation per pass, and the file panel's pass selector is exactly a pick among
them. Each entry reads as a hash-prefixed ordinal and a trigger, and the trigger is derived from the
piece that opened the pass:</p>
<ul>
<li>the call term with its P word — <code>M98 P8</code>, <code>M198 P8</code> — when the piece carries a Fanuc
subprogram-call record. Only that record is read, so a pass opened by a Siemens or Heidenhain
call, or by a Fanuc macro call, falls through to the two cases below;</li>
<li><code>re-entry</code> when this session has already seen a pass over the same path;</li>
<li><code>top</code> otherwise.</li>
</ul>
<p>The selector opens on the last invocation in the node's list — the pass that started most recently —
and re-defaults whenever a rebuild leaves the current selection absent from the list. It is disabled
while the node has none, and it takes typed text as a filter over the entries. Everything below it
belongs to the selected pass alone: switching passes drops the mark and link caches and refetches
both for every page of text already loaded, not only for the pages on screen. The footer counts the
file's lines and, for the selected pass, the number of distinct source lines that executed in it.</p>
<h2 id="what-a-run-marks">What a Run Marks</h2>
<p>The line viewer is virtualized. Text arrives in 1000-line pages covering the visible window plus two
pages either side; the server caps one request at 2000 lines and keeps a small most-recently-used
cache of whole files keyed on path and last-write time, so paging through a long program does not
re-read it once per page. A path with no file on disk is answered as non-existent, the miss is
cached so scrolling does not re-fire it, and the panel captions the file as missing — or, for an
inline node, as inline text that is no longer available, because an NC Code command's text is served
from the mission command itself and goes when the command is removed or retitled. A disk file wins
over a command title that shadows it.</p>
<p>Marks are fetched the same way and per selected pass. A line the pass executed carries the sentence
index it ran and the range of machining steps that sentence produced; a line absent from the answer
did not execute in that pass and is greyed — but only once the node holds at least one invocation,
so a placeholder's text renders plain rather than uniformly grey. A line whose sentence produced
steps carries a step badge, single-valued or a range.</p>
<p>Marks grow as a run advances, so a page cached early would keep later lines looking unexecuted. The
panel drops its mark cache and re-fetches the visible window on every throttled CL-strip update
broadcast.</p>
<p>Clicking a line points the shared sentence cursor at that source position, which is what fills the
Step Info column's <strong>Sentence Syntax</strong> panel; when the line's sentence produced steps, the click
also selects that sentence's first step, moving the charts and the 3D strip with it. A line with no
steps — a <code>G54</code>, a comment, a line that never ran — moves the cursor alone. Hovering a line sends
the same anchor as the entered step on a 50 ms leading-edge throttle, and leaving the viewer clears
it.</p>
<p>The traffic runs the other way too. A step picked on a chart or the 3D strip resolves to a source
anchor and lands on the cursor; a file panel whose path matches switches to the pass that step
belongs to and scrolls the line into view. The <strong>Follow</strong> toggle beside the pass selector is the
live variant: while it is on, the panel scrolls to whatever line the execution-status hub's cursor
reports for this file. It is off by default, it belongs to the mounted panel rather than to stored
preferences, and it does not change the selected pass.</p>
<h2 id="writeback-conversions">Writeback Conversions</h2>
<p>The session retains the destination piece streams and source-to-destination maps of its latest
CL-to-NC writeback run — <a class="xref" href="../../api/Hi.MachiningProcs.MachiningSession.html#Hi_MachiningProcs_MachiningSession_NcConversions">NcConversions</a><small>(API)</small>,
refilled by <a class="xref" href="../../api/Hi.MachiningProcs.MachiningSession.html#Hi_MachiningProcs_MachiningSession_ConvertClToNcFiles_">ConvertClToNcFiles</a><small>(API)</small>. This
branch only displays them; the writeback itself is switched on by the mission's <strong>Post-Execution</strong>
command, in its <strong>CL → NC Writeback</strong> section. Because the conversions live on the session, they go
when it does.</p>
<p>A conversion node shows the written file's lines, each line whose piece has a registered source
carrying a back-arrow badge naming that source line. The panel's header names this conversion's
source file; the link on that name lands on the file's node when a root file node matched the
conversion's source path, and otherwise falls back to the first entry of the branch's file-index
map, so a conversion whose source was reached only as a nested or inline node can name one file and
open another. Clicking a badge selects the source node, switches it to the invocation the piece came
from, and scrolls to the line; clicking anywhere else on a row only highlights it.
The viewer has no missing-file caption of its own, so a written file no longer on disk renders as an
empty viewer.</p>
<p>The reverse direction is carried by the file panel. A root file node whose path matches a
conversion's source path gets forward-arrow badges naming the destination line, with a count when
one source line produced several destination lines, and clicking one selects the conversion node and
scrolls to the first of them. That matching is done on root nodes only, and never on an inline node,
so a subprogram file reached through a call carries no forward badges of its own even though a
backward jump can land on it and switch its pass.</p>
<p>The jump itself rides one shared slot, because only one editor panel is mounted at a time: the
requesting panel parks the target line and emits a selection, and the twin takes the parked jump
when it mounts — or through a watcher, when it was already the selected panel. A target consumed
before the first page of text resolves is parked again and re-applied once the line array is sized.</p>
<h2 id="when-the-branch-is-rebuilt">When the Branch Is Rebuilt</h2>
<ul>
<li><strong>Page initialization.</strong> Building the Execution page's two roots builds the branch, and only when
a project is loaded; without one the root stands with no children.</li>
<li><strong>Any change in the broadcast execution status.</strong> The status the hub reports is one of
<code>NoProject</code>, <code>Ready</code>, <code>Running</code>, <code>Paused</code> and <code>Finished</code>, and the host re-reads the branch
whenever that value changes. It deliberately does not take the structural-change path used
elsewhere in the tree, because that path force-expands the node it rebuilds and a run would then
keep re-opening a branch the reader had closed. The panels pick up <strong>part</strong> of the change from
the replaced nodes: the path caption, the pass selector, the inline wording and the executed-line
count are all derived from the node, but the file text is not — it is fetched once per page on
mount and on scroll, with no watcher on the path, and the panel is not remounted because its key
— the node id, the node key and the mission stamp — reduces on a Program node to the id alone,
the other two parts being empty, and the id is positional and therefore unchanged. A rebuild that
puts a different file at the same index leaves the previous file's text on screen under the new
node's caption and marks.</li>
<li><strong>The refresh button on the root panel.</strong> This one does take the structural-change path: it
re-reads the file tree from the current session and expands the branch.</li>
</ul>
<p>A reset is the emptying event: it ends the session and clears the index, so the next read of the
branch returns the mission's placeholders and nothing else.</p>
<h2 id="layout">Layout</h2>
<ul>
<li>Program Node
<ul>
<li>Intro Caption</li>
<li>Status Row
<ul>
<li>Run-State Badge — reads <code>run data</code> when any of the branch root's direct file children holds at
least one invocation and <code>not run yet</code> otherwise; like the count beside it, it looks one level
deep and never at nested subprogram nodes. It is computed from the nodes, not from the
file-tree response's own run-data flag.</li>
<li>File Count Caption — the branch root's direct file children only; nested subprogram nodes are
not counted.</li>
<li>Converted File Count Caption — shown only when the session holds conversions.</li>
<li>Refresh Button</li>
</ul>
</li>
<li>Not-Run Hint — shown while the badge reads <code>not run yet</code>.</li>
<li>Conversions Hint — shown only when the session holds conversions.</li>
</ul>
</li>
<li>Program File Node
<ul>
<li>Path Caption — the path as the run stamped it; an inline node appends an inline-NC-code tag.</li>
<li>Pass Select</li>
<li>Follow Toggle</li>
<li>Not-Run Hint — shown while the node has no invocations.</li>
<li>Missing-Source Caption — the disk-file wording or the inline-text wording.</li>
<li>Line Viewer
<ul>
<li>Line Number</li>
<li>Line Text</li>
<li>Step Badge</li>
<li>Converted-Line Badge</li>
</ul>
</li>
<li>Count Footer — line count, plus the selected pass's executed-line count.</li>
</ul>
</li>
<li>Converted File Node
<ul>
<li>Path Caption</li>
<li>Converted-From Line — the source file's name, linked to its node when a root file node matched.</li>
<li>Line Viewer
<ul>
<li>Line Number</li>
<li>Line Text</li>
<li>Source-Line Badge</li>
</ul>
</li>
<li>Count Footer — line count and converted-piece count.</li>
</ul>
</li>
</ul>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<li><code>wwwroot-src/src/components/controlTree/programItemTypes.ts</code> — the branch's three item types, the
node ids, the labels, the conversion stamping, and the two-request child builder.</li>
<li><code>wwwroot-src/src/components/controlTree/ProgramRootPanel.vue</code> — the branch root: intro, run-state
badge, file and conversion counts, hints and the refresh button.</li>
<li><code>wwwroot-src/src/components/controlTree/ProgramFilePanel.vue</code> — one source file: the pass
selector, the Follow toggle, the paged line viewer, the execution marks, the step and
converted-line badges, and the cursor and hover wiring.</li>
<li><code>wwwroot-src/src/components/controlTree/ProgramConversionFilePanel.vue</code> — one written file: the
paged line viewer and the source-line links back into the file panel.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — declares the branch root as the
Execution page's second root, below Mission, re-reads it on every execution-status change without
expanding it, and hides the tick on every node that is not a Mission command or an enable-bearing
Mission section.</li>
<li><code>wwwroot-src/src/components/controlTree/itemTypes.ts</code> — the node shape carrying the program
bookkeeping, the merged item-type registry, and the eager subtree builder.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane that renders the
branch's nodes, binds the tree's strict tick strategy, and pins the run header — the transport bar
and the execution-status badge — above the tree on the Execution page.</li>
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — mounts the selected node's panel
under a key built from the node id, the node key and the mission stamp — the last two empty on
every Program node — and forwards its selection request to the host.</li>
<li><code>wwwroot-src/src/api/ncProgram.ts</code> — the typed client for the file tree, the paged lines, the line
marks, the syntax piece, the sentence-to-step mapping and both directions of conversion links.</li>
<li><code>wwwroot-src/src/api/clStrip.ts</code> — the step-select and step-enter posts a line click and a line
hover make.</li>
<li><code>wwwroot-src/src/composables/useConversionJump.ts</code> — the single parked-jump slot the two viewers
hand a target through.</li>
<li><code>wwwroot-src/src/composables/useSentenceCursor.ts</code> — the shared source position, written by a line
click and by the resolved step selection.</li>
<li><code>wwwroot-src/src/composables/useClStripHub.ts</code> — the throttled run-advance counter that
invalidates the visible marks.</li>
<li><code>wwwroot-src/src/composables/useExecutionStatusHub.ts</code> — the status the branch rebuild watches and
the running cursor the Follow toggle scrolls to.</li>
<li><code>wwwroot-src/src/components/execution/SyntaxPiecePanel.vue</code> — the Step Info column's Sentence
Syntax panel, the other reader of the shared cursor.</li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the branch's labels, hints, badges and pluralised counts.</li>
<li><code>Execution/NcProgramController.cs</code> — the read-only endpoints: the file tree, the paged file lines
with their inline-command fallback and whole-file cache, the line marks, the syntax piece, the
sentence and step lookups, the conversion list and both directions of conversion links.</li>
<li><code>Execution/NcProgramRegistryService.cs</code> — the session-scoped index: the event feed, the invocation
records with their trigger and caller resolution, the file-tree snapshot with its mission
placeholders, the per-line marks, and the clear on reset or project change.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/MachiningProcs/LocalProjectService.cs</code> — the app-lifetime bridge that forwards each executed
piece and each built machining step, and the reset that ends the session.</li>
<li><code>HiMech/MachiningProcs/MachiningSession.cs</code> — the retained conversions and the CL-to-NC writeback
run that refills them.</li>
<li><code>HiMech/NcParsers/NcWriteback/NcConversion.cs</code> — one conversion: the destination piece stream, its
written path and the source-to-destination map the cross-links walk.</li>
<li><code>HiMech/NcParsers/Syntaxs/SyntaxPiece.cs</code> — the executed unit the index is keyed on, and the
source line stamped on its sentence.</li>
<li><code>HiNc/SessionCommands/NcFileCommand.cs</code> — the Program File command whose path seeds a placeholder.</li>
<li><code>HiNc/SessionCommands/NcCodeCommand.cs</code> — the NC Code command whose title is the pseudo-path of an
inline node and whose text is that node's only source.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="mission/mission-root-panel.html">Mission Root Panel</a> — the editable twin: the command list this branch reports on. Its
Add Command, drag, move, duplicate and delete ops live on the Control Tree rows and act on
commands of any kind; the root's own panel is informational — a no-project note when no project
is loaded, otherwise the command count with an Add Command prompt while that count is zero, and
the run-order hint in either case</li>
<li><a class="xref" href="index.html">Execution Page</a> — the page that hosts both branches, and the transport, canvas and charts
the branch's selections drive</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>