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/shell/session-message-panel.html
T
2026-09-09 17:35:23 +08:00

221 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Session Message Panel | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Session Message Panel | 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-SessionMessagePanel">
<h1 id="session-message-panel">Session Message Panel</h1>
<p>Session messages are partitioned by kind into four sinks on <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> (obtained via dependency injection):</p>
<ul>
<li><a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ShellProgress">ShellProgress</a> — session-level routine / lifecycle messages (<a class="xref" href="../../api/Hi.MachiningProcs.ShellProgress.html">ShellProgress</a>). Session-scoped: the property is null outside <code>BeginSession</code>/<code>EndSession</code>.</li>
<li><a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_NcDiagnosticProgress">NcDiagnosticProgress</a> — play-time NC-pipeline diagnostics (<a class="xref" href="../../api/Hi.NcParsers.NcDiagnosticProgress.html">NcDiagnosticProgress</a>), anchored to the NC source block that raised them wherever the diagnostic has one.</li>
<li><a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_StepDiagnosticProgress">StepDiagnosticProgress</a> — diagnostics anchored to a motion step (<a class="xref" href="../../api/Hi.MachiningProcs.StepDiagnosticProgress.html">StepDiagnosticProgress</a>).</li>
<li><a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_NcManipulationDiagnosticProgress">NcManipulationDiagnosticProgress</a> — NC-manipulation diagnostics: a second <a class="xref" href="../../api/Hi.NcParsers.NcDiagnosticProgress.html">NcDiagnosticProgress</a>, written by <a class="xref" href="../../api/Hi.MachiningProcs.MachiningSession.html#Hi_MachiningProcs_MachiningSession_ConvertClToNcFiles_">ConvertClToNcFiles</a> and <a class="xref" href="../../api/Hi.MachiningProcs.MachiningSession.html#Hi_MachiningProcs_MachiningSession_OptimizeNcFiles_">OptimizeNcFiles</a>, held apart from the play-time sink so writeback findings never mix into the play pipeline's.</li>
</ul>
<p>The panel surfaces each sink in its own tab, so one tab holds one message kind. <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ResetRuntime_">ResetRuntime</a> — which a project change runs — empties the first three, so each of them holds the current project only; the manipulation sink is outside that sweep, cleared only at the start of the conversion or optimization run that fills it, and its rows therefore survive a project change.</p>
<h2 id="layout">Layout</h2>
<ul>
<li>Tab Bar (each tab carries a floating count badge, drawn only while its sink holds messages)
<ul>
<li>Shell Tab</li>
<li>NC Diagnostics Tab</li>
<li>Step Diagnostics Tab</li>
<li>NC Manipulation Tab</li>
</ul>
</li>
<li>Per-Tab Content
<ul>
<li>Filter Toolbar
<ul>
<li><code>Severity</code> Filter Dropdown</li>
<li><code>Category</code> Filter Dropdown</li>
<li>Message Text Filter Input</li>
<li><code>Reset</code> Button (this tab's three filters, nothing else)</li>
<li><code>Export</code> Button</li>
<li>Matched / Total Badge (also the tab's hub connection indicator)</li>
</ul>
</li>
<li>Message Table</li>
</ul>
</li>
</ul>
<h2 id="message-table-per-tab">Message Table (per tab)</h2>
<p>Each tab renders its sink's message list — <a class="xref" href="../../api/Hi.MachiningProcs.ShellProgress.html#Hi_MachiningProcs_ShellProgress_Messages">Messages</a>, <a class="xref" href="../../api/Hi.MachiningProcs.StepDiagnosticProgress.html#Hi_MachiningProcs_StepDiagnosticProgress_Messages">Messages</a>, or <a class="xref" href="../../api/Hi.NcParsers.NcDiagnosticProgress.html#Hi_NcParsers_NcDiagnosticProgress_Diagnostics">Diagnostics</a> for the two NC-diagnostic sinks — as rows of:</p>
<ul>
<li><code>Severity</code> (colour-coded via <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetSeverity">GetSeverity()</a>)</li>
<li><code>Anchor</code> — the kind-specific position: none for shell messages, the NC sentence ordinal (<code>Sn &lt;n&gt;</code>) for both the play-time and the manipulation NC diagnostics, and the motion step with its sentence ordinal (<code>S&lt;step&gt; · Sn &lt;n&gt;</code>) for step diagnostics; an NC diagnostic raised at pipeline level rather than at a source block carries none</li>
<li><code>Message</code> — <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetCategory">GetCategory()</a>, <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetId">GetId()</a> and <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetNotification">GetNotification()</a></li>
</ul>
<p>Only take the last filtered elements (e.g. 500–1000) for user experience. Find the usage example in the code:</p>
<pre><code class="lang-csharp" name="Demo_UseSessionMessageHost">internal static void DemoUseSessionMessageHost(LocalProjectService localProjectService)
{
// Session messages are partitioned by kind into three sinks on LocalProjectService:
// - ShellProgress: session-level routine / lifecycle messages
// (session-scoped: null outside BeginSession/EndSession).
// - NcDiagnosticProgress: NC-pipeline diagnostics, anchored to the NC source sentence.
// - StepDiagnosticProgress: diagnostics anchored to a motion step.
ShellProgress shellProgress = localProjectService.ShellProgress;
List&lt;IMessage&gt; shellMessages = shellProgress == null
? new List&lt;IMessage&gt;() : shellProgress.Messages.ToList();
foreach (IMessage message in shellMessages)
Console.WriteLine(
$&quot;Shell [{message.GetSeverity()}] {message.GetId()}: {message.GetNotification()}&quot;);
foreach (NcDiagnostic diagnostic in
localProjectService.NcDiagnosticProgress.Diagnostics.ToList())
{
var ncLine = diagnostic.SentenceCarrier?.GetSentence()?.FirstIndexedFileLine;
Console.WriteLine(
$&quot;NC [{diagnostic.GetSeverity()}] {diagnostic.GetId()}: {diagnostic.GetNotification()}; &quot; +
$&quot;File: {ncLine?.FilePath}; LineNo: {ncLine?.GetLineNo()}; NC: {ncLine?.Line}&quot;);
}
foreach (StepDiagnostic diagnostic in
localProjectService.StepDiagnosticProgress.Messages.ToList())
Console.WriteLine(
$&quot;Step {diagnostic.StepIndex} [{diagnostic.GetSeverity()}] &quot; +
$&quot;{diagnostic.GetId()}: {diagnostic.GetNotification()}&quot;);
File.WriteAllLines(&quot;output-session-messages.txt&quot;,
shellMessages.Select(m =&gt;
$&quot;[{m.GetSeverity()}] {m.GetId()}: {m.GetNotification()}&quot;));
}
</code></pre>
<p>Add the update-table event per sink: <a class="xref" href="../../api/Hi.MachiningProcs.StepDiagnosticProgress.html#Hi_MachiningProcs_StepDiagnosticProgress_MessageAdded">MessageAdded</a> / <a class="xref" href="../../api/Hi.NcParsers.NcDiagnosticProgress.html#Hi_NcParsers_NcDiagnosticProgress_MessageAdded">MessageAdded</a>, and for the session-scoped shell sink the app-lifetime bridge <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_OnShellMessageAdded">OnShellMessageAdded</a> (with the matching <code>Cleared</code> events). The updating process has to be called by <a class="xref" href="../conventions/index.html">Loose Manner</a> for user experience.</p>
<div class="TIP">
<h5>Tip</h5>
<p>On window desktop application (WPF), consider use textarea instead of datagrid to MessageTable for better performance. Use padding to show the different columns. And use the font in the textarea that with consistent width.</p>
</div>
<div class="NOTE">
<h5>Note</h5>
<p>The message display should be real-time.</p>
</div>
<h2 id="behavior-of-export-button">Behavior of Export Button</h2>
<p>Every tab has its own <code>Export</code>, and it carries that tab's sink alone. It writes the rows the tab is holding — the recent window pulled from that sink, narrowed by that tab's severity, category and text filters — as a CSV of <code>Index,Count,Severity,Category,Id,Anchor,Notification,Detail</code>, named after the sink it came from. It is disabled while the filters match nothing.</p>
<h2 id="signalr-implementation-webapi-only">SignalR Implementation (Webapi Only)</h2>
<p>One hub per sink — <code>/shellMessageHub</code>, <code>/ncDiagnosticHub</code>, <code>/stepDiagnosticHub</code>, <code>/ncManipulationDiagnosticHub</code> — each with a <code>GetMessages(int limit)</code> pull returning <code>MessagesUpdate { messages, totalCount }</code>. A per-sink broadcast service subscribes its sink's <code>MessageAdded</code>/<code>Cleared</code> and raises a coalesced <code>MessagesChanged</code> notification via <a class="xref" href="../../api/Hi.Common.LooseRunner.html">LooseRunner</a>; the client re-pulls the recent window on each notification (loss-free regardless of how many appends coalesced). The client components connect to the hubs they display to receive real-time updates.</p>
<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>
<ul>
<li>wwwroot-src/src/components/execution/SessionMessagePanel.vue (tabbed panel)</li>
<li>wwwroot-src/src/components/execution/SessionMessageTab.vue + MessageRow.vue (per-tab list)</li>
<li>wwwroot-src/src/composables/useSessionSinkHub.ts (the four hub composables)</li>
<li>Execution/SessionSinkHub.cs (the SignalR hub base; one hub per sink)</li>
<li>Execution/SessionSinkBroadcastService.cs + ShellMessageBroadcastService.cs, NcDiagnosticBroadcastService.cs, StepDiagnosticBroadcastService.cs, NcManipulationDiagnosticBroadcastService.cs (subscribe-and-rebroadcast)</li>
<li>Execution/SessionSinkDtos.cs (typed DTOs)</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../execution/index.html">Execution Page</a> — the page whose main column hosts this panel</li>
<li><a class="xref" href="bottom-message-bar.html">Bottom Message Bar</a> — the app-level notification bar, as distinct from these session sinks</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>