Skip to content

Commit 540ab5d

Browse files
committed
Merges all per port emulator events into 1 event with a port argument
1 parent ba63d05 commit 540ab5d

File tree

6 files changed

+70
-146
lines changed

6 files changed

+70
-146
lines changed

src/app/pages/editor-page/editor-page.component.html

+9-6
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
</as-split-area>
1515
<as-split-area size="45">
1616
<as-split>
17-
<app-panel title="Terminal" as-split-area>
18-
<app-terminal #terminal (input)="emulator.sendTerminal($event)" />
19-
</app-panel>
20-
<app-panel title="Controller log" as-split-area>
21-
<app-terminal #controller (input)="emulator.sendTerminal($event)" />
17+
<app-panel title="Console" as-split-area>
18+
<app-terminal
19+
#terminal
20+
(input)="emulator.sendPort(Port.Console, $event)"
21+
/>
2222
</app-panel>
2323
<app-panel title="Screen log" as-split-area>
24-
<app-terminal #screen (input)="emulator.sendTerminal($event)" />
24+
<app-terminal #screen />
25+
</app-panel>
26+
<app-panel title="Controller log" as-split-area>
27+
<app-terminal #controller />
2528
</app-panel>
2629
</as-split>
2730
</as-split-area>

src/app/pages/editor-page/editor-page.component.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { EmulatorService } from '../../../vm/emulator.service';
66
import { ExecutorService } from '../../../vm/executor.service';
77
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
88
import { PanelComponent } from '../../components/panel/panel.component';
9+
import { Port } from '../../../utils/literalConstants';
910

1011
@Component({
1112
selector: 'app-editor-page',
@@ -36,21 +37,19 @@ export class EditorPageComponent {
3637
executor.output.pipe(takeUntilDestroyed(destroyRef)).subscribe((value) => {
3738
this.output += value;
3839
});
39-
emulator.receivedOutputScreen
40+
emulator.receivedOutput
4041
.pipe(takeUntilDestroyed(destroyRef))
41-
.subscribe((value) => {
42-
this.screen.write(value);
43-
});
44-
emulator.receivedOutputController //TODO: need feature parity with the old version
45-
.pipe(takeUntilDestroyed(destroyRef))
46-
.subscribe((value) => {
47-
this.controller.write(value.replace(/[\u0000\n]/, '\r\n'));
48-
});
49-
50-
emulator.receivedOutputConsole
51-
.pipe(takeUntilDestroyed(destroyRef))
52-
.subscribe((value) => {
53-
this.terminal.write(value);
42+
.subscribe(([port, value]) => {
43+
switch (port) {
44+
case Port.Console:
45+
return this.terminal.write(value);
46+
case Port.Screen:
47+
return this.screen.write(value);
48+
case Port.Controller: //TODO: need feature parity with the old version for controller pretty print
49+
return this.controller.write(value.replace(/[\u0000\n]/, '\r\n'));
50+
}
5451
});
5552
}
53+
54+
protected readonly Port = Port;
5655
}

src/utils/literalConstants.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
11
export const vmRemoteUrlSearchParameter = 'vmRemoteUrl';
2+
3+
export enum Port {
4+
Console,
5+
Screen,
6+
Controller,
7+
}

src/vm/commandQueue.service.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Injectable } from '@angular/core';
22
import { EmulatorService } from './emulator.service';
33
import { Process } from './process';
4+
import { Port } from '../utils/literalConstants';
45

56
export interface CommandResultOK<C extends Command> {
67
status: 'OK';
@@ -73,7 +74,9 @@ export class CommandQueueService {
7374
public constructor(public emulator: EmulatorService) {
7475
//It's called from window.setTimeout so this is window otherwise
7576
this.tickQueue = this.tickQueue.bind(this);
76-
emulator.receivedOutputController.subscribe((data) => {
77+
emulator.receivedOutput.subscribe(([port, data]) => {
78+
if (port != Port.Controller) return;
79+
7780
for (const chr of data) {
7881
//TODO: Rewrite the receive function to receive chunks instead of character by character
7982
try {
@@ -172,7 +175,7 @@ export class CommandQueueService {
172175

173176
this.activeCommand = command;
174177

175-
this.emulator.sendController(cmdStr + '\0');
178+
this.emulator.sendPort(Port.Controller, cmdStr + '\0');
176179
}
177180

178181
/**

src/vm/emulator.service.ts

+10-20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { EventEmitter, Injectable, Output } from '@angular/core';
2-
import type { WorkerMsgWithoutCID, WorkerResponseMsg } from './emulator.worker';
2+
import type {
3+
MsgSendPort,
4+
WorkerMsgWithoutCID,
5+
WorkerResponseMsg,
6+
} from './emulator.worker';
37
import { environment } from '../environments/environment';
4-
import { vmRemoteUrlSearchParameter } from '../utils/literalConstants';
8+
import { Port, vmRemoteUrlSearchParameter } from '../utils/literalConstants';
59

610
const encoder = new TextEncoder();
711

@@ -12,11 +16,7 @@ export class EmulatorService {
1216
@Output()
1317
public resetOutputConsole = new EventEmitter<void>();
1418
@Output()
15-
public receivedOutputConsole = new EventEmitter<string>();
16-
@Output()
17-
public receivedOutputScreen = new EventEmitter<string>();
18-
@Output()
19-
public receivedOutputController = new EventEmitter<string>();
19+
public receivedOutput = new EventEmitter<[Port, string]>();
2020

2121
private worker;
2222

@@ -38,7 +38,7 @@ export class EmulatorService {
3838
if (e.event === 'resetOutputConsole')
3939
return this.resetOutputConsole.emit();
4040

41-
return this[e.event].emit(...(e.data ?? []));
41+
return this[e.event].emit(e.data);
4242
}
4343

4444
const callback = this.asyncCallbacks.get(e.commandID);
@@ -70,16 +70,9 @@ export class EmulatorService {
7070
);
7171
}
7272

73-
public sendTerminal(data: string) {
74-
this.sendCommand({ command: 'sendTerminal', data });
75-
}
76-
public sendScreen(data: string) {
77-
this.sendCommand({ command: 'sendScreen', data });
73+
public sendPort(...data: MsgSendPort['data']) {
74+
this.sendCommand({ command: 'sendPort', data });
7875
}
79-
public sendController(data: string) {
80-
this.sendCommand({ command: 'sendController', data });
81-
}
82-
8376
public pause() {
8477
return this.sendCommandAsync({ command: 'pause' });
8578
}
@@ -94,7 +87,4 @@ export class EmulatorService {
9487
data: new Uint8Array(content),
9588
});
9689
}
97-
public resetTerminal() {
98-
this.sendCommand({ command: 'resetTerminal' });
99-
}
10090
}

src/vm/emulator.worker.ts

+27-104
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,31 @@
11
/// <reference lib="webworker" />
2-
import { vmRemoteUrlSearchParameter } from '../utils/literalConstants';
2+
import { Port, vmRemoteUrlSearchParameter } from '../utils/literalConstants';
33

44
importScripts('./lib/libv86.js');
55

6-
interface MsgSendTerminal {
7-
command: 'sendTerminal';
8-
data: string;
6+
export interface MsgSendPort {
7+
command: 'sendPort';
8+
data: [Port, string];
99
}
10-
interface MsgSendScreen {
11-
command: 'sendScreen';
12-
data: string;
13-
}
14-
interface MsgSendController {
15-
command: 'sendController';
16-
data: string;
17-
}
18-
interface MsgStart {
10+
export interface MsgStart {
1911
command: 'start';
2012
data?: undefined;
2113
}
22-
interface MsgPause {
14+
export interface MsgPause {
2315
command: 'pause';
2416
data?: undefined;
2517
}
26-
interface MsgSendFile {
18+
export interface MsgSendFile {
2719
command: 'sendFile';
2820
name: string;
2921
data: Uint8Array;
3022
}
31-
interface MsgResetTerminal {
32-
command: 'resetTerminal';
33-
data?: undefined;
34-
}
3523

3624
export type WorkerMsgWithoutCID =
37-
| MsgSendTerminal
38-
| MsgSendScreen
39-
| MsgSendController
25+
| MsgSendPort
4026
| MsgStart
4127
| MsgPause
42-
| MsgSendFile
43-
| MsgResetTerminal;
28+
| MsgSendFile;
4429

4530
export type WorkerMsg = WorkerMsgWithoutCID & {
4631
commandID: number;
@@ -55,16 +40,8 @@ export type WorkerResponseMsg =
5540

5641
export type WorkerEventResponseMsg =
5742
| {
58-
event: 'receivedOutputConsole';
59-
data: [string];
60-
}
61-
| {
62-
event: 'receivedOutputScreen';
63-
data: [string];
64-
}
65-
| {
66-
event: 'receivedOutputController';
67-
data: [string];
43+
event: 'receivedOutput';
44+
data: [Port, string];
6845
}
6946
| {
7047
event: 'resetOutputConsole';
@@ -152,41 +129,13 @@ const emulator = new V86({
152129
virtio_console: true,
153130
});
154131

155-
//@ts-ignore
156-
self.emulator = emulator;
157-
158-
let resetting = false;
159-
160-
function sendTerminal(message: string) {
161-
emulator.bus.send(
162-
'virtio-console0-input-bytes',
163-
[...message].map((x) => x.charCodeAt(0)),
164-
);
165-
}
166-
function sendScreen(message: string) {
167-
emulator.bus.send(
168-
'virtio-console1-input-bytes',
169-
[...message].map((x) => x.charCodeAt(0)),
170-
);
171-
}
172-
function sendController(message: string) {
173-
emulator.bus.send(
174-
'virtio-console2-input-bytes',
175-
[...message].map((x) => x.charCodeAt(0)),
176-
);
177-
}
178132
onmessage = ({ data: e }: MessageEvent<WorkerMsg>) => {
179133
switch (e.command) {
180-
case 'sendTerminal': {
181-
sendTerminal(e.data);
182-
break;
183-
}
184-
case 'sendScreen': {
185-
sendScreen(e.data);
186-
break;
187-
}
188-
case 'sendController': {
189-
sendController(e.data);
134+
case 'sendPort': {
135+
emulator.bus.send(
136+
`virtio-console${e.data[0]}-input-bytes`,
137+
[...e.data[1]].map((x) => x.charCodeAt(0)),
138+
);
190139
break;
191140
}
192141
case 'start': {
@@ -216,43 +165,17 @@ onmessage = ({ data: e }: MessageEvent<WorkerMsg>) => {
216165
});
217166
break;
218167
}
219-
case 'resetTerminal': {
220-
if (!emulator.is_running()) return;
221-
if (resetting) return;
222-
resetting = true;
223-
const uart0: {
224-
lsr: number;
225-
} = emulator.v86.cpu.devices.uart0;
226-
uart0.lsr |= 0b00010000;
227-
setTimeout(() => {
228-
sendTerminal(' ');
229-
setTimeout(() => {
230-
uart0.lsr &= ~0b00010000;
231-
sendTerminal('k');
232-
postMessage({ event: 'resetOutputConsole' });
233-
sendTerminal('\n');
234-
resetting = false;
235-
}, 1);
236-
}, 1);
237-
}
238168
}
239169
};
240170

241-
emulator.add_listener('virtio-console0-output-bytes', (bytes: Uint8Array) => {
242-
postMessage({
243-
event: 'receivedOutputConsole',
244-
data: [decoder.decode(bytes)],
245-
});
246-
});
247-
emulator.add_listener('virtio-console1-output-bytes', (bytes: Uint8Array) => {
248-
postMessage({
249-
event: 'receivedOutputScreen',
250-
data: [decoder.decode(bytes)],
251-
});
252-
});
253-
emulator.add_listener('virtio-console2-output-bytes', (bytes: Uint8Array) => {
254-
postMessage({
255-
event: 'receivedOutputController',
256-
data: [decoder.decode(bytes)],
257-
});
258-
});
171+
for (let i = 0; i < 3; i++) {
172+
emulator.add_listener(
173+
`virtio-console${i}-output-bytes`,
174+
(bytes: Uint8Array) => {
175+
postMessage({
176+
event: 'receivedOutput',
177+
data: [i, decoder.decode(bytes)],
178+
});
179+
},
180+
);
181+
}

0 commit comments

Comments
 (0)