feat(editor): the simulation's properties in a sheet of their own, with a restart for everyone
Who started the simulation, "Pakete verwerfen" and the dropped packets move from the toolbar into a properties sheet beside the surface. New in it: restart the simulation, after asking. The room learns a restart message: stopped as by stop, every capture, dropped frame and program window emptied, started anew and named after who restarted; refused for readers and frozen projects, logged, and waiting for asked blobs like a start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,7 @@ export type AppKind = (typeof APP_KINDS)[number];
|
||||
*/
|
||||
export type Topic = 'activity' | 'dropped' | `trace:${string}` | `app:${string}/${AppKind}` | `node:${string}`;
|
||||
|
||||
export const CLIENT_MESSAGE_KINDS = ['sub', 'unsub', 'start', 'stop', 'speed', 'drop', 'clearCapture', 'input'] as const;
|
||||
export const CLIENT_MESSAGE_KINDS = ['sub', 'unsub', 'start', 'stop', 'restart', 'speed', 'drop', 'clearCapture', 'input'] as const;
|
||||
export type ClientMessageKind = (typeof CLIENT_MESSAGE_KINDS)[number];
|
||||
|
||||
export type ClientMessage =
|
||||
@@ -35,6 +35,15 @@ export type ClientMessage =
|
||||
*/
|
||||
| { readonly v: 1; readonly kind: 'start'; readonly language?: PageLanguage }
|
||||
| { readonly v: 1; readonly kind: 'stop' }
|
||||
/**
|
||||
* Starts the simulation anew (not Java's: there one stops and starts, and
|
||||
* the data exchange tables and the desktops' windows outlive it): a running
|
||||
* one is stopped as by `stop` — what the devices wrote stays in the
|
||||
* document — then every card's capture, the dropped frames and every
|
||||
* program window are emptied, and it starts as by `start`. From the design
|
||||
* it only starts, emptied as well.
|
||||
*/
|
||||
| { readonly v: 1; readonly kind: 'restart'; readonly language?: PageLanguage }
|
||||
/** Java's speed slider, 1 to 100 per cent: how long a frame takes over a cable. */
|
||||
| { readonly v: 1; readonly kind: 'speed'; readonly value: number }
|
||||
/** Java's "Pakete verwerfen" pressed (on) or let go: every cable drops what it carries while any client holds it. */
|
||||
@@ -80,7 +89,7 @@ export interface DroppedUnit {
|
||||
export const ERROR_CODES = ['badMessage', 'badVersion', 'unknownKind', 'badTopic', 'notRunning', 'unknownNode', 'unknownApp', 'unknownAction', 'badArgs', 'engineFailed', 'readOnly', 'frozen'] as const;
|
||||
|
||||
/** What a client sends that changes the room: only with a write grant (plan §6.4); a reader subscribes. */
|
||||
export const WRITING_KINDS: readonly ClientMessageKind[] = ['start', 'stop', 'speed', 'drop', 'clearCapture', 'input'];
|
||||
export const WRITING_KINDS: readonly ClientMessageKind[] = ['start', 'stop', 'restart', 'speed', 'drop', 'clearCapture', 'input'];
|
||||
export type ErrorCode = (typeof ERROR_CODES)[number];
|
||||
|
||||
export type HostMessage =
|
||||
@@ -160,9 +169,12 @@ export function parseClientMessage(value: unknown): Parsed<ClientMessage> {
|
||||
return { message: { v: 1, kind: kind as 'sub' | 'unsub', topics: topics as Topic[] } };
|
||||
}
|
||||
case 'start':
|
||||
if (value.language === undefined) return { message: { v: 1, kind: 'start' } };
|
||||
case 'restart': {
|
||||
const starting = kind as 'start' | 'restart';
|
||||
if (value.language === undefined) return { message: { v: 1, kind: starting } };
|
||||
if (value.language !== 'de' && value.language !== 'en') return bad('badMessage', `language ${String(value.language)}`);
|
||||
return { message: { v: 1, kind: 'start', language: value.language } };
|
||||
return { message: { v: 1, kind: starting, language: value.language } };
|
||||
}
|
||||
case 'stop':
|
||||
return { message: { v: 1, kind: 'stop' } };
|
||||
case 'clearCapture':
|
||||
|
||||
Reference in New Issue
Block a user