This commit is contained in:
2026-09-15 01:12:50 +08:00
parent 2db889ad89
commit 1a75503105
99 changed files with 4168 additions and 726 deletions
@@ -88,26 +88,35 @@
<h1 id="the-program-branch">The Program Branch</h1>
<p>What the run actually read, line by line, as opposed to what the mission asked for.</p>
<p>The Execution page's Control Tree carries two branches: <strong>Mission</strong> above, <strong>Program</strong> below, at
Control-Tree path <code>execution/program</code>. Program is read-only — every node on it is either a file the
mission points at or a pass a run made over one — and the transport bar stays pinned above its
panels, so a run can be started, stepped and reset without leaving the branch.</p>
<p>The Execution page's Control Tree carries two roots: <strong>Mission</strong> above, <strong>Program</strong> below, at
Control-Tree path <code>execution/program</code>. Program is read-only — its nodes are what the session played
or produced: the files the mission points at, the files the run reached from them, the inline text
of the NC Code commands, one node per distinct title, and the writeback files converted from a
played file — and the transport sits in the run header at the top of the Control Tree pane, with
the run-state badge at its right end, so a run can be started, stepped and reset without leaving
the branch.</p>
<h2 id="before-anything-runs">Before anything runs</h2>
<p>The branch is not empty before a run. The service seeds it from the mission: one node per distinct
NC file a <strong>Program File</strong> command names, and one per <strong>NC Code</strong> command, taken in the order the
mission lists them and reaching into nested groups. Those nodes are placeholders — a file the run
has not opened yet — and the branch panel says so, badging itself <em>not run yet</em> beside the file
count.</p>
<p>Three things decide what is seeded, and each of them is visible in the screenshot below:</p>
<p>The branch is not empty before a run. The service seeds it from the mission: first one node per
distinct file an enabled <strong>Program File</strong> command names — NC, CL or CSV alike, since the seed reads
the command's path and not its kind — in the order the mission lists them and reaching into nested
<strong>List</strong> commands, then one node per distinct title among the enabled
<strong>NC Code</strong> commands — so an NC Code command listed above a Program File still seeds below every
file node. Those nodes are placeholders — a file the run has not opened yet — and the branch panel
says so, badging itself <em>not run yet</em> beside the file count.</p>
<p>Three things decide what is seeded:</p>
<ul>
<li><strong>A disabled command seeds nothing.</strong> The mission's greyed <em>Program File</em> entry names an NC file
that never reaches the branch, and nothing beneath a disabled group reaches it either.</li>
<li><strong>A disabled command seeds nothing.</strong> The mission's greyed <em>Program File</em> entry names a file
that never reaches the branch, and nothing beneath a disabled List reaches it either.</li>
<li><strong>Two commands naming one file seed one node.</strong> Paths are compared with case and slash direction
ignored, so a file played twice appears once.</li>
ignored, so a file played twice appears once. In the screenshot below the first <code>circle.ptp</code>
command sits inside the collapsed <strong>List [Roughing]</strong> and the second is the top-level
<strong>Program File</strong> row, so the branch shows one plain <code>circle.ptp</code>; the <code>×2</code> it takes once both
commands have played is in the next section.</li>
<li><strong>An NC Code command is seeded under its own title</strong>, not under a file name, because it has no
file — its text lives in the mission. The branch marks it <code>(inline)</code>.</li>
file — its text lives in the mission. The branch marks it <code>(inline)</code>, and two NC Code commands
with the same title share one node.</li>
</ul>
<p><img src="the-program-branch-img/program-before-run.en.png" alt="The Execution page before a run: the Control Tree shows the Mission branch with nine commands — two of them greyed out and unticked — over the Program branch, whose five nodes are circle.ptp, drill_slot.ptp, side.ptp, slide.ptp and (inline) Inline finishing pass. The branch panel below the transport bar is badged not run yet beside 5 files, and the four Session Messages tabs are empty"></p>
<p><img src="the-program-branch-img/program-before-run.en.png" alt="The Execution page before a run: the run header at the top of the Control Tree pane shows the six transport buttons and a green ready badge at its right end; under it the Mission root row, with a + at its right edge, lists nine command rows, each with a checkbox and a drag handle, two of them greyed out and unticked, and the two List rows carry their own +; the Program root below is selected and holds five nodes — circle.ptp, drill_slot.ptp, side.ptp, slide.ptp and (inline) Inline finishing pass; the Program panel in the editor row under the tree is badged not run yet beside 5 files with a round refresh button at the row's right end, above the hint to run the mission; the 3D canvas shows an uncut block, and the four Session Messages tabs carry no badge"></p>
<p><em>The Program branch at <code>/execution?tree=execution/program</code>, on a project that has not been played.
The disabled <code>Program File</code> entry in Mission has no node under Program; the enabled <code>NC Code</code>
command has one, under its title.</em></p>
@@ -116,25 +125,37 @@ command has one, under its title.</em></p>
not name — a subprogram call nests its callee under the caller. The panel's badge changes from
<em>not run yet</em> to <em>run data</em>, and a file the run made more than one pass over takes a <code>×</code> and a
count in its tree label.</p>
<p><img src="the-program-branch-img/program-after-run.en.png" alt="The same page after the run has finished: the Execution root badge reads finished, the first Program node now reads circle.ptp ×2, the branch panel is badged run data beside 5 files, and the Session Messages tabs carry counts — Shell 11 and NC Diagnostics 7, with Step Diagnostics and NC Manipulation still unbadged"></p>
<p><img src="the-program-branch-img/program-after-run.en.png" alt="The same page after the run has finished: the badge at the right end of the run header reads finished, the Mission rows are unchanged, the first Program node reads circle.ptp ×2, the Program panel under the tree is badged run data beside 5 files with the refresh button at the row's right end, the 3D canvas shows the cut block with a gold cutter and green tool paths above it, and the Session Messages tabs carry counts — Shell 11 and NC Diagnostics 7, with Step Diagnostics and NC Manipulation still unbadged — over a list of System messages"></p>
<p><em>The same deep link once the run has finished. <code>circle.ptp ×2</code> is one node holding two passes,
because two Program File commands named the same file.</em></p>
<div class="IMPORTANT">
<h5>Important</h5>
<p>The branch is rebuilt when the run <strong>changes state</strong> — starting, finishing, being reset — and not
while it is playing. During a long run the nodes on screen are the ones the last transition left
there, so a file the run has since opened may not be listed yet. Pausing brings it up to date.</p>
<p>The branch is rebuilt when the run <strong>changes state</strong> — starting, pausing, finishing, being reset —
and not while it is playing. During a long run the nodes on screen are the ones the last
transition left there, so a file the run has since opened may not be listed yet. The round
refresh button at the far right end of the Program panel's badge row — across the row from the
<em>run data</em> badge and the file count, its tooltip <em>Re-read the file tree from the current
session</em> — rebuilds the branch on the spot without touching the transport; pausing rebuilds it
too, since a pause is a state change.</p>
</div>
<h2 id="reading-one-file">Reading one file</h2>
<p>Selecting a node opens the file as the run saw it: the path it was read from, a selector for the
passes made over it, and the text with what each line produced beside it.</p>
<p><img src="the-program-branch-img/program-file-passes.en.png" alt="The Program branch with circle.ptp ×2 selected: the breadcrumb reads Execution / Program / circle.ptp ×2, the path caption NC/circle.ptp, a pass selector reading Pass (2) and #2 · re-entry beside a Follow toggle, then twenty-one numbered lines of NC with a step range printed to the right of thirteen of them, and a footer reading 21 lines · 21 executed lines"></p>
<p><img src="the-program-branch-img/program-file-passes.en.png" alt="The Program branch with circle.ptp ×2 selected and the canvas and right-hand columns switched off, so the Control Tree pane spans the window: the menu bar carries a red disconnected chip beside the four layout toggles, the run header's green finished badge sits at the far right, the Mission root row is collapsed with a + at its right edge, the Program root beneath it is open and holds five nodes — circle.ptp ×2 highlighted in blue, drill_slot.ptp, side.ptp, slide.ptp and (inline) Inline finishing pass — and the editor row's header reads Program / circle.ptp ×2; inside it the path caption NC/circle.ptp, a pass selector reading Pass (2) and #2 · re-entry beside a Follow toggle, then twenty-one numbered lines of NC with a step range printed to the right of ten of them, a footer reading 21 lines · 21 executed lines, and the window footer reading Ready"></p>
<p><em>One file node at <code>/execution?tree=execution/program/0</code>, with the canvas column switched off so the
line viewer has the width. The pass selector names the pass and why it was entered.</em></p>
line viewer has the width — which is why the menu-bar chip reads <strong>disconnected</strong>: the badge folds the
page's rendering connection in with its service connections, and with the canvas column off the page
holds no rendering connection (see <a href="../basics/the-app-window.html">The Application Window</a>).
The pass selector names the pass and why it was entered.</em></p>
<ul>
<li><strong>The pass selector</strong> carries one entry per pass, labelled with how that pass was entered — the
first arrival at the top of the file, a re-entry when the mission came back to it, or the call
that reached it from another file.</li>
<li><strong>The pass selector</strong> carries one entry per pass, labelled with how that pass was entered. A
pass that an <code>M98</code>/<code>M198</code> subprogram call started carries the call word and its <code>P</code> number —
<code>M98 P8</code> — on every pass, so a subprogram the caller repeats with an <code>L</code> count or calls a second
time reads <code>×N</code> with each pass labelled by the call, never as a re-entry. A pass with no call
behind it reads <em>top</em> on the first arrival at that path and <em>re-entry</em> on every later pass over
it — whether a second Program File command named the file again or a <code>WHILE</code> or <code>GOTO</code> inside a
single play of it started a new pass. So a file the mission names once can still read <code>×N</code>, with
every pass after the first labelled re-entry.</li>
<li><strong>The step range</strong> beside a line is what that line produced. A line with no range beside it ran
and produced no motion: <code>G</code> and <code>M</code> words that set state, and the tape marks, all execute without
cutting anything.</li>
@@ -146,13 +167,17 @@ was put.</li>
</ul>
<h2 id="what-the-branch-does-not-hold">What the branch does not hold</h2>
<ul>
<li><strong>The writeback files are not inside the file nodes.</strong> Converting a played program back to NC
makes its own node at the top of the branch, beside the file nodes rather than under them, and
clicking a line on either side jumps to its twin on the other. That conversion is the CL-to-NC
writeback, so a mission that plays brand NC produces none, and the branch shows only source files.</li>
<li><strong>Node addresses are positions, not files.</strong> A node is <code>execution/program</code> followed by its index,
so a deep link into the branch survives only as long as the branch has the same shape. Link to the
branch, not into it.</li>
<li><strong>The writeback files are not inside the file nodes.</strong> With <strong>Post-Execution › CL → NC
Writeback</strong> enabled, the mission re-serializes every file the session played — NC plays as well
as CL plays — and each converted file makes its own node, labelled <code>→</code> and the output file's
name, at the top level of the branch, after the file nodes rather than under them; the Program
panel counts them beside the file count, and clicking a line on either side jumps to its twin on
the other. With that section disabled the branch shows only source files.</li>
<li><strong>Node addresses are positions, not files.</strong> A node is <code>execution/program</code> followed by an index
at each level of nesting — <code>execution/program/0</code> for a top-level file, <code>execution/program/0/0</code>
for a subprogram nested under it — and a writeback node takes <code>dst-</code> and its own index in place
of a file index, <code>execution/program/dst-0</code>. So a deep link into the branch survives only as long
as the branch has the same shape. Link to the branch, not into it.</li>
<li><strong>A skipped line is not only recorded here.</strong> A line suppressed by block skip is also announced in
the <strong>NC Diagnostics</strong> list while the run is playing — see
<a href="when-something-goes-wrong.html">When Something Goes Wrong</a>.</li>