Skip to content

Hmp1PresentationAdapter

Namespace: Hex1b

Assembly: Hex1b.dll

A presentation adapter that serves terminal output to multiple remote clients over the Hex1b Muxer Protocol (HMP).

csharp
public sealed class Hmp1PresentationAdapter : ITerminalLifecycleAwarePresentationAdapter, IHex1bTerminalPresentationAdapter, IAsyncDisposable

Inheritance

ObjectHmp1PresentationAdapter

Implements

Constructors

Hmp1PresentationAdapter(int, int)

Creates a new muxer presentation adapter with the specified initial dimensions.

Parameters:

  • width (Int32): Initial terminal width in columns. The PTY runs at this size from t0 until a peer takes primary and requests a resize.
  • height (Int32): Initial terminal height in rows.
csharp
public Hmp1PresentationAdapter(int width = 80, int height = 24)

Properties

Capabilities

Capability hints that inform optimization strategies.

Returns: TerminalCapabilities

csharp
public TerminalCapabilities Capabilities { get; }

ClientCount

Gets the number of currently connected clients.

Returns: Int32

csharp
public int ClientCount { get; }

Height

Current terminal height in rows.

Returns: Int32

csharp
public int Height { get; }

OnClientConnected

Invoked after a new client completes its ClientHello → Hello → StateSync handshake. Argument carries the assigned peer ID, the display name and (parsed) role hint the client supplied.

Returns: Func<Hmp1ClientConnectedEventArgs, CancellationToken, Task>

csharp
public Func<Hmp1ClientConnectedEventArgs, CancellationToken, Task>? OnClientConnected { get; set; }

OnClientDisconnected

Invoked when a per-client session ends (clean disconnect or transport failure). Per-session disposal runs in parallel so a slow handler does not delay transport cleanup. Receives .

Returns: Func<Hmp1ClientDisconnectedEventArgs, CancellationToken, Task>

csharp
public Func<Hmp1ClientDisconnectedEventArgs, CancellationToken, Task>? OnClientDisconnected { get; set; }

OnPrimaryChanged

Invoked when the primary peer changes (including transitions to no primary).

Returns: Func<Hmp1ServerPrimaryChangedEventArgs, CancellationToken, Task>

csharp
public Func<Hmp1ServerPrimaryChangedEventArgs, CancellationToken, Task>? OnPrimaryChanged { get; set; }

OnResized

Invoked when the producer's PTY dimensions change at runtime (typically as a result of a primary-peer resize). Awaited inline by the per-client read pump that processed the triggering frame. Multicast (+=) is supported; each handler is awaited independently with its own exception isolation.

Returns: Func<Hmp1ServerResizedEventArgs, CancellationToken, Task>

csharp
public Func<Hmp1ServerResizedEventArgs, CancellationToken, Task>? OnResized { get; set; }

PrimaryPeerId

Gets the peer ID of the current primary, or null when no peer is primary (initial state, or after the previous primary disconnected with no replacement).

Returns: String

csharp
public string? PrimaryPeerId { get; }

Width

Current terminal width in columns.

Returns: Int32

csharp
public int Width { get; }

Methods

AddClient(Stream, CancellationToken)

Adds a new client connection. The client must first send a frame; the server then writes the assigned peer ID, current primary, and roster in , followed by a frame.

Parameters:

Returns: Task<Hmp1ClientHandle>

A handle that can be disposed to disconnect the client.

csharp
public Task<Hmp1ClientHandle> AddClient(Stream stream, CancellationToken ct = default)

DisposeAsync()

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

Returns: ValueTask

A task that represents the asynchronous dispose operation.

csharp
public ValueTask DisposeAsync()

EnterRawModeAsync(CancellationToken)

Enter raw mode for proper input capture.

Parameters:

Returns: ValueTask

csharp
public ValueTask EnterRawModeAsync(CancellationToken ct = default)

ExitRawModeAsync(CancellationToken)

Exit raw mode and restore normal terminal input handling.

Parameters:

Returns: ValueTask

csharp
public ValueTask ExitRawModeAsync(CancellationToken ct = default)

FlushAsync(CancellationToken)

Flush any buffered output immediately.

Parameters:

Returns: ValueTask

csharp
public ValueTask FlushAsync(CancellationToken ct = default)

GetCursorPosition()

Gets the current cursor position in the terminal. Returns (0, 0) if the position cannot be determined.

Returns: ValueTuple<Int32, Int32>

A tuple of (Row, Column), both 0-based.

csharp
public (int Row, int Column) GetCursorPosition()

ReadInputAsync(CancellationToken)

Receive input (keystrokes, mouse events as ANSI sequences) FROM the user.

Parameters:

Returns: ValueTask<Byte>>

Raw input bytes from the user, or empty when disconnected.

csharp
public ValueTask<ReadOnlyMemory<byte>> ReadInputAsync(CancellationToken ct = default)

TerminalCompleted(int)

Called when the terminal has completed execution.

Parameters:

  • exitCode (Int32): The exit code from the terminal's run callback or workload.
csharp
public void TerminalCompleted(int exitCode)

TerminalCreated(Hex1bTerminal)

Called when the terminal instance is created and associated with this adapter.

Parameters:

csharp
public void TerminalCreated(Hex1bTerminal terminal)

TerminalStarted()

Called when the terminal has started and is ready to process I/O.

csharp
public void TerminalStarted()

WriteOutputAsync(ReadOnlyMemory<byte>, CancellationToken)

Write rendered output TO the presentation layer (display).

Parameters:

Returns: ValueTask

csharp
public ValueTask WriteOutputAsync(ReadOnlyMemory<byte> data, CancellationToken ct = default)

Events

Disconnected

Raised when the presentation layer disconnects (e.g., terminal closed, WebSocket dropped).

Returns: Action

csharp
public event Action? Disconnected

Resized

Raised when the presentation layer is resized by the user.

Returns: Action<Int32, Int32>

csharp
public event Action<int, int>? Resized

Remarks

This adapter acts as a headless presentation layer. Instead of displaying output on a local console, it multicasts ANSI output to all connected clients via their streams. Use to add new client connections.

Each client first sends a frame; the server then assigns a peer ID and replies with (carrying the assigned peer ID, current primary, and roster) followed by a frame with a full screen snapshot.

One peer may be the primary at any time. The primary's frames are applied to the underlying PTY; secondaries' Resize frames are silently dropped. Any peer can send a to take over (always granted in this iteration); the resulting and any fresh are broadcast to all peers.

Released under the MIT License.