feat(editor): F4.6b the command line on a computer's desktop
A new oracle, TerminalWindowRun, types into Java's own command line window: the window writes each line after its prompt, takes a blank line, cls, reset and exit itself, keeps the lines for the arrow keys, and keeps its text, history and working directory over a stop and a start. The room now holds a command line window per computer for everyone (TerminalWindow), kept over stops; the protocol carries its lines and the one way to read them (terminalScreen); the core goes on in the working directory of the run before (continueIn). The desktop opens programs in Java's frame, and the command line works with keyboard and finger: grey on black, the prompt hidden while a command runs, history, chips for the commands, Ctrl+C. The room's failure is now tested in the browser. Fixed: the room handed the engine the wall clock with fractions of a millisecond, and a ping hung after its first timeout. The engine and the room count whole milliseconds, as Java's clock does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,9 +20,10 @@ import { Palette, type PaletteKind } from './design/Palette.js';
|
||||
import { RouterDialog } from './design/RouterDialog.js';
|
||||
import { DeviceSheet } from './sheet/DeviceSheet.js';
|
||||
import { DesktopWindow } from './desktop/DesktopWindow.js';
|
||||
import type { DesktopProgram } from './desktop/programs.js';
|
||||
import { useTranslate } from './i18n/i18n.js';
|
||||
import { ModeBar } from './simulation/ModeBar.js';
|
||||
import { useSimulation, type Simulation, type SimHostFactory } from './simulation/useSimulation.js';
|
||||
import { useSimulation, type SimHostFactory } from './simulation/useSimulation.js';
|
||||
|
||||
/** The document's drawing, read anew after every change. */
|
||||
export function useTopologyView(doc: Y.Doc): TopologyView {
|
||||
@@ -79,6 +80,7 @@ interface OpenDesktop {
|
||||
readonly x: number;
|
||||
readonly y: number;
|
||||
readonly z: number;
|
||||
readonly program: DesktopProgram | null;
|
||||
}
|
||||
|
||||
/** Brings a desktop to the top by its stacking, not its place in the page: moved in the page, it would lose the press on it. */
|
||||
@@ -87,13 +89,6 @@ const toFront = (open: readonly OpenDesktop[], id: string): readonly OpenDesktop
|
||||
return open.some((each) => each.id === id && each.z === top) ? open : open.map((each) => (each.id === id ? { ...each, z: top + 1 } : each));
|
||||
};
|
||||
|
||||
/** A desktop that watches its computer's network while it is shown. */
|
||||
function WatchedDesktop({ simulation, ...props }: Omit<Parameters<typeof DesktopWindow>[0], 'settings'> & { readonly simulation: Simulation }) {
|
||||
const { watch } = simulation;
|
||||
useEffect(() => watch([`node:${props.id}`]), [watch, props.id]);
|
||||
return <DesktopWindow {...props} settings={simulation.nodes.get(props.id)} />;
|
||||
}
|
||||
|
||||
export function Editor({ doc, createSimHost }: { readonly doc: Y.Doc; readonly createSimHost?: SimHostFactory }) {
|
||||
const t = useTranslate();
|
||||
const view = useTopologyView(doc);
|
||||
@@ -146,7 +141,7 @@ export function Editor({ doc, createSimHost }: { readonly doc: Y.Doc; readonly c
|
||||
setDesktops((open) => {
|
||||
if (open.some((each) => each.id === id)) return toFront(open, id);
|
||||
// Java stacks a desktop that does not fit beside the others a little further on.
|
||||
return [...open, { id, x: 24 + 24 * open.length, y: 76 + 24 * open.length, z: Math.max(0, ...open.map((each) => each.z)) + 1 }];
|
||||
return [...open, { id, x: 24 + 24 * open.length, y: 76 + 24 * open.length, z: Math.max(0, ...open.map((each) => each.z)) + 1, program: null }];
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -305,7 +300,7 @@ export function Editor({ doc, createSimHost }: { readonly doc: Y.Doc; readonly c
|
||||
</div>
|
||||
{simulating
|
||||
? desktops.map((desktop) => (
|
||||
<WatchedDesktop
|
||||
<DesktopWindow
|
||||
key={desktop.id}
|
||||
simulation={simulation}
|
||||
doc={doc}
|
||||
@@ -314,6 +309,8 @@ export function Editor({ doc, createSimHost }: { readonly doc: Y.Doc; readonly c
|
||||
x={desktop.x}
|
||||
y={desktop.y}
|
||||
z={desktop.z}
|
||||
program={desktop.program}
|
||||
onProgram={(program) => setDesktops((open) => open.map((each) => (each.id === desktop.id ? { ...each, program } : each)))}
|
||||
onMove={(x, y) => setDesktops((open) => open.map((each) => (each.id === desktop.id ? { ...each, x, y } : each)))}
|
||||
onFront={() => setDesktops((open) => toFront(open, desktop.id))}
|
||||
onClose={() => setDesktops((open) => open.filter((each) => each.id !== desktop.id))}
|
||||
|
||||
Reference in New Issue
Block a user