Table of Contents

Class LocalProjectService

Namespace
Hi.MachiningProcs
Assembly
HiNc.dll

Root(Local) project service. Apply absolute file path.

public class LocalProjectService : IProjectService, IMachiningProjectGetter, IMachiningService, IGetMachiningEquipment, IStepPropertyAccessHost, IDisposable
Inheritance
LocalProjectService
Implements
Inherited Members
Extension Methods

Remarks

LocalProjectService handles the runtime data and cache generally not requires configuration IO. Compare to MachiningProject, LocalProjectService also handles events that does not reset on the MachiningProject been reloaded.

Constructors

LocalProjectService(ILogger<LocalProjectService>)

Ctor.

public LocalProjectService(ILogger<LocalProjectService> logger = null)

Parameters

logger ILogger<LocalProjectService>

Optional logger instance.

Fields

DefaultNcResultsDirectory

The default results directory, the parent of DefaultRelDirectoryTemplate.

public const string DefaultNcResultsDirectory = "Output/results"

Field Value

string

Properties

ActiveNcRunner

Gets the active NC runner based on EnableSoftNcRunner.

public INcRunner ActiveNcRunner { get; }

Property Value

INcRunner

BaseDirectory

Gets the project base directory (relative-path root).

public string BaseDirectory { get; }

Property Value

string

BoundSelectorHost

Gets the bound selector host for managing selection boundaries.

public BoundSelectorHost BoundSelectorHost { get; }

Property Value

BoundSelectorHost

ClRunner

Gets the NX-CL (CLSF) runner of the project (NxClRunner); null when there is no project.

public INcRunner ClRunner { get; }

Property Value

INcRunner

ClStrip

Gets the cutter location strip containing the machining steps.

public ClStrip ClStrip { get; }

Property Value

ClStrip

CsvRunner

Gets the CSV runner — the CSV suit's pipeline (GeneralCsvRunner); null when there is no project.

public INcRunner CsvRunner { get; }

Property Value

INcRunner

DictionaryColorGuide

Gets the color guide for dictionary-based coloring.

public DictionaryColorGuide DictionaryColorGuide { get; }

Property Value

DictionaryColorGuide

DiffVisualRadius_mm

Gets or sets the diff colour-scale radius (mm): a project setting held on the authored workpiece (DiffVisualRadius_mm, saved with the project) and mirrored onto the runtime face and the live colour rule (DiffVisualRadius_mm), so a write recolours the current overlay at once with no re-materialise. Finite and positive (ArgumentOutOfRangeException otherwise). Saving the project stays the caller's, like every other setup edit.

public double DiffVisualRadius_mm { get; set; }

Property Value

double

EnableErrorTerms

Gets or sets whether the machine runs with its error terms — the project switch EnableErrorTerms. On (the default), the runtime face carries the transformer authored on every branch marked as an error term (IsErrorTerm), so the machine moves, cuts and collides with its errors. Off, each of those branches carries a NoTransform on the runtime face (the mark stays on the branch) and the machine runs as its nominal chain. The authored face keeps its transformers and its marks either way. The kinematics solver (XyzabcSolver) takes the error terms out by itself whatever the switch says, so the machine coordinates solved for a program do not depend on it: the switch decides only whether the errors are left on the part.

The getter answers true while no project, or no runner config, is loaded; the setter does nothing then, nor when the value does not change. A write is a setup edit (NotifySetupEquipmentEdited(IProgress<IMessage>)): the runtime face is rebuilt at once when no session is alive, otherwise at the next session boundary, and IsSetupEquipmentDirty is true meanwhile. Saving the project stays the caller's, like every other setup edit.

public bool EnableErrorTerms { get; set; }

Property Value

bool

EnablePauseOnFailure

Gets or sets whether to pause execution on failure.

public bool EnablePauseOnFailure { get; set; }

Property Value

bool

EnableSoftNcRunner

Switches between SoftNcRunner and the legacy HardNcRunner. Default true (2026-07-17): SoftNcRunner is the flagship NC pipeline; set false to fall back to HardNcRunner for the features that still depend on it (e.g. Hi.NcOpt.NcOptProc optimization reads NcLines). Will be removed when HardNcRunner is fully replaced.

public bool EnableSoftNcRunner { get; set; }

Property Value

bool

EnableStrokeLimitCheck

Gets or sets whether stroke limit checking is enabled.

public bool EnableStrokeLimitCheck { get; set; }

Property Value

bool

Fixture

Gets or sets the authored fixture (setup face). The runtime face follows by rebuild; runtime readers use MachiningEquipment.Fixture. With a session alive, the fixture the runtime face holds is taken at the session's next boundary, as one written on the runtime face.

public Fixture Fixture { get; set; }

Property Value

Fixture

Global

global variable for SessionShell. Not save on XML.

public Dictionary<object, object> Global { get; set; }

Property Value

Dictionary<object, object>

HasUnreadableSoftNcRunner

Whether the active suit's runner is an unresolved reference: it names a side file (SoftNcRunnerFile) that could not be read at load, so SoftNcRunner is null.

public bool HasUnreadableSoftNcRunner { get; }

Property Value

bool

InspectingKey

Gets or sets the current inspecting key for visualization. When set, updates the inspecting quantity function.

public string InspectingKey { get; set; }

Property Value

string

InspectingQuantityFunc

Gets the function that retrieves the quantity value for the current inspecting key: the step's inspecting slot (TryGetInspectingValue(int, out double)), which the host fills as the step is built and on every move of InspectingSlotGeneration; null while the slot is stale, and null when no key is inspected.

public Func<MachiningStep, double?> InspectingQuantityFunc { get; }

Property Value

Func<MachiningStep, double?>

InspectingSlotGeneration

The generation the inspecting slots are valid under: a step's slot stamped with another one is stale (TryGetInspectingValue(int, out double)). Moves when InspectingKey changes, TimeMapping is set, the step registry changes (StepPropertiesGeneration; not for an edit of a color tree's names and hues alone, TryUpdateStepColorTreeAppearance(string, StepColorTree), whose slots hold the same leaf ids) or a session begins; every move schedules a scan that fills every step on the strip and raises InspectingSlotsScanned.

public int InspectingSlotGeneration { get; }

Property Value

int

InspectingSlotScanFillHookForTests

Internal Use Only, for tests: called by the inspecting-slot scan for every step it fills, after the step's value is computed and before it is written to the slot — the window a fact widens to land a run's close inside it; the second argument is true for the walk's probe read of a step (the two probe steps are read once more in their segment's own pass). Null costs nothing; the step-built hook, the recompute's refill and the fold's refills do not call it.

public Action<MachiningStep, bool> InspectingSlotScanFillHookForTests { get; set; }

Property Value

Action<MachiningStep, bool>

IsCollisionDetectionEnabled

Gets whether collision detection is currently enabled.

public bool IsCollisionDetectionEnabled { get; }

Property Value

bool

IsNcResultRecording

Whether a recording section is open: a BeginNcResultRecording(string) not yet ended.

public bool IsNcResultRecording { get; }

Property Value

bool

IsSetupAngleEstimationArmed

True while an arm is watching the step stream (its window not yet complete).

public bool IsSetupAngleEstimationArmed { get; }

Property Value

bool

IsSetupEquipmentDirty

True while the authored face carries an edit the runtime face has not followed yet: set by NotifySetupEquipmentEdited(IProgress<IMessage>), cleared by the materialise that follows — at once with no session, otherwise at the next session boundary. A host shows it, so a user who edited the setup while a session is alive (anything played since the last reset) knows the runtime scene lags until a reset. A field written in place on the workpiece's material or cutting parameter needs no follow: the runtime face holds the authored objects themselves, so the run takes the new value with no notice and no rebuild (see NotifySetupEquipmentEdited(IProgress<IMessage>)).

public bool IsSetupEquipmentDirty { get; }

Property Value

bool

LastInspectingSlotScanStoreReads

Internal Use Only. The store reads the last completed slot scan made on its thread: the probes, then one read a segment when a probe read the store, or one a step whose getter reads it although the probes did not.

public int LastInspectingSlotScanStoreReads { get; }

Property Value

int

LastMillingParaTrainResult

Snapshot of the most recent TrainMillingPara(SampleFlag, bool, double, string, CancellationToken, ICuttingPara, IProgress<IMessage>) / ReTrainMillingPara(SampleFlag, double, string, CancellationToken, IProgress<IMessage>) outcome — sampleFlags, correlation R, filtered sample count, output file and the built parameter's XML — so a caller (e.g. the webservice) can read the training result without re-opening the output .mp file. Service lifetime, last-wins; null until the first training call completes. Deliberately not cleared by ResetRuntime(IProgress<IMessage>) so the result stays readable after a post-run reset.

public MillingParaTrainResult LastMillingParaTrainResult { get; }

Property Value

MillingParaTrainResult

LastNcResultCompletion

Internal Use Only. How the last completed file ended (the section's end, a runtime reset's); null before any. For the tests.

public NcResultCompletion LastNcResultCompletion { get; }

Property Value

NcResultCompletion

LastSetupAngleEstimates

Snapshot of the most recent EstimateSetupAngle(SampleFlag, double, string, CancellationToken, IProgress<IMessage>, ICuttingPara, IReadOnlySet<int>) outcome — one estimate per tool the mapped data covered. Project lifetime, last-wins: null until the first estimation completes, and null again when another project is opened (the tool ids name that project's tools). Like LastMillingParaTrainResult it survives ResetRuntime(IProgress<IMessage>).

public List<SetupAngleEstimate> LastSetupAngleEstimates { get; }

Property Value

List<SetupAngleEstimate>

LastSetupAngleOnlineResult

The most recent online estimation's outcome (armed or explicit), from the moment it starts; project lifetime, last-wins, null until the first and again when another project is opened. Survives ResetRuntime(IProgress<IMessage>) like LastSetupAngleEstimates.

public SetupAngleOnlineResult LastSetupAngleOnlineResult { get; }

Property Value

SetupAngleOnlineResult

LastSetupAngleReports

LastSetupAngleEstimates flattened for transport — one SetupAngleReport per estimate, with the inputs of the call that made it (the parameter name, the channels, the outlier ratio), which the estimate itself does not carry. Set together with the estimates, same lifetime (and cleared with them when another project is opened); what a web API reads and a GUI shows, whether or not a report file was asked for.

public List<SetupAngleReport> LastSetupAngleReports { get; }

Property Value

List<SetupAngleReport>

LastStepsRevisedRefill

Internal Use Only. The wall-clock of the last refill of revised steps, the recolor included.

public TimeSpan LastStepsRevisedRefill { get; }

Property Value

TimeSpan

LastStepsRevisedRefillSteps

Internal Use Only. The steps the last refill of revised steps covered (end - begin).

public int LastStepsRevisedRefillSteps { get; }

Property Value

int

LastStepsRevisedRefillStoreReads

Internal Use Only. The step-cache reads the last refill of revised steps (OnStepsRevised(int, int)) made on its thread: 0 while the inspecting key reads resident data alone (the four overload-run keys, a tree over keys with a resident read), one a step where a key the tree or the variable reads has none. With LastStepsRevisedRefill and LastStepsRevisedRefillSteps the cost of a close the plan asked to be measured once (02 §7.3: a refill above 1% of the play's wall-clock would move to a pinned background refill).

public int LastStepsRevisedRefillStoreReads { get; }

Property Value

int

Logger

Gets the logger instance for this service.

public ILogger<LocalProjectService> Logger { get; }

Property Value

ILogger<LocalProjectService>

MachiningActRunner

Gets the machining act runner responsible for executing machining operations.

public MachiningActRunner MachiningActRunner { get; }

Property Value

MachiningActRunner

MachiningChain

Gets or sets the authored machining chain (setup face). The runtime face follows by rebuild; runtime readers use MachiningEquipment.MachiningChain. With a session alive, the chain the runtime face holds is taken at the session's next boundary, as one written on the runtime face.

public IMachiningChain MachiningChain { get; set; }

Property Value

IMachiningChain

MachiningChainFile

Gets or sets the file path of the solid machining chain. This is used for XML serialization and file management.

public string MachiningChainFile { get; set; }

Property Value

string

MachiningEquipment

The runtime (execution) equipment face — service-owned, materialised from SetupEquipment at project assignment and session boundaries, never serialized; its AuthoredFace is SetupEquipment. Runtime consumers (runner, physics, collision, execution display) read this.

A write on the face this property hands out is a setup edit, as through the facade (MemberReplaced). A workpiece, fixture, machine chain or table transformer written is taken into SetupEquipment — the object itself, which leaves the runtime face, so an in-place edit of it afterwards is the setup's — and the runtime face follows by rebuild (NotifySetupEquipmentEdited(IProgress<IMessage>)). With a session alive, the runtime face keeps the object written until the session's next boundary — the next play, a reset, the end of the session — where the setup takes it and the face is rebuilt, unless the setup's member was written since, which then stands; IsSetupEquipmentDirty is true meanwhile, and a save before then saves the setup as it was and says so (RuntimeEquipment-Save--HeldBack, a warning). The setup's own workpiece, fixture or machine chain written on the face changes nothing: the setup keeps it and the face its copy. An ambient temperature, spindle capability or coolant heat condition written is written on SetupEquipment at once and forwarded (ForwardSetupEnvironmentToExecution()), session or not. MachiningChainFile and SpindleCapabilityFile are the setup's own, and a write of either is a setup edit too. The face this property hands out now and any face it handed out before a rebuild from the same setup are taken the same way — so is the face it hands out while a setup assigned with a session alive waits for the boundary; a face built from a setup the project no longer holds — the project changed, or its setup was replaced, since the face was taken — is not: the write is reported (RuntimeEquipment-Write--StaleFace, a warning) and the setup is left as it was, a part of the setup that face took given back. The tool is the run's: a write of MachiningTool stays on the runtime face, and the next rebuild mounts the setup's tool selection again. Read the property again after a write: the face is rebuilt.

The setter takes a MachiningEquipment read from a file (XFactory.GenByFile<MachiningEquipment>): what was written on it since it was read is written onto its AuthoredFace (CommitToAuthoredFace(): the parts and the table transformer move there, the environment values are written there, not the tool), that face becomes the project's SetupEquipment, and the runtime face follows as after any setup edit (NotifySetupEquipmentEdited(IProgress<IMessage>): rebuilt at once with no session alive, else at the next session boundary; a workpiece that is another object is announced by WorkpieceChanged), so read the property again after the assignment — the face assigned is not the face the service runs. A write on the face assigned afterwards is a setup edit as on the face this property hands out. The face the service holds already is accepted and changes nothing; one it handed out before a rebuild, whose authored face is the project's setup already, leaves the setup as it is and the runtime face follows it. Refused: null (ArgumentNullException); a face without an authored face, one built in code (ArgumentException): set SetupEquipment and call NotifySetupEquipmentEdited(IProgress<IMessage>) instead; no project loaded to hold the authored face (InvalidOperationException).

A workpiece, fixture or machine chain of SetupEquipment that another equipment face takes leaves the project's setup (a part belongs to one face at a time): a setup edit, as if the facade had cleared it (WorkpieceChanged for the workpiece).

public MachiningEquipment MachiningEquipment { get; set; }

Property Value

MachiningEquipment

MachiningMotionResolution

Gets or sets the machining motion resolution strategy (project-level; backed by MachiningActRunner).

public IMachiningMotionResolution MachiningMotionResolution { get; set; }

Property Value

IMachiningMotionResolution

MachiningProject

Gets or sets the machining project. The setter runs the full change lifecycle (teardown of the outgoing project, then Hi.MachiningProcs.LocalProjectService.OnMachiningProjectChanged()), so external assignment — e.g. through MachiningProject or a desktop host — can no longer bypass the hooks and leave the runner config un-wired (equipment-split P2).

public MachiningProject MachiningProject { get; set; }

Property Value

MachiningProject

MachiningProjectPath

public string MachiningProjectPath { get; set; }

Property Value

string

MachiningResolution_mm

Gets the machining resolution (mm) — the act-runner value, or the workpiece bottom resolution when unset. Set via SetMachiningResolution_mm(double, IProgress<IMessage>) (have-both: the caller injects the message host). Seeded from InitResolution when a project is loaded/assigned; an explicit setting then survives ResetRuntime(IProgress<IMessage>) and workpiece swaps.

public double MachiningResolution_mm { get; }

Property Value

double

MachiningSession

Gets the current machining session.

public MachiningSession MachiningSession { get; set; }

Property Value

MachiningSession

MachiningTool

Gets or sets the Setup-page selected tool (setup face). The tool the runner currently drives is MachiningEquipment.MachiningTool.

public IMachiningTool MachiningTool { get; set; }

Property Value

IMachiningTool

MachiningToolHouse

Gets or sets the machining tool house containing tool configurations.

public MachiningToolHouse MachiningToolHouse { get; set; }

Property Value

MachiningToolHouse

MachiningToolHouseFile

Gets or sets the file path to the milling tool house configuration.

public string MachiningToolHouseFile { get; set; }

Property Value

string

NcDiagnosticProgress

NC-pipeline diagnostic sink on the IMessage channel — sibling of StepDiagnosticProgress. Stable for the service lifetime (created in the ctor, only Cleared on reset, never swapped per session).

public NcDiagnosticProgress NcDiagnosticProgress { get; }

Property Value

NcDiagnosticProgress

NcManipulationDiagnosticProgress

Gets the NC-manipulation diagnostic sink — the second diagnostic home, for operations that rework an already-played NC/CL program (writeback conversion, NC optimization) as opposed to the play-time pipeline diagnostics in NcDiagnosticProgress. Keeping the two scenarios in separate homes lets a play reset clear run diagnostics without discarding manipulation results, and vice versa; each manipulation run clears this home at its start so it always holds the latest run.

public NcDiagnosticProgress NcManipulationDiagnosticProgress { get; }

Property Value

NcDiagnosticProgress

NcOptProc

Gets the HardNc NC optimization processor (retiring; the SoftNc leg is OptimizeNcFiles(string, string, ICuttingPara, IProgress<IMessage>, CancellationToken, ReadBulkDelegate<StepLuggage>, ReadBulkDelegate<StepBrief>)). Built on first use: its step luggage reader pre-allocates a dictionary of (ProcessorCount + 1) × 16,384 slots, a fixed cost no service pays until it runs a HardNc optimization.

public NcOptProc NcOptProc { get; }

Property Value

NcOptProc

NcResultRecorder

Internal Use Only. The recorder of the file being recorded; null outside a section. For the tests.

public NcResultRecorder NcResultRecorder { get; }

Property Value

NcResultRecorder

NcResultReview

Internal Use Only. The play result under review: the file, what the fill counted and the pieces for the source panels; null while no result is under review. Read without a lock: a panel that holds the object across a close finds its reader-backed queries throwing ObjectDisposedException, its metadata and counts still readable.

public NcResultReview NcResultReview { get; }

Property Value

NcResultReview

NcRunner

Gets the legacy NC runner.

public HardNcRunner NcRunner { get; }

Property Value

HardNcRunner

PacePlayer

Gets the pace player for controlling execution pace of milling operations.

public PacePlayer PacePlayer { get; }

Property Value

PacePlayer

ProjectDirectory

Gets the directory containing the machining project.

public string ProjectDirectory { get; }

Property Value

string

ProjectGeneration

The order of project changes: it moves up by one on every MachiningProjectChanged – a New, a Load, a Reload, a Close, an assignment of MachiningProject – before the event is raised, and it starts at the service's construction time in Unix milliseconds, so a later service instance starts above every value an earlier one reached. What a host keys a rebuild of its views on, since a Reload, or a Load of the file already open, leaves MachiningProjectPath as it was; and what tells it a status snapshot taken during a teardown from one taken after the change, whichever arrives last.

public long ProjectGeneration { get; }

Property Value

long

RecomputePacePointTimeout

How long RecomputeStepPhysicsOnPlayerAsync(int?, IProgress<IMessage>) lets a live play take to reach its next pace point before the queued recompute is withdrawn and –Busy reported. Pause takes effect only at the next Pace(), so a heavy step in flight is the usual cause; the play itself is never touched. Default 30 s.

public TimeSpan RecomputePacePointTimeout { get; set; }

Property Value

TimeSpan

ScriptOptions

Project-level Roslyn script options for session script execution. Initialized from DefaultScriptOptions.

public ScriptOptions ScriptOptions { get; set; }

Property Value

ScriptOptions

ScriptWrittenStepVariableKeys

Internal Use Only. The keys a value was stored under by a script since the step cache was last reset – a step-built handler's or a later indexer write, the shell's bulk write, a CSV program's data columns – and not a mapping's or a training's batches: the keys the step-physics recompute names as not recomputed, those still holding a row (WrittenStepVariableKeys). A write that stored nothing (a type a step cannot hold, a batch the store refused, a delete) notes no key.

public IReadOnlyCollection<string> ScriptWrittenStepVariableKeys { get; }

Property Value

IReadOnlyCollection<string>

SessionShell

Gets the shell API for the active session. Created at BeginSession(IProgress<IMessage>), nulled at EndSession(IProgress<IMessage>); null outside a session — its lifetime is unified with MachiningSession, so a non-null instance always implies an active session.

public SessionShell SessionShell { get; }

Property Value

SessionShell

SetupEquipment

The authored (setup) equipment face of the loaded project — the only persisted face. Authoring surfaces (setup pages, equipment editors) read and write this; runtime follows by rebuild (see NotifySetupEquipmentEdited(IProgress<IMessage>)).

public SetupEquipment SetupEquipment { get; }

Property Value

SetupEquipment

ShellProgress

Session-level routine / lifecycle message sink on the IMessage channel (cache reset, file progress, …). Owned by MachiningSession (truly session-scoped); null outside a session. Use null-safely.

public ShellProgress ShellProgress { get; }

Property Value

ShellProgress

SoftNcRunner

Facade over the active suit's NC pipeline (MachiningProject.NcRunnerSuit.SoftNcRunner). The getter is null-safe (returns null when there is no project/suit). The setter is the single rewiring entry point: it assigns the suit's runner and re-binds everything that depends on it (proxy hosts, kinematics provider, session script dictionaries, and the per-session NcRunnerSessionState). Set between two plays of one session (the strip kept: a brand or preset switch without a player reset), it resets the NC pipeline over the strip's steps as PowerReset() does: an optimization after it is refused until ResetRuntime(IProgress<IMessage>) clears the strip.

public SoftNcRunner SoftNcRunner { get; set; }

Property Value

SoftNcRunner

StepDefinitionEditLock

The project's step definitions — the step variables (StepVariableList) and the color trees (StepColorTreeList) — are edited one at a time, from the read of a list to the end of the refresh: a host takes this lock around its edit of a list and the RefreshStepVariables(IProgress<IMessage>) that follows, and the refresh takes it itself (a Monitor lock re-enters on the same thread). Readers of the registry never take it.

public object StepDefinitionEditLock { get; }

Property Value

object

StepDiagnosticProgress

Step-anchored message sink on the IMessage channel, threaded through the runner / act-processing chain.

public StepDiagnosticProgress StepDiagnosticProgress { get; }

Property Value

StepDiagnosticProgress

StepPropertiesGeneration

The generation count of StepPropertyAccessDictionary: it moves on every change the service makes to the keys a client lists — the registry rebuilt (every chain update, so every session begin and project load, a refresh of the project's step variables, RefreshStepVariables(IProgress<IMessage>), and a project's close), a step variable registered (RegisterStepVariable(string, string, string, string, Func<MachiningStep, object>): a script, a CSV mapping or title row), a training key registered (a training, a setup-angle estimate), a color tree registered (RegisterStepColorTree(StepColorTree)), and a project tree's names and hues edited in place (TryUpdateStepColorTreeAppearance(string, StepColorTree): the name a client lists changes while the inspecting slots stand). A client holding the list reads it again when this differs from the value it read with the list. It only ever increases; the value carries no other meaning. Entries a caller adds to the dictionary directly do not move it.

public long StepPropertiesGeneration { get; }

Property Value

long

StepPropertyAccessDictionary

Gets the dictionary mapping property keys to their access methods: the built-in properties, the MC.* coordinates of the current chain, the project's step variables (StepVariableList) and the step variables registered in the session. Built on first use and replaced whole by UpdateByMachiningChain(), RefreshStepVariables(IProgress<IMessage>) and a project's close; two threads asking for the first one at once get the same instance.

public ConcurrentDictionary<string, PropertyAccess<MachiningStep>> StepPropertyAccessDictionary { get; }

Property Value

ConcurrentDictionary<string, PropertyAccess<MachiningStep>>

TimeMapping

Gets or sets the time mapping for synchronizing different time-based data streams.

public TimeMapping TimeMapping { get; set; }

Property Value

TimeMapping

Workpiece

Gets or sets the authored workpiece (setup face). The runtime face follows by rebuild, its workpiece sharing the authored one's material and cutting parameter objects (see NotifySetupEquipmentEdited(IProgress<IMessage>)); runtime readers use MachiningEquipment.Workpiece. A set is a setup edit (NotifySetupEquipmentEdited(IProgress<IMessage>)): the new object brings no marks of the licensed-default rule, so its resolution never chosen follows the licensed default, and the replacement is announced (WorkpieceChanged) after the follow – with no session open after the runtime face was rebuilt from it. With a session alive another object assigned is announced at once and the runtime face follows at the next session boundary; the workpiece the running face holds, assigned here, is held back for that boundary and announced there when the setup takes it (a later write of the member stands instead), as one written on the runtime face.

public Workpiece Workpiece { get; set; }

Property Value

Workpiece

WorkpieceService

Gets the workpiece runtime service.

public WorkpieceService WorkpieceService { get; }

Property Value

WorkpieceService

WrittenStepVariableKeys

Internal Use Only. The keys a value was ever written under since the step cache was last reset (its key table), in no particular order.

public IReadOnlyCollection<string> WrittenStepVariableKeys { get; }

Property Value

IReadOnlyCollection<string>

XyzabcSolver

Gets the shared kinematics solver — the third topology entity of the equipment split, owned by the service (runtime side) rather than the persisted project graph. Rebuilt by Hi.MachiningProcs.LocalProjectService.BuildCoordinateConverter() whenever the machine chain changes.

public XyzabcSolver XyzabcSolver { get; }

Property Value

XyzabcSolver

Methods

Act(IAct, ISentenceCarrier, CancellationToken?)

Executes an act and collects all results.

public void Act(IAct act, ISentenceCarrier sourceCommand = null, CancellationToken? cancellationToken = null)

Parameters

act IAct

The act to execute.

sourceCommand ISentenceCarrier

The source command that triggered the act.

cancellationToken CancellationToken?

Cancellation token to cancel the operation.

Remarks

Plays nothing, with Play–BusyAct on ShellProgress, when ProcAct(IAct, ISentenceCarrier, CancellationToken?) refuses the act: the player running or paused – a mission, or a job such as the step-physics recompute – with this call off the player thread, or, with Play–BusyActAnotherThread, another thread playing NC on this session. With no session open the player's lock alone refuses it, and a Play–BusyAct, in a sentence of its own, is logged at Error instead. Plays nothing either, with Play–Reviewing, while a play result is under review.

Exceptions

ErrorTermRoleException

A role branch of the runtime machining chain — an axis or the spindle of a machine tool, the key branch of a CL device — is marked as an error term; an admitted act is not processed (a refused one says Play–BusyAct or Play–BusyActAnotherThread and throws nothing).

InvalidOperationException

Called from a step-built handler, on the step pipeline's pump thread (ProcAct(IAct, ISentenceCarrier, CancellationToken?)).

ApplyLicensedDefault(MachiningResolutionCommand)

Writes the licensed default for the current workpiece into a command the web Add Command dialog just created (LicensedDefaultResolution_mm(double) of ReferenceSizeForCap_mm(out bool, out double?) – the plain default when there is no reference) and records the write, so a later geometry edit lets the value follow the workpiece as it then is.

public void ApplyLicensedDefault(MachiningResolutionCommand command)

Parameters

command MachiningResolutionCommand

The fresh command.

ArmSetupAngleEstimation(SetupAngleOnlineRequest, IProgress<IMessage>)

Arms the online estimation: the tool's touched steps built from now on are watched (FirstContactWindow), and when their contact time reaches ContactSeconds the estimation (EstimateSetupAngleByFirstContact(SetupAngleOnlineRequest, int, IProgress<IMessage>, CancellationToken)) is queued on the live player run (TryRunAtPacePoint(IPacedJob, CancellationToken, out Task, bool)) and run by the player thread at its next pace point — the play is held there until the estimate, the application and the recompute are done, then continues on the new angle (the recompute runs in chunks: Pause parks it at a chunk boundary and Stop cancels it there; a paused play is resumed for the work and paused again after it). Any thread; one arm at a time (a second call replaces a still-watching first). Disarmed by ResetRuntime(IProgress<IMessage>); a run that ends before the window is complete reports SetupAngle-Online–NotReached; a window completing with no player run live (a play driven outside the player) reports SetupAngle-Online–NoPlayerRun and does nothing. Refused, with nothing armed, while a play result is under review (SetupAngle-Online–Reviewing: the steps are a result file's, and the estimate would change the project's tool).

public void ArmSetupAngleEstimation(SetupAngleOnlineRequest request, IProgress<IMessage> messageProgress)

Parameters

request SetupAngleOnlineRequest

What to sample, read and do.

messageProgress IProgress<IMessage>

Sink of every message the arm and its estimation emit; may be null.

BeginNcResultRecording(string)

Begins a recording section: the plays from here on are recorded into a result folder made from relDirectoryTemplate (DefaultRelDirectoryTemplate when null or blank; see NcResultRecorder for the tokens, which may stand in the template's last segment only, so that the results directory is one folder). A section open already is completed first (two begins are two sections). The results directory is looked through for incomplete folders, which are said, not deleted (DeleteOrphanNcResults(string) deletes them on request).

public void BeginNcResultRecording(string relDirectoryTemplate)

Parameters

relDirectoryTemplate string

The result folder's template, relative to the project folder.

Exceptions

InvalidOperationException

No project is loaded: a relative template has no folder to go into.

ArgumentException

A token stands in a segment of the template other than the last.

BeginNcRunner()

Prepares the NC runner for a play session by initializing the workpiece meshed geometry (when not already initialized), reporting progress through ShellProgress, and by giving a tree a stopped geometry Diff left partly bare its plain base back (RestorePlainBaseAfterStoppedDiff(IProgress<IMessage>)). The session's missing physics inputs are said here when they are owed: the physics turned on after the session begin, or a runtime reset that cleared what the session begin said. An outermost run drops here the selection begins a stopped run left open (ClearUnclosed()): the run stopped between a key's begin anchor and its end anchor, and kept, the begin would swallow this run's begin of the key and pair with this run's end into a section across the two runs. A nested run (an embedded script's PlayNc) is inside a live run whose open begins stand.

public void BeginNcRunner()

BeginSession(IProgress<IMessage>)

Initiate a simulation session: a new MachiningSession on the runtime face rebuilt from the setup; a call while a session is alive does nothing. The steps on the strip are kept (ResetRuntime(IProgress<IMessage>) clears them) unless the step cache holds more rows than the strip has positions: then the strip and the step cache are cleared together, so that the next step's index meets no stored row. The new session's physics record starts at the strip's count (RecordedFromStepIndex), so a recompute of the kept steps (RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken)) answers NeedsReplay: reset the runtime and replay the program.

Refused, with BeginSession--Busy and no session begun, when no session is open, the player is locked -- a run or a job on the player still beginning its own session on the player thread, or a mission script between its EndSession() and BeginSession() -- and the caller is not the player thread, which begins the session itself. The refusal is said once, on messageProgress; with none it is logged at Error through Logger, with its id: with no session there is no shell to say it on. With a session alive the call does nothing and answers true, whatever the player does: a no-op, not a refusal. The player's own run begins its session on the player thread without this gate.

public bool BeginSession(IProgress<IMessage> messageProgress = null)

Parameters

messageProgress IProgress<IMessage>

The message host of the refusal; null = the log (a refusal finds no session, so no shell).

Returns

bool

True when a session was begun, or when one is alive already (the call does nothing then); false when the call was refused (BeginSession–Busy) and no session was begun.

CheckStepColorTree(StepColorTree, IProgress<IMessage>, Func<string, bool>)

Internal Use Only. Checks a tree as a host's editor holds it, before or after an apply: what reads otherwise than written against the registry of the moment, reported to messageProgress as configuration warnings — each warning problem of FindProblems() (which the host reads itself) by its place (StepColorTree-Tree–TooManyLeavesForChart, –Tree–NextIdOutOfRange, –Node–NoOtherwise, –Node–Unreachable, –Condition–Empty, –Group–Empty, –Leaf–HueOutOfRange); each key the tree refers to that is a color tree's (–Term–ColorTreeKey: it reads as no value), that the host's interface hides (–Term–PhysicsHidden) or that no step property has now (–Term–KeyUnresolved: not registered, not a training's, not the project's); and each leaf whose value key is no quantity (–Leaf–ValueKeyNotQuantity). A problem that refuses is not reported: the host refuses the tree with it. Changes nothing and takes no lock.

public void CheckStepColorTree(StepColorTree tree, IProgress<IMessage> messageProgress, Func<string, bool> isKeyHidden = null)

Parameters

tree StepColorTree

The tree; null is checked as empty.

messageProgress IProgress<IMessage>

Where the warnings go; null reports nothing.

isKeyHidden Func<string, bool>

Whether the host's interface hides a key the registry has (a physics key while the physics options are hidden); null hides none.

CheckStrokeLimitOnStep(int)

Checks the stroke limit at the current MC position, the pose the step act just played left the chain in; a report is anchored to stepIndex. Uses IStrokeLimitConfig when EnableSoftNcRunner is active – its chain overload, which reads the six axes' native steps in the one native call that compares them (stroke_limit__check, play-core migration P9: no shadow value of a bound axis is read, one P/Invoke per step) – otherwise falls back to CheckStrokeLimit(dvec3d_t, IProgress<IMessage>) over GetMcXyzabc(IXyzabcAxes) (one native read of the six steps, then the legacy comparison).

public bool CheckStrokeLimitOnStep(int stepIndex)

Parameters

stepIndex int

The built step's index (its strip position's), or, for a step act that built no step, the index the next built step takes.

Returns

bool

True if within limits or no limits configured.

CloseNcResultReview(IProgress<IMessage>)

Closes the review (OpenNcResultReview(string, IProgress<IMessage>)): the runtime is reset as ResetRuntime(IProgress<IMessage>) resets it – the strip, the step cache, the channels and the stock go – and NcResult-Review–Closed is said. Without a review open or opening, says so (NcResult-Review–NotReviewing) and resets nothing; a close asked while an open is under way on another thread waits for that open and closes the review it stood. Refused, with the review kept, as OpenNcResultReview(string, IProgress<IMessage>) is refused.

public bool CloseNcResultReview(IProgress<IMessage> messageProgress = null)

Parameters

messageProgress IProgress<IMessage>

The message host of the call; null = the shell's.

Returns

bool

True when a review was closed.

CloseProject()

Closes the current project. Like the other five project-file operations this runs under RunExclusiveProjectFileOp(Action): a close arriving while a load or a save holds the file is cancelled with ProjectFileBusyException instead of interleaving with it. It was the one operation left outside the gate, which is why ProjectController.CloseProject's 409 handler could never fire.

public void CloseProject()

Remarks

The project is torn down before its path is cleared, in the order NewProject(string) and LoadProjectFrom(string, IProgress<IMessage>) keep. What the teardown raises on its way (the pace player's reset events, the setup-dirty flip) then still describes the open project under its own path, and only the closing MachiningProjectChanged says it is gone. A host that rebuilds its views when the project goes away — the web service's SPA does — rebuilds them once, against a service that has released the project, not mid-teardown against its runtime face, strip and session; and a teardown that throws before the project is released leaves it open under its path, so the close can be retried.

Exceptions

ProjectFileBusyException

Another project-file operation is in progress.

ConvertClToNcFiles(string, IProgress<IMessage>)

Converts the CLSF play of the current session into Fanuc NC files (writeback synthesis — MSYS tilt becomes G68.2, RTCP becomes G43.4). Play a CL file on an XYZABC machine chain first, then convert; see ConvertClToNcFiles(string, string, IProgress<IMessage>).

public IReadOnlyList<string> ConvertClToNcFiles(string relNcFileTemplate = "Output/[NcName].nc", IProgress<IMessage> messageProgress = null)

Parameters

relNcFileTemplate string

Output path template; [NcName] is replaced by the source file name.

messageProgress IProgress<IMessage>

Optional message sink for lifecycle reporting.

Returns

IReadOnlyList<string>

Written NC file paths, relative to the project base directory.

DeleteNcResult(string)

Deletes one result folder (Delete(string): the files the recording wrote, then the folder when nothing else is left in it; it must hold a result.db, and a file a connection holds in WAL mode is refused). The folder being recorded is refused here; a deleted file leaves the list the amends go to.

public bool DeleteNcResult(string relResultDirectory)

Parameters

relResultDirectory string

The result folder, relative to the project folder.

Returns

bool

True when the folder went too; false when it keeps entries the recording did not write.

Exceptions

InvalidOperationException

The folder is the one being recorded.

DeleteOrphanNcResults(string)

Deletes the orphans under relResultsDirectory (DeleteOrphans(string, IProgress<IMessage>, string)); the folder being recorded, if any, is left out.

public int DeleteOrphanNcResults(string relResultsDirectory = null)

Parameters

relResultsDirectory string

The results directory; null for Output/results.

Returns

int

How many folders were deleted.

DisarmSetupAngleEstimation(IProgress<IMessage>)

Cancels the arm still watching the step stream, if any; an estimation already queued on the player is not affected. The notice goes to messageProgress, or to the arm's own sink when null.

public void DisarmSetupAngleEstimation(IProgress<IMessage> messageProgress)

Parameters

messageProgress IProgress<IMessage>

Sink of the cancellation notice; null uses the arm's.

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose()

Dispose(bool)

protected virtual void Dispose(bool disposing)

Parameters

disposing bool

EnableCollisionDetection(bool, IProgress<IMessage>)

Enables or disables collision detection. When enabling, prepares the collidable items; when disabling, resets collision flags. Progress is reported to the injected messageProgress.

public void EnableCollisionDetection(bool value, IProgress<IMessage> messageProgress = null)

Parameters

value bool

Whether collision detection should be enabled.

messageProgress IProgress<IMessage>

Sink-agnostic message host for progress reporting.

EndNcResultRecording()

Ends the open recording section: the file is completed (the finished stock written beside it; the caller waits for it) and the values written after the play taken in; the outcome is said on the messages and kept in LastNcResultCompletion. Without a section open, says so.

public void EndNcResultRecording()

EndSession(IProgress<IMessage>)

Ends the current machining session and releases associated resources.

Refused, with EndSession--Busy and the session kept, when the player is locked -- a mission's run, playing, paused or between its commands, or a job on the player such as the step-physics recompute -- and the caller is not the player thread: ending the session would dispose it under the steps the player thread builds. Refused the same way, with EndSession--BusyAnotherThread, when another thread is inside a run of the session (PlayNcFile(string, string, NcKind), PlayNc(string, string), or an enumeration of RunNcFile(string, string, NcKind) / RunNc(string, string)). The refusal is said once, on messageProgress, else on ShellProgress. A mission script's own EndSession(), on the player thread, passes while no other thread plays; with no session open the call does nothing and answers true (nothing to end). A step-built handler's call, on the step pipeline's pump thread, passes this gate and throws at the pipeline's wait (the exception below). The player's Reset() ends the session without this gate.

public bool EndSession(IProgress<IMessage> messageProgress = null)

Parameters

messageProgress IProgress<IMessage>

The message host of the refusal; null = ShellProgress.

Returns

bool

True when the session was ended, or when none was open; false when the call was refused (EndSession–Busy, EndSession–BusyAnotherThread) and the session is kept.

Exceptions

InvalidOperationException

Called from a step-built handler, on the step pipeline's pump thread, with a session open: ending the session waits for the step pipeline, which its own handler cannot do; the pipeline reports it on the step (Step–Exception).

EnsureExecutionEquipment()

Ensures the runtime MachiningEquipment reflects the authored setup face — re-materialising it when setup edits are pending (equipment split: follow = rebuild at session boundaries). Default: no-op, for hosts without a setup face (e.g. test stubs).

public void EnsureExecutionEquipment()

EstimateSetupAngle(SampleFlag, double, string, CancellationToken, IProgress<IMessage>, ICuttingPara, IReadOnlySet<int>)

Estimates the cutter setup angle from the mapped smart-holder data and a known cutting parameter (knownPara, default Workpiece.CuttingPara — the same seed ReTrainMillingPara(SampleFlag, double, string, CancellationToken, IProgress<IMessage>) uses). Nothing is trained; see SetupAngleEstimation.

public List<SetupAngleEstimate> EstimateSetupAngle(SampleFlag sampleFlags, double outlierRatio, string dstRelFile, CancellationToken cancellationToken, IProgress<IMessage> messageProgress = null, ICuttingPara knownPara = null, IReadOnlySet<int> stepSubset = null)

Parameters

sampleFlags SampleFlag

Channels to use: Mx, My or both (a single transverse channel suits a cutter with three or more flutes; on a one- or two-flute cutter it is read with the scale pinned, to 1 or to the ratio Mz measures, and gives two mirrored angles, ScaleFixed). Mz, when selected, sharpens the per-step phase and the scale.

outlierRatio double

Fraction of the worst-fitting steps trimmed before the final estimate.

dstRelFile string

Optional report file (relative to the project base directory): JSON, one SetupAngleReport per estimate. A file that cannot be written is one SetupAngle-Report–Fault; the estimates stand.

cancellationToken CancellationToken

Cancellation token.

messageProgress IProgress<IMessage>

Message sink.

knownPara ICuttingPara

The known cutting parameter; null uses Workpiece.CuttingPara.

stepSubset IReadOnlySet<int>

Optional: only the mapped steps with these indices enter the estimate (the online command's first seconds of contact); null uses every mapped step.

Returns

List<SetupAngleEstimate>

The estimates (possibly empty).

EstimateSetupAngleByFirstContact(SetupAngleOnlineRequest, int, IProgress<IMessage>, CancellationToken)

The online estimation, now, on the steps built so far: selects the tool's first ContactSeconds seconds of contact from fromStepIndex on (FirstContactWindow), maps the recording onto those steps (MapShotFileOntoSteps(string, Range<int>, int, CycleSamplingMode, IReadOnlyList<MachiningStep>, IProgress<IMessage>, CancellationToken)), estimates the setup angle on them alone (EstimateSetupAngle(SampleFlag, double, string, CancellationToken, IProgress<IMessage>, ICuttingPara, IReadOnlySet<int>)), gates the estimate (GetApplyRefusal(SetupAngleEstimate, double)), applies it (TryApplySetupAngleEstimate(SetupAngleEstimate, IProgress<IMessage>, out double)) and recomputes the finished steps from their stored engagement (RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken), scope auto-detected: the tool's touched steps through the force kernel, the thermal chain from its mount). Waits for the pipeline first, so every step built so far is considered. Call on the player thread (a mission script, the armed pace point) or when no play is live; every outcome is reported on messageProgress under SetupAngle-Online–* and returned. The result is also kept in LastSetupAngleOnlineResult.

public SetupAngleOnlineResult EstimateSetupAngleByFirstContact(SetupAngleOnlineRequest request, int fromStepIndex, IProgress<IMessage> messageProgress, CancellationToken cancellationToken)

Parameters

request SetupAngleOnlineRequest

What to sample, read and do.

fromStepIndex int

First step index considered.

messageProgress IProgress<IMessage>

Message sink; may be null.

cancellationToken CancellationToken

Cancels the mapping, the estimate and the recompute (at its chunk boundaries).

Returns

SetupAngleOnlineResult

What was sampled, estimated, applied and recomputed; a refused call (SetupAngle-Online–Busy, or SetupAngle-Online–Reviewing while a play result is under review) answers the request alone, with a note.

FillInspectingSlot(MachiningStep)

Internal Use Only. Fills a step's inspecting slot with the inspecting key's value under the generation of the moment: the generation is read first, the value computed through the registry's current accessor (a getter that throws reads as no value), the slot written last. The step-built hook calls it with the step's briefs in its creation cache, the step-physics recompute with the new briefs pinned (InspectingSlotRefill, which a recompute job driven by hand binds to it), the scan with a segment's rows pinned, and the overload run fold's refills (OnStepsRevised(int, int), and the scan's refill of the ranges revised under it) with nothing pinned; a key that is not inspected, or not registered, writes NaN. A color tree's key writes the leaf id and the leaf's shown value packed in one double (StepColorTreeSlot), and NaN for a step that falls into no leaf.

public void FillInspectingSlot(MachiningStep step)

Parameters

step MachiningStep

The step.

FixedPace(double, double)

Creates a fixed machining motion resolution with the specified linear (mm) and rotary (deg) resolutions.

public FixedMachiningMotionResolution FixedPace(double linearResolution_mm, double rotaryResolution_deg)

Parameters

linearResolution_mm double

Linear resolution in millimeters.

rotaryResolution_deg double

Rotary resolution in degrees.

Returns

FixedMachiningMotionResolution

ForwardSetupEnvironmentToExecution()

Forwards the authored environment values (ambient temperature, coolant condition, spindle capability) onto the runtime face. These are pure data with no topology involvement, so eager forwarding is safe and keeps environment edits immediate — a full materialise is not needed for them. Call after writing the environment members on SetupEquipment.

public void ForwardSetupEnvironmentToExecution()

ForwardSetupWorkpiecePhysicsToExecution()

Forwards the authored workpiece physics inputs (workpiece material, cutting parameter and their file references) onto the runtime workpiece — the sibling of ForwardSetupEnvironmentToExecution() for the two inputs the step physics read. Pure data with no topology involvement, so eager forwarding is safe; the runtime workpiece takes the authored one's material and parameter objects when it is built, and this call forwards ones replaced on the authored workpiece since (a new object is what re-keys the physics packs). RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken) calls it before the recompute so an edit made on the setup page reaches the finished steps without a session boundary, and EnsureExecutionEquipment() at every play boundary that does not rebuild the runtime face.

public void ForwardSetupWorkpiecePhysicsToExecution()

GetInspectingKeyPresentName(StringLocalizer)

Gets the localized presentation name for the current inspecting key.

public string GetInspectingKeyPresentName(StringLocalizer stringLocalizer)

Parameters

stringLocalizer StringLocalizer

The string localizer to use for localization

Returns

string

The localized presentation name

GetLocalProjectService()

Get Local Project Service as base-service.

public LocalProjectService GetLocalProjectService()

Returns

LocalProjectService

Local Project Service

GetMachiningEquipment()

Get the runtime MachiningEquipment.

public MachiningEquipment GetMachiningEquipment()

Returns

MachiningEquipment

MachiningEquipment

GetMachiningProject()

Gets the MachiningProject instance.

public MachiningProject GetMachiningProject()

Returns

MachiningProject

The MachiningProject instance.

GetSessionShell()

Returns the session shell that exposes the runtime surface of the active machining session.

public ISessionShell GetSessionShell()

Returns

ISessionShell

IsStepColorTreeKey(string)

Internal Use Only. Whether the registry's current entry under key is a color tree, the project's or one the session registered: its inspecting slot holds a packed leaf (StepColorTreeSlot), its value is the leaf id and its colors are the tree's.

public bool IsStepColorTreeKey(string key)

Parameters

key string

The key; null is no tree's.

Returns

bool

ListNcResults(string)

Lists the result folders under relResultsDirectory (relative to the project folder), the newest first; the folder being recorded, if any, is left out.

public IReadOnlyList<NcResultEntry> ListNcResults(string relResultsDirectory = null)

Parameters

relResultsDirectory string

The results directory; null for Output/results.

Returns

IReadOnlyList<NcResultEntry>

The entries.

LoadProject(string, IProgress<IMessage>)

Loads a project by absolute file path. Load-time diagnostics (a machine or part STL the project references but that is missing on disk, an unloadable child XML, a referenced side file that cannot be read, …) do not fail the load: the project comes up without that part and each problem is reported as an IMessage — always to the service logger, and also to messageProgress when the caller injects one.

public void LoadProject(string projectPath, IProgress<IMessage> messageProgress = null)

Parameters

projectPath string

The absolute file path

messageProgress IProgress<IMessage>

Optional caller-injected sink for the load-time diagnostics (e.g. a MessageCollector a web controller hands back in its response). Null keeps logger-only reporting.

Remarks

The project file itself is the one file that tolerance does not cover: a .hincproj that is missing, locked or malformed fails the call. The call begins by releasing the project that is open (LoadProjectFrom(string, IProgress<IMessage>)), so such a failure leaves no project open — the CloseProject() state, announced through MachiningProjectChanged — rather than the one that was open: a load means the current data is no longer needed, and the meshes of two projects must never be in memory at once (owner, 2026-09-25).

Exceptions

FileNotFoundException

No file at projectPath.

IOException

The file could not be read as a project (locked, malformed, gone between the existence check and the read); the reason is the inner exception.

ProjectFileBusyException

Another project-file operation is in progress.

MapShotFileOntoSteps(string, Range<int>, int, CycleSamplingMode, IReadOnlyList<MachiningStep>, IProgress<IMessage>, CancellationToken)

Maps the recording onto the steps of stepSection for an estimate on those steps. A CSV-played strip (its steps stamped with the controller instant) is mapped by wall clock, the stamped-step pairs overlapping the section only; an NC-simulated strip has no wall clock, so the file's Time column is read as the play's own timecode and the section is mapped as the timecode window [begin(first), begin(last) + one cycle of the last step] — with that end the mapper's stretch ratio is exactly 1, so every step's pairing window starts at its own begin timecode and the shot file of a replay of the same program at the same resolution lands on the steps that produced it. The section is mapped as one such window per run of consecutive steps of toolId whose spindle turns (a tool change or an M05 inside the window — which the contact window survives — ends a run: a stopped step has no revolution to pair and no timecode window can span it). The file is evicted from the cache first, so a recording still being written is re-read; stale rows of the section are dropped so the returned count is this mapping's. The caller must have waited for any mapping in flight (WaitForTagMappings(CancellationToken)).

public int MapShotFileOntoSteps(string shotRelFile, Range<int> stepSection, int toolId, StepTimeShotUtil.CycleSamplingMode cycleSamplingMode, IReadOnlyList<MachiningStep> steps, IProgress<IMessage> messageProgress, CancellationToken cancellationToken)

Parameters

shotRelFile string

The recording, relative to the project base directory.

stepSection Range<int>

Inclusive step-index window.

toolId int

The tool whose steps are paired; a negative value pairs every step of the section.

cycleSamplingMode StepTimeShotUtil.CycleSamplingMode

How much of the recording each step is paired with.

steps IReadOnlyList<MachiningStep>

The strip's steps, by index.

messageProgress IProgress<IMessage>

Message sink; may be null.

cancellationToken CancellationToken

Cancels the file read and the mapping.

Returns

int

The number of steps in the section that received rows.

MarkInitResolutionChosen()

Records that the authored workpiece's InitResolution was set explicitly (REST, the setup controller, the picker): the licensed-default rule leaves it alone from now on. The mark is the Workpiece object's, kept until the project is closed: it goes with the object when that is replaced – through the Workpiece setter, a whole SetupEquipment assigned, or Workpiece written directly – and the new object's value is judged afresh (nothing is recorded while the equipment holds no workpiece). A workpiece written on the runtime face under a live session is not the authored one until the session's next boundary takes it: the mark goes on the object the setup holds now, and the one taken at the boundary is judged afresh there. An explicit value is the user's whatever it is – an odd but legal input is accepted, and only warned about where it is used.

public void MarkInitResolutionChosen()

MarkMachiningResolutionChosen(MachiningResolutionCommand)

Records that command's value was set explicitly: the licensed-default rule leaves it alone.

public void MarkMachiningResolutionChosen(MachiningResolutionCommand command)

Parameters

command MachiningResolutionCommand

The command whose value was set.

NewProject(string)

Creates a new project by file path.

public void NewProject(string projectPath)

Parameters

projectPath string

The absolute file path

NotifySetupEquipmentEdited(IProgress<IMessage>)

Marks the authored face edited so the runtime face follows. Follow is a REBUILD (never live incremental sync): immediately when no session is active, otherwise at the next session boundary (BeginSession(IProgress<IMessage>) / the next play's EnsureExecutionEquipment() / a player reset). The workpiece's material and cutting parameter are the exception: the runtime face holds the authored workpiece's WorkpieceMaterial and CuttingPara objects themselves, as it holds the setup's spindle capability and coolant condition. A field written in place on one of them needs neither this call nor a rebuild: the run takes it – the material from the next step whose physics is computed, the cutting parameter from the session's next physics-pack build (the next play or the next tool change) – and a step-physics recompute (RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken)) that rolls its forward back does not undo it. A material or cutting parameter replaced on the authored workpiece needs no call either: the runtime face takes it at the next play start, a reset or a recompute that keeps its forward (ForwardSetupWorkpiecePhysicsToExecution()), and a running or paused play keeps the old object until then; with no session open, this call rebuilds the runtime face from it at once. The facade setters call this; call it manually after mutating SetupEquipment members in place, after assigning a whole SetupEquipment (an equipment file read as one) and after writing Workpiece directly: the workpiece then in the equipment is the one judged, with its own marks (MarkInitResolutionChosen(): a replaced object brings none, so its value is judged afresh), and a replaced object is announced (WorkpieceChanged) after the follow – with no session open after the runtime face was rebuilt from it, else before the runtime face follows at the next session boundary. Before the runtime face follows, the resolutions never chosen follow the licensed default for the workpiece as it now is: the workpiece's InitResolution, every MachiningResolutionCommand directly under the Mission root and the runner's seeded machining resolution (at once with no session open, else at the next BeginSession(IProgress<IMessage>)) are written with LicensedDefaultResolution_mm(double) of ReferenceSizeForCap_mm(out bool, out double?) when they were never chosen – not marked chosen (MarkInitResolutionChosen(), MarkMachiningResolutionChosen(MachiningResolutionCommand), SetMachiningResolution_mm(double, IProgress<IMessage>)) and at the plain DefaultInitResolution_mm or at what the rule itself last wrote – up for a larger part, down for a smaller one, back to the plain default when the licence allows it; a value set to anything else is the user's and is left alone (it is clamped where it is used, with the engine's warning). With no reference (no geometry, a .wct whose tree is not loaded, a geometry without bounds) nothing is written and nothing is said. Reports Workpiece-InitResolution–DefaultFollowsLicense and MachiningResolution–DefaultFollowsLicense for what changed.

public void NotifySetupEquipmentEdited(IProgress<IMessage> messageProgress = null)

Parameters

messageProgress IProgress<IMessage>

Sink for the messages a follow reports (have-both: the caller injects the host); null = the session shell when one is open, else the logger alone.

NotifyStepValuesWritten()

Values were written onto built steps by a mapping embed (MappedStepColumns, the keys registered already included): the slots of a written key are stale, so the generation moves and a scan follows.

public void NotifyStepValuesWritten()

OpenNcResultReview(string, IProgress<IMessage>)

Opens a recorded play result for review: the recording section, if open, is ended; the runtime is reset as ResetRuntime(IProgress<IMessage>) resets it (a review open already is closed by that); then the strip, the steps and the physics channels are rebuilt from the result file and the finished stock, when the result holds one and its hash matches, is loaded as the workpiece. The review stays until a reset – CloseNcResultReview(IProgress<IMessage>), the player's Reset, ResetRuntime(IProgress<IMessage>), a project switch, the service's dispose. The outcome is said on messageProgress or the shell (NcResult-Review–Opened with the counts, the warnings of an incomplete result and of a stock that did not load). Refused, with nothing changed, from inside the NC run being played (NcResult-Review–Refused), while the player is running or paused on another thread (NcResult-Review–Busy) or another thread plays NC on this session (NcResult-Review–BusyAnotherThread), and for the folder this service is recording into (NcResult-Review–Recording). A recording open is ended first, and the result it completed is said again after the reset (NcResult-Review–RecordingEnded). From the moment the recording is ended until the review stands, the work a review refuses is refused as under the review. A stop of the player while the fill runs on its thread (a mission's Review Play Result command), and the service's dispose, end the fill at a bin's end, close the review and say NcResult-Review–Cancelled.

public bool OpenNcResultReview(string relResultDirectory, IProgress<IMessage> messageProgress = null)

Parameters

relResultDirectory string

The result folder, relative to the project folder (an absolute path is used as it is); null or blank for the newest completed result: the one the recording open at the call completes (a mission's Record, play, Review), else the newest under DefaultNcResultsDirectory.

messageProgress IProgress<IMessage>

The message host of the call; null = the shell's.

Returns

bool

True when the result is under review; false when the call was refused or the fill was stopped.

Exceptions

InvalidOperationException

No project is loaded; or no completed result exists when none was named (a recording open was ended first, nothing else changed); or the strip changed under the fill (another thread added positions): nothing is under review then, and the runtime stays reset, the strip empty.

FileNotFoundException

The folder named holds no result file.

InvalidDataException

The result file is not one this build reads (the cases of OpenRead(string)), or a chunk of it is not: nothing is under review then, and the runtime stays reset, the strip empty.

PlayBrandNcFile(string, string)

Plays a famous-brand NC code file from the specified path with pace control (no kind dispatch — always the brand runner).

public void PlayBrandNcFile(string baseDirectory, string relFilePath)

Parameters

baseDirectory string

Base directory for resolving relative paths

relFilePath string

Relative path to the NC file

Remarks

Throws InvalidOperationException, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>); the review is closed by a reset, never by a play).

PlayClFile(string, string)

Plays an NX-CL (CLSF) file from the specified path.

public void PlayClFile(string baseDirectory, string relFilePath)

Parameters

baseDirectory string

Base directory for resolving relative paths.

relFilePath string

Relative path to the CLSF file.

Remarks

Throws InvalidOperationException, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>); the review is closed by a reset, never by a play).

PlayCsvFile(string, string)

Plays a CSV file from the specified path.

public void PlayCsvFile(string baseDirectory, string relFilePath)

Parameters

baseDirectory string

Base directory for resolving relative paths.

relFilePath string

Relative path to the CSV file.

Remarks

Throws InvalidOperationException, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>); the review is closed by a reset, never by a play).

PlayNc(string, string)

Plays NC commands from raw text with pace control.

public void PlayNc(string ncText, string fileNameAlternative = "--")

Parameters

ncText string

The NC command text to execute

fileNameAlternative string

Alternative name to associate with the NC program

Remarks

Throws InvalidOperationException, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>); the review is closed by a reset, never by a play).

PlayNcFile(string, string, NcKind)

Plays an NC program file from the specified path, the runner picked by kind (Auto = by file extension: known CL/CSV extensions map to those runners, anything else plays as brand NC).

public void PlayNcFile(string baseDirectory, string relFilePath, NcKind kind = NcKind.Auto)

Parameters

baseDirectory string

Base directory for resolving relative paths.

relFilePath string

Relative path to the NC program file.

kind NcKind

Which runner plays the file; Auto detects by extension.

Remarks

Throws InvalidOperationException, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>); the review is closed by a reset, never by a play).

PowerReset()

Performs a controller power reset, modelling a power-off / power-on cycle:

No axis moves: the chain stays where it stands (only ResetRuntime(IProgress<IMessage>) and a new session re-home it). After a stop, the next run's program starts at the pose the machine stopped at; between two programs that ran to their end, it starts from the configured home pose, as before. Without the second step, calling PowerReset while a project is loaded would leave volatile commons alive across the supposed power cycle (they live in the SyntaxPiece JSON dataflow rather than in any IPowerResettable dependency). The strip is kept: between two files of a mission the first file's steps stay on it while the second file's sentence indices start at 0 again, so with steps on the strip an optimization after the reset is refused with nothing written (OptimizeNc--StripSpansPipelineReset, OptimizeNcFiles(string, string, ICuttingPara, IProgress<IMessage>, CancellationToken, ReadBulkDelegate<StepLuggage>, ReadBulkDelegate<StepBrief>)): optimize before the reset, or clear the strip with ResetRuntime(IProgress<IMessage>).

Refused, with PowerReset--Refused on ShellProgress and nothing reset, from inside a run of the session on the calling thread (IsRunningNcLinesOnThisThread: an NC-embedded @@PowerReset();, or a mission script enumerating RunNcFile(string, string, NcKind) itself): the second step would dispose the pipeline layers the run walks, and the program's remaining lines would never be played, the play reported as ended. A mission script's PowerReset() between two programs passes.

public void PowerReset()

ProcAct(IAct, ISentenceCarrier, CancellationToken?)

Processes an act and returns the results.

public IEnumerable<object> ProcAct(IAct act, ISentenceCarrier sourceCommand = null, CancellationToken? cancellationToken = null)

Parameters

act IAct

The act to process.

sourceCommand ISentenceCarrier

The source command that triggered the act.

cancellationToken CancellationToken?

Cancellation token to cancel the operation.

Returns

IEnumerable<object>

What the act runner yields for the act (ProcAct(IAct, MachiningSession, IMachiningService, ISentenceCarrier, CancellationToken, StepDiagnosticProgress), which lists every case), played as the sequence is enumerated: for each step the act plays, the collision result when the detection found one, then the step's bundle or a SkippedStep when the step procedure built none, then the act that played the step; a tooling act yields itself, and a feedrate or spindle-speed act does when it changes the state in force (a repeat yields nothing); the other acts yield nothing. Act(IAct, ISentenceCarrier, CancellationToken?) enumerates it to the end. Empty, with Play–BusyAct on ShellProgress and nothing played, when the act is refused (IsPacedActAdmitted()): the player is running or paused – a mission, or a job such as the step-physics recompute – and this is not the player thread, or, with Play–BusyActAnotherThread, another thread is playing NC on this session. With no session open – a mission script between its EndSession() and BeginSession(), or a run still beginning its session – the player's lock alone refuses it off the player thread, and a Play–BusyAct is logged at Error through Logger, with its id and a sentence of its own, there being no shell to say it on; the sequence is empty all the same. A step-built handler's call, on the step pipeline's pump thread, is not refused here: it throws when the sequence is enumerated (the exception below). Empty too, with Play–Reviewing on the shell (logged with no session), while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>)): an act would build a live step after the result's positions. The admission is decided at the call, ahead of the role check; the act is played as the sequence is enumerated, so enumerate it at once.

Exceptions

ErrorTermRoleException

A role branch of the runtime machining chain — an axis or the spindle of a machine tool, the key branch of a CL device — is marked as an error term. Thrown at the call of an admitted act, before the act is processed; the message names the role and the branch.

InvalidOperationException

Enumerated on the step pipeline's pump thread: a step-built handler cannot play an act, and the act runner refuses it.

ReTrainMillingPara(SampleFlag, double, string, CancellationToken, IProgress<IMessage>)

Train Milling Parameter.

public void ReTrainMillingPara(SampleFlag sampleFlags, double outlierRatio, string dstRelFile, CancellationToken cancellationToken, IProgress<IMessage> messageProgress = null)

Parameters

sampleFlags SampleFlag
outlierRatio double
dstRelFile string
cancellationToken CancellationToken
messageProgress IProgress<IMessage>

ReadNcRunnerSuit(string)

Reads an NcRunnerSuit from relFile (project relative) and makes it the active suit — switching the active parser (NC or CSV) — then re-binds every host hookup (see Hi.MachiningProcs.LocalProjectService.RewireForActiveSuit()). Refused, with ReadNcRunnerSuit–Refused on ShellProgress, while a run of the session is in flight on any thread – a mission's program file or a script's play, playing or paused (IsRunningNcLines): the runner's per-session layers are mid-enumeration and cannot be safely reset. Between two plays of one session (the strip kept) the switch resets the NC pipeline over the strip's steps, as PowerReset() does: an optimization after it is refused (OptimizeNc–StripSpansPipelineReset) until ResetRuntime(IProgress<IMessage>) clears the strip.

public void ReadNcRunnerSuit(string relFile)

Parameters

relFile string

ReadStepColorTreeTrace(CompiledStepColorTree, MachiningStep)

Internal Use Only. One step under a tree, explained: the values of the keys the tree refers to (Keys, in that order, read as the registry's entry reads them, one step's reads with no row pinned), the nodes tried (as Classify(ReadOnlySpan<double>, out double) walks them), the leaf and its shown value. A read that throws ends the trace with the exception's text; a tree being read on this thread already answers no leaf, no values and the note in Error. Nothing is written or reported.

public StepColorTreeTrace ReadStepColorTreeTrace(CompiledStepColorTree compiled, MachiningStep step)

Parameters

compiled CompiledStepColorTree

The tree; null traces nothing.

step MachiningStep

The step; null traces nothing.

Returns

StepColorTreeTrace

The trace (StepColorTreeTrace).

RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken)

Recomputes the step physics of the finished steps from the stored cutter-workpiece engagement with the CURRENT inputs, in place — no replay. Waits for the runner's pipeline to drain (WaitAll()), then forwards the authored workpiece physics onto the runtime face (ForwardSetupWorkpiecePhysicsToExecution()): a step still in flight would read the forwarded material as its sequential physics runs, and a refusal's rollback could not take that back. The environment values — ambient temperature, coolant condition, spindle capability — are not forwarded here: whoever writes them on the authored face calls ForwardSetupEnvironmentToExecution() afterwards (an in-place edit of the shared capability or coolant object needs no call), and a value that has not reached the runtime face is not seen by the change detection. Then drives CreateStepPhysicsRecomputeJob(StepPhysicsRecomputeOptions) chunk by chunk, the job reading each chunk's rows (and, for its pre-scan, which kinds the rows hold) straight from SqliteStepStorage and writing through its synchronous whole-row upsert, pacing through the session's pace point between the chunks while a player run is live — so from a mission script Pause parks the recompute at a chunk boundary and Stop cancels it there. Raises StepPhysicsRecomputed when a range was replaced.

Direct entry: call on the player thread (a mission or NC-embedded script) or when no play is live (a direct-drive host). The HTTP mirror goes through RecomputeStepPhysicsOnPlayerAsync(int?, IProgress<IMessage>) instead, which schedules the same job on the player. A session is required; without one a StepPhysics-Recompute--NoSession error is reported and the result is Refused. A fault in the core, the luggage store or the message sink propagates to the caller — no result, no --Fault message. What the job had written before it stays: those steps keep the recomputed values, the forward stays with them, StepPhysicsRecomputed is raised over that range before the fault propagates, and the job's record says where it stopped, so the next recompute finishes the rest; a fault with nothing written rolls the forward back, as a refusal does. The rollback sets the runtime workpiece's material, cutting parameter and their files back to what they were before the forward: it takes back a material or cutting parameter the forward brought from the authored workpiece, not a field written in place on an object both faces hold.

One recompute at a time per service: a call that lands while another is in flight — a queued HTTP recompute reaching its pace point inside a script's, or the reverse — is refused with --Busy and changes nothing (a nested recompute would sweep the strip the outer one is rewriting).

public StepPhysicsRecomputeResult RecomputeStepPhysics(int? toolId, IProgress<IMessage> messageProgress, CancellationToken cancellationToken)

Parameters

toolId int?

Scope override: only this tool's steps go through the force kernel, whatever changed, while the sequential chain still passes every tool's steps from where it starts; null auto-detects the scope from what changed.

messageProgress IProgress<IMessage>

User-facing message sink (StepPhysics-Recompute–*); may be null.

cancellationToken CancellationToken

Checked at every chunk boundary; a cancelled recompute keeps what was written.

Returns

StepPhysicsRecomputeResult

What was done, with the replaced strip range and the counts.

RecomputeStepPhysicsOnPlayerAsync(int?, IProgress<IMessage>)

The HTTP path of RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken): schedules the recompute on the player so it never runs concurrently with a play, and completes when it has ended. Two ways onto the player thread:

  • Player idle (Ready / Finished): a one-shot (TryStartOneShot(Action<PacePlayee>, out Task)) that owns the player exactly like a play — the status shows Running, the transport is blocked, Pause parks it at the next chunk boundary and Stop cancels it there — without counting as a run or flipping the player's finished state.
  • A run live (playing or paused): queued on it as a paced job (TryRunAtPacePoint(IPacedJob, CancellationToken, out Task, bool)) and driven by the player thread from its next pace point — the one it is parked in when paused, the next Pace() when playing — chunk by chunk, the play held there until the recompute has finished. Every chunk boundary is a pace point: Pause parks the recompute there and Resume goes on, exactly as for the play; Stop cancels it there. A play that is PAUSED when the recompute starts is resumed for it (the status shows Running while it computes, and a Pause meanwhile parks it like any play) and paused again when it has finished, before the play could take a step — the user is back where they were; a Resume pressed meanwhile does not cancel that. This covers the shipping shape of a mission, whose script commands call PlayNcFile themselves: that play runs on the player thread with IsRunningNcLines raised BY that thread, and parks at the same pace points, so the recompute is welcome there — the flag alone would have refused it. The steps built so far are recomputed with the current inputs and the resumed play continues from the recomputed chain, so the whole strip ends up on one set of inputs; --Done covers the steps that existed at the pace point. When the play does not reach a pace point within RecomputePacePointTimeout the request is withdrawn and --Busy reported; a Stop that ends the run first completes with Canceled.
Never throws: an NC program being played on the session by a thread OTHER than the one the recompute lands on — a PlayNcFile / PlayNc host request on its own thread, which has no pace point to ride and keeps growing the strip (StepPhysics-Recompute--Busy, checked before scheduling a one-shot and again on the player thread through IsRunningNcLinesOnOtherThreads), another recompute in flight (--Busy) and a session that ended or was replaced between the request and the player thread (--NoSession) report to messageProgress and complete with Refused. A fault inside the recompute, or of the player's pace point between two chunks, reports --Fault and completes with Refused when nothing was written, and with Canceled over the replaced range when the job had written: those steps keep the recomputed values, the rest their previous ones, a --FaultKeptRange warning ahead of the --Fault names the range, and the next recompute finishes the rest. Progress: one StepPhysics-Recompute--Progress line per chunk boundary (at most about twenty per recompute), and the drawing is flagged after every chunk.
public Task<StepPhysicsRecomputeResult> RecomputeStepPhysicsOnPlayerAsync(int? toolId, IProgress<IMessage> messageProgress)

Parameters

toolId int?

Scope override; see RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken).

messageProgress IProgress<IMessage>

User-facing message sink; may be null.

Returns

Task<StepPhysicsRecomputeResult>

A task that completes with the recompute's result once it has ended on the player thread.

ReferenceSizeForCap_mm(out bool, out double?)

The reference size the licence's resolution cap is judged against for this project – the one reference every entrance reads (ApplyLicensedDefault(MachiningResolutionCommand), the follow on a setup edit, the runner's seed at BeginSession(IProgress<IMessage>), the REST reply) – with the width of the stock standing for it. It is always the AUTHORED geometry's: the standing tree's own ReferenceSize_mm while the tree stands for that geometry (MeshedGeomIsOf(IMakeXmlSource), whatever its kind: the number the engine's clamp reads, and a tree built from a shape records the raw bounds' longest side anyway), else the raw bounds (ReferenceSizeOfRawGeom_mm(IMakeXmlSource)) for a shape and 0 for a CubeTreeFile whose tree is not loaded (a .wct carries no other source) – so a tree built from a previous geometry (a mid-session re-play after a geometry edit) can never win. stockWidth_mm is the standing tree's cube width only while the tree stands for this geometry (the stock the next play goes on cutting); null until the stock is built, and null while the stock standing is another geometry's (an edit whose stock the next play has yet to build). The dirty flag plays no part: a tool edit marks the authored face dirty, but the stock standing is still this geometry's.

public double ReferenceSizeForCap_mm(out bool fromMeshedGeom, out double? stockWidth_mm)

Parameters

fromMeshedGeom bool

True when the size is the loaded tree's own (a .wct stock whose tree stands).

stockWidth_mm double?

The cube width of the stock standing for this geometry; null until built, or while the stock standing is another geometry's.

Returns

double

The reference size in mm; 0 when unknown.

RefreshDrawing()

Refreshes the visual display of the milling course.

public void RefreshDrawing()

RefreshStepVariables(IProgress<IMessage>)

Compiles the project's step variables (StepVariableList) and color trees (StepColorTreeList) again and registers them in place of the ones registered before; call it after editing either list. A formula text already compiled for the same script options is not compiled again; a formula is full-trust C#, as a mission's script is. What is not registered — a variable or a tree under a built-in's key or MC., under a key an earlier one has (the variables count as earlier than the trees), a formula that does not compile, a tree this version does not understand or one with a problem that refuses — and what reads otherwise than written — a unit name that is not a unit, a tree the load numbered, a tree with a warning — are reported to messageProgress, or to the session's shell when it is null, and always to the log. A project variable whose formula throws, and a tree that throws, are reported again the next time they throw. What a script, a CSV or a training registered in the session stays — under a key the project now defines, set aside until the project lets the key go; the generation moves, and the inspected key's chart line and colors are bound again. The refresh runs under StepDefinitionEditLock; a host edits a list under the same lock, so a list is never read here while it is edited.

public void RefreshStepVariables(IProgress<IMessage> messageProgress = null)

Parameters

messageProgress IProgress<IMessage>

Where to report what is not registered.

Reg(XFactory)

Bootstraps XML-factory registration for the simulation pipeline. Entry points must call this once at startup before any project XML is deserialized. Pass a custom XFactory for test isolation, or null to populate Default. Idempotent.

public static void Reg(XFactory factory = null)

Parameters

factory XFactory

RegisterStepColorTree(StepColorTree)

Registers a color tree for the session (RegisterStepColorTree(StepColorTree)): a categorical step property whose value is the id of the leaf a step falls into, which the charts, the 3D view and the step CSV can pick until the session ends. The tree is cloned (Clone(): a node without an id is numbered from NextId, 1, 2, 3… when none is given, the same numbers every time) and compiled; tree itself is not touched or kept. A key registered again in the session takes the new definition; a key named like a built-in step property or under MC. (StepColorTree-Register–KeyTaken), or one the project defines a step variable or a color tree under (StepColorTree-Register–ProjectKeyTaken), and a tree with a problem that refuses — no key, a term without a key, a comparison without a threshold, an id repeated or out of range, a value this version writes but does not read back such as an operation outside its enum (StepColorTree-Register–Refused) — are not registered; a tree with problems that only warn is registered as it is (StepColorTree-Register–Problems). Each is reported once per key per session. The generation moves, and the inspected key's chart line and colors are bound again when the key is the inspected one.

public void RegisterStepColorTree(StepColorTree tree)

Parameters

tree StepColorTree

The tree; null registers nothing.

RegisterStepVariable(string, string, string, string, Func<MachiningStep, object>)

Registers a step variable so downstream components (strip charts, CSV exports, scripting) can read it from MachiningStep. A key registered again in the same session takes the new definition; a key named like a built-in step property (IsBuiltInKey(string)) is not registered, nor is one the host keeps for itself (the HiNc host keeps the keys its project defines step variables or color trees under). The value is read when asked for and never stored on the step: a value written onto the step under the key wins, else variableFunc is called; a number of any numeric type (or a bool, as 1 / 0) reads as a double, anything else — and a call that throws — as no value.

public void RegisterStepVariable(string key, string name, string unit, string formatString, Func<MachiningStep, object> variableFunc = null)

Parameters

key string

Unique key.

name string

Human-readable name; may equal key.

unit string

Physical unit name (PhysicsUnit); null for none, and a name that is not a unit reads as none.

formatString string

Display format string; nullable.

variableFunc Func<MachiningStep, object>

Optional value extractor; null when the key reads only a value written onto the step under the key (a script's indexer, a mapping, a training).

ReloadProject(IProgress<IMessage>)

Reloads the current project from disk, discarding in-memory edits. Load-time diagnostics are reported the same way as in LoadProject(string, IProgress<IMessage>).

public void ReloadProject(IProgress<IMessage> messageProgress = null)

Parameters

messageProgress IProgress<IMessage>

Optional caller-injected sink for the load-time diagnostics; null keeps logger-only reporting.

Remarks

The in-memory project is released before the file is read, as in LoadProject(string, IProgress<IMessage>): a project file that has been deleted, locked or damaged since the project was opened fails the call and leaves no project open. Reloading is the user saying the in-memory data is not needed; putting the file back and loading it again is the recovery.

Exceptions

InvalidOperationException

No project is open.

FileNotFoundException

The project file is no longer on disk.

IOException

The file could not be read as a project; the reason is the inner exception.

ProjectFileBusyException

Another project-file operation is in progress.

ReportStepColorTreesReferencing(string, IProgress<IMessage>)

Internal Use Only. The keys of the project's color trees that refer to key, in the list's order, each once; when there are any, one configuration warning StepVariable-Delete–ReferencedByColorTree to messageProgress naming them: a host removing a project step variable says so beside the removal, before its refresh — the trees read the key as no value until something registers it again. The engine itself removes nothing here.

public IReadOnlyList<string> ReportStepColorTreesReferencing(string key, IProgress<IMessage> messageProgress)

Parameters

key string

The key of the step variable being removed; null or empty names no tree.

messageProgress IProgress<IMessage>

Where the warning goes; null reports nothing.

Returns

IReadOnlyList<string>

The keys of the trees that refer to key.

ResetPlayer(IProgress<IMessage>)

Resets the player from a thread that may: Reset() – the run stopped and waited for, then the player's reset handler (Hi.MachiningProcs.LocalProjectService.PacePlayer_ResetedEvent(): ResetRuntimeCore(IProgress<IMessage>), Hi.MachiningProcs.LocalProjectService.EndSessionCore()) and ResetedEvent. The mission script's Reset() (Reset()), its REST mirror and the web service's api/Execution/reset come here; the service's own reset at a project switch (Hi.MachiningProcs.LocalProjectService.OnMachiningProjectChanging()) calls the player directly.

From the Busy check to the end of the reset's handler the session is marked torn down (TryBeginSessionTeardown()): a direct play that reaches its registration meanwhile -- admitted before, materialising while the reset decided -- is refused there with Play--BusyReset.

Refused, with Reset--Refused on messageProgress (else on ShellProgress) and nothing reset, on the player thread -- a mission script's Reset(), an NC-embedded @@Reset(); under a mission: the reset would cancel the run it is called from and run its handler on that very thread, ending the session and clearing the runtime under the mission's own run (a script resets the runtime between two programs with ResetRuntime(IProgress<IMessage>)). Refused, with Reset--Busy and nothing reset, while a thread other than the player's is inside a run of the session (IsRunningNcLinesOffThePlayerThread: a PlayNcFile(string, string, NcKind) request on its request thread, an enumeration of RunNcFile(string, string, NcKind) on a host's thread): the player's own run the reset stops and waits for first, that one it cannot, and the reset's handler would clear the strip and end the session under it -- stop it, or let it finish, then reset. A mission's own play on the player thread is no refusal: the reset ends it. The refusal is said once, on messageProgress, else on ShellProgress; with neither (no session open, no sink given) it is logged at Error through Logger, with its id. Throws on the step pipeline's pump thread (a step-built handler's call, IsOnPumpThread): the reset waits for the pipeline, which its own handler cannot do, and under the player's reset lock a host's reset waiting at that pipeline would hold the lock this call waits for.

public bool ResetPlayer(IProgress<IMessage> messageProgress = null)

Parameters

messageProgress IProgress<IMessage>

The message host of the refusal; null = ShellProgress, or the log with no session open.

Returns

bool

True when the player was reset; false when the call was refused (Reset–Refused, Reset–Busy) and nothing was reset.

Exceptions

InvalidOperationException

Called from a step-built handler, on the step pipeline's pump thread.

ResetRuntime(IProgress<IMessage>)

Reset the runtime states including: meshed geometry, collision flags, machine tool position, CL strips, message buffer and etc.. MachiningResolution_mm is deliberately left untouched so an explicit setting survives resets; it is seeded from InitResolution only when a project is loaded/assigned.

Refused, with ResetRuntime--Refused on messageProgress (else on ShellProgress) and nothing reset, from inside a run of the session on the calling thread (IsRunningNcLinesOnThisThread): an NC-embedded @@ResetRuntime();, which runs on the thread of its play under the semantic loop of its own block, and a mission script that enumerates RunNcFile(string, string, NcKind) / RunNc(string, string) itself and calls this inside its loop. The reset would clear the strip under the block in play and dispose the pipeline layers the run walks, so the block's remaining acts would land on an emptied strip and the program's remaining lines would never be played, the play reported as ended. A mission script's ResetRuntime() between two programs runs on the player thread with no run in flight and passes, as does a host's call from its own thread while the player is idle and no other thread plays.

Refused, with ResetRuntime--Busy and nothing reset, when the player is locked -- a mission's run, playing, paused or between its commands, or a job on the player such as the step-physics recompute (RecomputeStepPhysicsOnPlayerAsync(int?, IProgress<IMessage>)) -- and the caller is not the player thread: the reset would clear the strip and the NC pipeline under the steps the player thread builds. Refused the same way, with ResetRuntime--BusyAnotherThread, when another thread is inside a run of the session (PlayNcFile(string, string, NcKind), PlayNc(string, string), or an enumeration of RunNcFile(string, string, NcKind) / RunNc(string, string)). The refusal is said once, on messageProgress, else on ShellProgress; with neither -- no session is open and the caller gave no sink, as a host's own call while a mission script is between its EndSession() and BeginSession() -- it is logged at Error through Logger, with its id. A step-built handler's call, on the step pipeline's pump thread, passes this gate and throws at the pipeline's wait (the exception below). The service's own resets -- a project switch, the player's Reset() -- do not go through this gate.

public bool ResetRuntime(IProgress<IMessage> messageProgress = null)

Parameters

messageProgress IProgress<IMessage>

The message host of the call – the refusal and the reset's own messages; null = ShellProgress for the refusal, or the log when no session is open.

Returns

bool

True when the runtime was reset; false when the call was refused (ResetRuntime–Refused, ResetRuntime–Busy, ResetRuntime–BusyAnotherThread) and nothing was reset.

Exceptions

InvalidOperationException

Called from a step-built handler, on the step pipeline's pump thread: the reset waits for the step pipeline, which its own handler cannot do; the pipeline reports it on the step (Step–Exception).

RunBrandNcFile(string, string)

Runs a famous-brand NC code file from the specified path (no kind dispatch — always the brand runner).

public IEnumerable<Action> RunBrandNcFile(string baseDirectory, string relFilePath)

Parameters

baseDirectory string

Base directory for resolving relative paths. If the value is null, BaseDirectory substitutes the value.

relFilePath string

Relative path to the NC file.

Returns

IEnumerable<Action>

An enumerable of actions to be executed.

Remarks

Refused, with Play–Busy on ShellProgress and an empty sequence, while the player is running or paused and this is not the player thread, or with Play–BusyAnotherThread while another thread plays this session, or with Play–BusyReset while the player is being reset (the reset ends the session) (RunNcLines(INcRunner, string, IEnumerable<string>, CancellationToken)); decided at the first MoveNext, the thread registered as playing for the enumeration – dispose it (foreach does). Throws InvalidOperationException at the first MoveNext, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>)).

RunClFile(string, string)

Runs an NX-CL (CLSF) file from the specified path.

public IEnumerable<Action> RunClFile(string baseDirectory, string relFilePath)

Parameters

baseDirectory string

Base directory for resolving relative paths.

relFilePath string

Relative path to the CLSF file.

Returns

IEnumerable<Action>

An enumerable of actions to be executed.

Remarks

Refused, with Play–Busy on ShellProgress and an empty sequence, while the player is running or paused and this is not the player thread, or with Play–BusyAnotherThread while another thread plays this session, or with Play–BusyReset while the player is being reset (the reset ends the session) (RunNcLines(INcRunner, string, IEnumerable<string>, CancellationToken)); decided at the first MoveNext, the thread registered as playing for the enumeration – dispose it (foreach does). Throws InvalidOperationException at the first MoveNext, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>)).

RunCsvFile(string, string)

Runs a CSV file from the specified path.

public IEnumerable<Action> RunCsvFile(string baseDirectory, string relFilePath)

Parameters

baseDirectory string

Base directory for resolving relative paths.

relFilePath string

Relative path to the CSV file.

Returns

IEnumerable<Action>

An enumerable of actions to be executed.

Remarks

Refused, with Play–Busy on ShellProgress and an empty sequence, while the player is running or paused and this is not the player thread, or with Play–BusyAnotherThread while another thread plays this session, or with Play–BusyReset while the player is being reset (the reset ends the session) (RunNcLines(INcRunner, string, IEnumerable<string>, CancellationToken)); decided at the first MoveNext, the thread registered as playing for the enumeration – dispose it (foreach does). Throws InvalidOperationException at the first MoveNext, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>)).

RunNc(string, string)

Runs NC commands from raw text.

public IEnumerable<Action> RunNc(string ncText, string fileNameAlternative = "--")

Parameters

ncText string

The NC command text to execute

fileNameAlternative string

Alternative name to associate with the NC program

Returns

IEnumerable<Action>

An enumerable of actions to be executed

Remarks

Refused, with Play–Busy on ShellProgress and an empty sequence, while the player is running or paused and this is not the player thread, or with Play–BusyAnotherThread while another thread plays this session, or with Play–BusyReset while the player is being reset (the reset ends the session) (RunNcLines(INcRunner, string, IEnumerable<string>, CancellationToken)); decided at the first MoveNext, the thread registered as playing for the enumeration – dispose it (foreach does). Throws InvalidOperationException at the first MoveNext, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>)).

RunNcFile(string, string, NcKind)

Runs an NC program file from the specified path, the runner picked by kind (Auto = by file extension: known CL/CSV extensions map to those runners, anything else runs as brand NC).

public IEnumerable<Action> RunNcFile(string baseDirectory, string relFilePath, NcKind kind = NcKind.Auto)

Parameters

baseDirectory string

Base directory for resolving relative paths.

relFilePath string

Relative path to the NC program file.

kind NcKind

Which runner runs the file; Auto detects by extension.

Returns

IEnumerable<Action>

An enumerable of actions to be executed.

Remarks

Refused, with Play–Busy on ShellProgress and an empty sequence, while the player is running or paused and this is not the player thread, or with Play–BusyAnotherThread while another thread plays this session, or with Play–BusyReset while the player is being reset (the reset ends the session) (RunNcLines(INcRunner, string, IEnumerable<string>, CancellationToken)); decided at the first MoveNext, the thread registered as playing for the enumeration – dispose it (foreach does). Throws InvalidOperationException at the first MoveNext, before a line is played and before the usage report counts a run, while a play result is under review (OpenNcResultReview(string, IProgress<IMessage>)).

RunToLineEnd()

Advances the player by one NC/CSV line and pauses.

public void RunToLineEnd()

SaveAsProject(string)

Saves the current project to a specified relative file path.

public void SaveAsProject(string projectPath)

Parameters

projectPath string

The absolute file path

SaveProject()

Save project by project path.

public void SaveProject()

ScanStepColorTree(CompiledStepColorTree, int, int, CancellationToken)

Internal Use Only. A preview of a tree over the strip: the steps of [begin, end) classified under compiled and counted per leaf, the strip walked one segment at a time with the rows the reads need pinned, as the inspecting-slot scan walks it (WalkStripSegments(ClStrip, int, int, Func<bool>, Func<bool>, Action<MachiningStep, bool>, Action<int, int>)). The keys are read as the registry's entry would read them (ReadStepColorTreeLeaf(StepColorTreeHolder, MachiningStep, out double)); a step whose read throws counts as faulted and in no leaf, and nothing is reported. Nothing is written: no slot, no generation, no guide, no drawing flag; the tree need not be registered.

public StepColorTreeScan ScanStepColorTree(CompiledStepColorTree compiled, int begin, int end, CancellationToken cancellation)

Parameters

compiled CompiledStepColorTree

The tree; null scans nothing.

begin int

The first strip index; a negative one starts at 0.

end int

One past the last strip index; the strip's count when it is beyond it. A begin at or beyond the strip walks nothing: the scan's End is its Begin.

cancellation CancellationToken

Ends the walk between segments; the counts are then partial. The walk ends the same way when InspectingSlotGeneration moves under it (a session's begin, a recompute, a key inspected or registered: the strip may be another one), and a strip cleared under it (a runtime reset, which moves no generation) leaves the scan not completed: a scan of two strips counts nothing.

Returns

StepColorTreeScan

The counts (StepColorTreeScan); every leaf of the tree listed, in tree order.

SelectFirstContactWindow(IReadOnlyList<MachiningStep>, int, double, int)

The tool's first contactSeconds seconds of contact from fromStepIndex on, read off the finished strip.

public static FirstContactWindow SelectFirstContactWindow(IReadOnlyList<MachiningStep> steps, int toolId, double contactSeconds, int fromStepIndex)

Parameters

steps IReadOnlyList<MachiningStep>

The strip's steps, by index (null entries are skipped).

toolId int

Tool-house id, or negative for the first tool that touches.

contactSeconds double

Contact time to accumulate.

fromStepIndex int

First step index considered.

Returns

FirstContactWindow

The window; Reached false when the strip holds less contact than asked.

SetEnableErrorTerms(bool, IProgress<IMessage>)

Writes the error-term switch (EnableErrorTerms) with a message host: what the setup edit says – the resolutions never chosen following the licensed default – goes to messageProgress, so a caller that answers a request can carry it back; null = the session shell when one is open, else the log.

public void SetEnableErrorTerms(bool value, IProgress<IMessage> messageProgress)

Parameters

value bool

Whether the machine runs with its error terms.

messageProgress IProgress<IMessage>

The message host; null = ShellProgress.

SetFixture(Fixture, IProgress<IMessage>)

Sets the authored fixture (Fixture) with a message host: what the setup edit says – the resolutions never chosen following the licensed default – goes to messageProgress, so a caller that answers a request can carry it back; null = the session shell when one is open, else the log.

public void SetFixture(Fixture value, IProgress<IMessage> messageProgress)

Parameters

value Fixture

The fixture; null to clear.

messageProgress IProgress<IMessage>

The message host; null = ShellProgress.

SetMachiningResolution_mm(double, IProgress<IMessage>)

Sets the machining resolution (mm): the API user's and the script's explicit set, so the runner's seed is marked chosen and the licensed-default rule leaves it alone until the project is closed. Progress is reported to the injected messageProgress. A command's Run writes through SetMachiningResolutionByCommand(double, bool, IProgress<IMessage>) instead, so a value the rule wrote is not taken for the user's.

public void SetMachiningResolution_mm(double value, IProgress<IMessage> messageProgress = null)

Parameters

value double

The machining resolution in millimeters.

messageProgress IProgress<IMessage>

Sink-agnostic message host for progress reporting.

TrainMillingPara(SampleFlag, bool, double, string, CancellationToken, ICuttingPara, IProgress<IMessage>)

Train Milling Parameter.

public void TrainMillingPara(SampleFlag sampleFlags, bool enableFzOnlyDuringDrilling, double outlierRatio, string dstRelFile, CancellationToken cancellationToken, ICuttingPara paraTemplate, IProgress<IMessage> messageProgress = null)

Parameters

sampleFlags SampleFlag
enableFzOnlyDuringDrilling bool
outlierRatio double
dstRelFile string
cancellationToken CancellationToken
paraTemplate ICuttingPara
messageProgress IProgress<IMessage>

TryApplySetupAngleEstimate(SetupAngleEstimate, IProgress<IMessage>, out double)

Advances the estimated tool's setup angle (SetupAngle_deg — the whole cutter turned in the holder) by the estimate; the cutter's own flute offset angles are not touched, so every fluting type is served alike. Reports EstimateSetupAngle–Applied, or a warning and false when the tool is not a milling tool carrying a milling cutter. No gate here — the caller decides; the physics pack snapshots the flute angles, so follow with RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken) (or ResetRuntime(IProgress<IMessage>) before a replay).

public bool TryApplySetupAngleEstimate(SetupAngleEstimate estimate, IProgress<IMessage> messageProgress, out double delta_deg)

Parameters

estimate SetupAngleEstimate

A succeeded estimate.

messageProgress IProgress<IMessage>

Message sink; may be null.

delta_deg double

The rotation added (deg): RotationSignConvention × the estimate.

Returns

bool

True when the angle was written.

TryGetStepColorTree(string, out CompiledStepColorTree)

Internal Use Only. The compiled tree the registry's current entry under key reads, the project's or one the session registered.

public bool TryGetStepColorTree(string key, out CompiledStepColorTree compiled)

Parameters

key string

The key; null is no tree's.

compiled CompiledStepColorTree

The compiled tree; null when there is none.

Returns

bool

True when the entry is a color tree with a compiled tree.

TryUpdateStepColorTreeAppearance(string, StepColorTree)

Internal Use Only. Takes an edit of a project tree's names and hues alone into the registry in place: the host has put tree into StepColorTreeList under key and asks for this before a refresh. When the key's registry entry reads a registered project tree and tree compiles to the same logic (HasSameLogicAs(CompiledStepColorTree)), the entry's holder takes the new tree, the entry's presentation takes the new name, the key's guide — when the project holds the tree's guide under it — is built anew over the new hues, the registry's generation moves (StepPropertiesGeneration: a client reads the names again) without the inspecting slots' (the slots hold the same leaf ids), and the strip is flagged for a recolor. Nothing is reported: the host's check (CheckStepColorTree(StepColorTree, IProgress<IMessage>, Func<string, bool>)) says what the tree's warnings are. Runs under StepDefinitionEditLock.

public bool TryUpdateStepColorTreeAppearance(string key, StepColorTree tree)

Parameters

key string

The key of the project tree edited.

tree StepColorTree

The tree as edited, numbered or not (a clone of it is what registers): under key, and the first tree of the project's list under it — the one the registry reads; a later tree under the same key never registers.

Returns

bool

True when the edit was taken in place. False when nothing was changed and the host must refresh instead (RefreshStepVariables(IProgress<IMessage>)): the tree is not the project's first under the key, the key's entry is no registered project tree's, the tree has a problem that refuses or does not compile, or its logic differs.

UpdateByMachiningChain()

Updates components when the machining chain changes.

public void UpdateByMachiningChain()

UpdateByMachiningEquipment()

Re-binds everything derived from the runtime equipment face. Runs as the tail of Hi.MachiningProcs.LocalProjectService.MaterialiseExecutionEquipment(); call manually only after mutating the runtime face outside the service.

public void UpdateByMachiningEquipment()

UpdateIdealMillingToolOffsetTableByToolHouse()

Updates the ideal milling tool offset table based on the current tool house configuration. The radius column follows the project's RadiusOffsetBasis so a zero-based (tool-centre path) program keeps its D rows at wear only.

public void UpdateIdealMillingToolOffsetTableByToolHouse()

WriteNcRunnerSuit(string)

Writes the active NcRunnerSuit to relFile (project relative). Pure file IO — does not update any in-memory pointer.

public void WriteNcRunnerSuit(string relFile)

Parameters

relFile string

WriteShotFile(TimeSpan, string, IProgress<IMessage>)

Writes time-based shot data to a file with the specified sampling period: one file per program the strip's steps were played from, a row per sampling beat from the strip's second position on (a row is interpolated from the step before it). A file is opened afresh – truncated – each time the strip turns to its program from another one, so a program whose steps resume after another program's keeps only its last stretch. A write that opens no file – no step of a program past the strip's first position: nothing has played yet, or what played came after this write – reports ShotFile-Write–NoFile (a warning) in place of ShotFile-Write–Finish.

public void WriteShotFile(TimeSpan samplingPeriod, string relFileTemplate = "Output/[NcName].shot.csv", IProgress<IMessage> messageProgress = null)

Parameters

samplingPeriod TimeSpan

The time period between samples

relFileTemplate string

Template for the output file path, can include [NcName] placeholder

messageProgress IProgress<IMessage>

Optional caller-supplied progress sink for start/finish messages.

WriteStepFile(string, IProgress<IMessage>)

Writes step-based data to a file: one file per program the strip's steps were played from, a row per step. A file is opened afresh – truncated – each time the strip turns to its program from another one, so a program whose steps resume after another program's keeps only its last stretch. A write that opens no file – no step of a program on the strip: nothing has played yet, or what played came after this write – reports StepFile-Write–NoFile (a warning) in place of StepFile-Write–Finish.

public void WriteStepFile(string relFileTemplate = "Output/[NcName].step.csv", IProgress<IMessage> messageProgress = null)

Parameters

relFileTemplate string

Template for the output file path, can include [NcName] placeholder

messageProgress IProgress<IMessage>

Optional caller-supplied progress sink for start/finish messages.

WriteStepVariables(IReadOnlyList<StepVariableWrite>)

Internal Use Only. Writes a batch of values onto steps under step-variable keys, one transaction for the batch (WriteStepVariables(IReadOnlyList<StepVariableWrite>)): a mapping's columns, a training's per-step estimates, a script's bulk writes (WriteStepVariables(IEnumerable<StepVariableWrite>)). A value that is not a number or a string is reported once per key (StepVariable-Write–NotStored) and not stored; a write that faults is reported (StepVariable-Write–Fault) and nothing of the batch lands. The inspecting slots of a written key are stale afterwards: the generation moves once for the batch (NotifyStepValuesWritten()).

public void WriteStepVariables(IReadOnlyList<StepVariableWrite> writes)

Parameters

writes IReadOnlyList<StepVariableWrite>

The writes; a caller with many hands them over a segment at a time (SegmentLength).

WriteStepVariablesFromScript(IReadOnlyList<StepVariableWrite>)

Internal Use Only. A script's bulk write (WriteStepVariables(IEnumerable<StepVariableWrite>)): WriteStepVariables(IReadOnlyList<StepVariableWrite>), the keys stored noted as script-written.

public void WriteStepVariablesFromScript(IReadOnlyList<StepVariableWrite> writes)

Parameters

writes IReadOnlyList<StepVariableWrite>

The writes; a segment at a time.

Events

InspectingSlotsScanned

Raised, on the scan's thread, with the generation whose scan filled every step on the strip and flagged the strip for a recolor: a client that read a pending Individual strip chart reads it again.

public event Action<int> InspectingSlotsScanned

Event Type

Action<int>

MachiningProjectChanged

Event raised when the machining project changes.

public event LocalProjectService.MachiningProjectChangedDelegate MachiningProjectChanged

Event Type

LocalProjectService.MachiningProjectChangedDelegate

MachiningProjectChanging

Raised at the start of every project change – a New, a Load, a Reload, a Close, an assignment of MachiningProject – before the open project is torn down and before the collection that follows the teardown (LoadProjectFrom(string, IProgress<IMessage>)), with the outgoing project and its path (both null when none is open). A host that holds the project's objects outside the service – the web service's model-key index, which names the machine chain, the tools and the geometries for its editors – lets go of them here, so that collection frees them before the next project's are read; held past this point, the outgoing chain kept its solids and their collision trees alive, the whole machine model a project. MachiningProjectChanged follows once the change is in place.

public event LocalProjectService.MachiningProjectChangedDelegate MachiningProjectChanging

Event Type

LocalProjectService.MachiningProjectChangedDelegate

MachiningStepBuilt

event to configure steps. The first parameter is the previous step; the second parameter is the current step. The previous step is null if no previous step exists.

public event MachiningActRunner.MachiningStepBuiltDelegate MachiningStepBuilt

Event Type

MachiningActRunner.MachiningStepBuiltDelegate

NcResultReviewChanged

Internal Use Only. Raised when a review opened (its strip, steps, channels and stock in place and NcResult-Review–Opened said, the review's lock released) and when one closed (as the reset that closes it begins, before anything else of the reset runs), on the thread that opened or closed it; outside the review's lock, except the close a reopen or an abandoned open raises, which runs while the opening thread holds that lock (it is reentrant and private to the service: a handler must not wait for another thread that opens or closes a review); NcResultReview reads the new state. A host that mirrors the state to its clients – the web service's execution status – subscribes this instead of inferring the change from the player's or the strip's events, which a review driven over REST does not raise. An open that is abandoned after the review stood (the fill stopped or failed) raises it once, as a close; a refused open, or one that failed before the file opened, raises nothing.

public event Action NcResultReviewChanged

Event Type

Action

OnNcFileRan

Event triggered after an NC file is executed.

public event Action OnNcFileRan

Event Type

Action

OnNcPipelineReset

App-lifetime event raised after the per-session NC pipeline state has been rewound (Hi.MachiningProcs.LocalProjectService.ResetNcPipelineState()): the next RunNcLines(string, IEnumerable<string>, MachiningSession, StepDiagnosticProgress, NcDiagnosticProgress, CancellationToken) re-initialises from scratch, so its FileIndex / SentenceIndex counters restart at 0. Raised on EVERY rewind path — a runner-suit rewire (brand switch), PowerReset() and ResetRuntime(IProgress<IMessage>) (including a mission script's ResetRuntime() between two NC files) — not only on a PacePlayer reset or a project swap, which are the two boundaries a session-lifetime consumer already sees. Anything keyed by those counters must drop its index here, or the next file's pieces land under the previous file's numbers.

public event Action OnNcPipelineReset

Event Type

Action

OnShellMessageAdded

App-lifetime bridge for ShellProgress appends. Because ShellProgress is session-scoped (recreated at BeginSession(IProgress<IMessage>), null outside a session), a consumer that wants every session's shell messages subscribes here once instead of chasing the swapping instance — BeginSession(IProgress<IMessage>) re-wires the bridge to the new sink each session, the same way OnSourcedActEntry is bridged. Carries the append index and the message.

public event Action<int, IMessage> OnShellMessageAdded

Event Type

Action<int, IMessage>

OnShellMessageCleared

App-lifetime bridge for ShellProgress clears (see OnShellMessageAdded).

public event Action OnShellMessageCleared

Event Type

Action

OnSourcedActEntry

App-lifetime event triggered for each SourcedActEntry produced during NC/CSV execution.

public event Action<SourcedActEntry> OnSourcedActEntry

Event Type

Action<SourcedActEntry>

OnSyntaxPieceRan

Raised after each SyntaxPiece has been run during NC execution (app lifetime).

public event Action<SyntaxPiece> OnSyntaxPieceRan

Event Type

Action<SyntaxPiece>

OnUpdatedInspectingQuantityFunc

Event triggered when the inspecting quantity function is updated.

public event Action OnUpdatedInspectingQuantityFunc

Event Type

Action

SetupEquipmentDirtyChanged

Raised with the new value whenever IsSetupEquipmentDirty changes. An edit with no session raises it twice back to back (true, then false once the immediate materialise has run).

public event Action<bool> SetupEquipmentDirtyChanged

Event Type

Action<bool>

StepPhysicsRecomputed

App-lifetime event raised after RecomputeStepPhysics(int?, IProgress<IMessage>, CancellationToken) has replaced the physics of the steps in [beginStepIndex, endStepIndex) — the strip range whose briefs, sequential physics states and (for force reruns) stored luggage rows now carry the recomputed values. Raised on the thread that ran the recompute (the player thread on the one-shot and mission-script paths, the caller's thread on a direct call) after the reader caches are cleared and the drawing refresh is flagged, so a subscriber may re-pull step quantities at once; it must not block. Not raised when nothing was replaced (NoChange, Refused, NeedsReplay, a cancel or a fault that landed before the first written step). Raised for a cancel and for a fault that wrote: the direct entry raises it before the fault propagates, the paced recompute (RecomputeStepPhysicsOnPlayerAsync(int?, IProgress<IMessage>)) before it answers Canceled over that range.

public event Action<int, int> StepPhysicsRecomputed

Event Type

Action<int, int>

StepPropertiesGenerationChanged

Raised with the new value after StepPropertiesGeneration moved, on the thread that changed the registry — a script's, the sequencing pipeline's for a CSV title row, a request's — so a handler returns at once. A CSV title row raises it once per column it registers.

public event Action<long> StepPropertiesGenerationChanged

Event Type

Action<long>

StepsRevised

Raised, on the thread that revised them, after the inspecting slots of the steps of [begin, end) were filled again and their positions re-stamped because the overload run fold revised their values (InternalStepsRevised: a run closed, a rapid line was reported) while the inspecting key reads the fold; the slot generation did not move. A client that read those steps' values (the Individual strip chart) reads them again. A subscriber runs on the revising thread (the sequencing stage, or the player at a run's start or end), under no lock, and returns at once — as a MachiningStepBuilt handler does; the webservice only nudges its broadcast runner.

public event Action<int, int> StepsRevised

Event Type

Action<int, int>

WorkpieceChanged

Raised when the authored workpiece object was replaced: by NotifySetupEquipmentEdited(IProgress<IMessage>), which every setup edit ends in, whenever it finds another Workpiece object in the equipment than the one last announced – replaced through the Workpiece setter, a whole SetupEquipment assigned, or Workpiece written directly. The pair carries the object last announced (the loaded project's own after a project swap, which is not announced) and the object now authored, either of them null when the equipment held none. Raised after the resolutions never chosen followed and, with no session open, after the runtime face was rebuilt from the new object; with a session open the runtime face follows at the next session boundary (IsSetupEquipmentDirty meanwhile). The notice compares with the object last announced, not with the last write: a replacement undone by a direct write before the next notice is not announced, while an object set back through the setter is announced again.

public event Action<SeqPair<Workpiece>> WorkpieceChanged

Event Type

Action<SeqPair<Workpiece>>