feat(editor): F4.6a simulation mode and a computer's desktop
Java's mode buttons start and stop the room, now in a worker of the editor's page (LocalSimHost), with Java's speed slider. While the simulation runs the design is locked as in Java: no palette, no sheet, nothing moves, no undo. Cables that carry a frame light up in Java's green, and a tap on a computer opens its desktop: Java's title, the software installation first, then the installed programs in the order of Java's list for the language, a taskbar with the network icon and the network as the simulation runs it. The room sends that over a new topic, node:<id>. Desktops stay over a return to the design and show again at the next start. The programs' windows follow from F4.6b. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,9 +15,10 @@ export type AppKind = (typeof APP_KINDS)[number];
|
||||
/**
|
||||
* What a client subscribes to: which cables carry frames (`activity`), a
|
||||
* card's capture (`trace:<portId>`), a program's window
|
||||
* (`app:<nodeId>/<app>`).
|
||||
* (`app:<nodeId>/<app>`), a computer's network settings as it runs with them
|
||||
* (`node:<nodeId>`: its desktop's title and network info).
|
||||
*/
|
||||
export type Topic = 'activity' | `trace:${string}` | `app:${string}/${AppKind}`;
|
||||
export type Topic = 'activity' | `trace:${string}` | `app:${string}/${AppKind}` | `node:${string}`;
|
||||
|
||||
export const CLIENT_MESSAGE_KINDS = ['sub', 'unsub', 'start', 'stop', 'speed', 'input'] as const;
|
||||
export type ClientMessageKind = (typeof CLIENT_MESSAGE_KINDS)[number];
|
||||
@@ -41,7 +42,7 @@ export type ClientMessage =
|
||||
readonly reqId: string;
|
||||
};
|
||||
|
||||
export const HOST_MESSAGE_KINDS = ['state', 'activity', 'trace', 'app', 'ack', 'error'] as const;
|
||||
export const HOST_MESSAGE_KINDS = ['state', 'activity', 'trace', 'app', 'node', 'ack', 'error'] as const;
|
||||
export type HostMessageKind = (typeof HOST_MESSAGE_KINDS)[number];
|
||||
|
||||
export type SimMode = 'design' | 'simulation';
|
||||
@@ -66,9 +67,23 @@ export type HostMessage =
|
||||
| { readonly v: 1; readonly kind: 'trace'; readonly portId: string; readonly frames: readonly TraceFrame[]; readonly reset: boolean }
|
||||
/** A program's new window lines from line `from` on; on subscribing, all (from 0). */
|
||||
| { readonly v: 1; readonly kind: 'app'; readonly node: string; readonly app: AppKind; readonly from: number; readonly lines: readonly unknown[] }
|
||||
/**
|
||||
* A computer's first card as the simulation runs it (DHCP may change it):
|
||||
* on subscribing, when it changes, and none while the simulation never ran.
|
||||
*/
|
||||
| { readonly v: 1; readonly kind: 'node'; readonly node: string; readonly settings: NodeSettings }
|
||||
| { readonly v: 1; readonly kind: 'ack'; readonly reqId: string }
|
||||
| { readonly v: 1; readonly kind: 'error'; readonly code: ErrorCode; readonly reqId?: string; readonly detail?: string };
|
||||
|
||||
/** What Java's desktop shows of a computer's network (NetworkInfoPanel, the window's title). */
|
||||
export interface NodeSettings {
|
||||
readonly ipAddress: string;
|
||||
readonly subnetMask: string;
|
||||
readonly defaultGateway: string;
|
||||
readonly dnsServer: string;
|
||||
readonly macAddress: string;
|
||||
}
|
||||
|
||||
export type Parsed<T> = { readonly message: T } | { readonly error: { readonly code: ErrorCode; readonly detail: string } };
|
||||
|
||||
const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);
|
||||
@@ -79,6 +94,7 @@ export function isTopic(value: unknown): value is Topic {
|
||||
if (value === 'activity') return true;
|
||||
if (typeof value !== 'string') return false;
|
||||
if (value.startsWith('trace:')) return value.length > 'trace:'.length;
|
||||
if (value.startsWith('node:')) return /^node:[^/]+$/.test(value);
|
||||
const app = /^app:([^/]+)\/(.+)$/.exec(value);
|
||||
return app !== null && (APP_KINDS as readonly string[]).includes(app[2]!);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user