make the webworker typed for type safety
This commit is contained in:
parent
e58a765cfa
commit
c8f9c9d9ea
2 changed files with 50 additions and 29 deletions
|
@ -3,8 +3,10 @@ import { GetKeySym } from "./key";
|
||||||
import { MouseState } from "./mouse";
|
import { MouseState } from "./mouse";
|
||||||
import {
|
import {
|
||||||
PlayerConfiguredMessage,
|
PlayerConfiguredMessage,
|
||||||
|
PlayerInputMessage,
|
||||||
PlayerOutputMessage,
|
PlayerOutputMessage,
|
||||||
} from "./player_worker_messages";
|
} from "./player_worker_messages";
|
||||||
|
import { TypedWorker } from "./typed_worker";
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
private uri: string;
|
private uri: string;
|
||||||
|
@ -21,7 +23,8 @@ class Client {
|
||||||
) as HTMLDivElement;
|
) as HTMLDivElement;
|
||||||
|
|
||||||
private webSocket: WebSocket;
|
private webSocket: WebSocket;
|
||||||
private player: Worker | null = null;
|
private player: TypedWorker<PlayerInputMessage, PlayerOutputMessage> | null =
|
||||||
|
null;
|
||||||
|
|
||||||
private mouse = new MouseState();
|
private mouse = new MouseState();
|
||||||
|
|
||||||
|
@ -127,17 +130,18 @@ class Client {
|
||||||
if (this.player == null) {
|
if (this.player == null) {
|
||||||
let offscreen = this.canvas.transferControlToOffscreen();
|
let offscreen = this.canvas.transferControlToOffscreen();
|
||||||
|
|
||||||
this.player = new Worker(new URL("./player_worker.ts", import.meta.url), {
|
this.player = new TypedWorker<PlayerInputMessage, PlayerOutputMessage>(
|
||||||
|
new URL("./player_worker.ts", import.meta.url),
|
||||||
|
{
|
||||||
type: "module",
|
type: "module",
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this.player.addEventListener(
|
this.player.onMessage = (message: PlayerOutputMessage) => {
|
||||||
"message",
|
switch (message.type) {
|
||||||
(message: MessageEvent<PlayerOutputMessage>) => {
|
|
||||||
switch (message.data.type) {
|
|
||||||
case "configured": {
|
case "configured": {
|
||||||
// set the message
|
// set the message
|
||||||
let configMessage = message.data as PlayerConfiguredMessage;
|
let configMessage = message as PlayerConfiguredMessage;
|
||||||
let hwLabelElement = document.getElementById(
|
let hwLabelElement = document.getElementById(
|
||||||
"hw-label"
|
"hw-label"
|
||||||
) as HTMLSpanElement;
|
) as HTMLSpanElement;
|
||||||
|
@ -155,12 +159,11 @@ class Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
);
|
|
||||||
|
|
||||||
// Send the init message to the worker to give it
|
// Send the init message to the worker to give it
|
||||||
// access to the canvas
|
// access to the canvas
|
||||||
this.player.postMessage(
|
this.player.post(
|
||||||
{
|
{
|
||||||
type: "init",
|
type: "init",
|
||||||
canvas: offscreen,
|
canvas: offscreen,
|
||||||
|
@ -185,13 +188,13 @@ class Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
OnWSOpen() {
|
OnWSOpen() {
|
||||||
this.player?.postMessage({
|
this.player?.post({
|
||||||
type: "init-decoder",
|
type: "init-decoder",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
OnWSClosed() {
|
OnWSClosed() {
|
||||||
this.player?.postMessage({
|
this.player?.post({
|
||||||
type: "shutdown-decoder",
|
type: "shutdown-decoder",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -203,7 +206,7 @@ class Client {
|
||||||
OnWSMessage(ev: MessageEvent<string | ArrayBuffer>) {
|
OnWSMessage(ev: MessageEvent<string | ArrayBuffer>) {
|
||||||
// Video data is binary
|
// Video data is binary
|
||||||
if (typeof ev.data !== "string") {
|
if (typeof ev.data !== "string") {
|
||||||
this.player?.postMessage(
|
this.player?.post(
|
||||||
{
|
{
|
||||||
type: "data",
|
type: "data",
|
||||||
data: ev.data as ArrayBuffer,
|
data: ev.data as ArrayBuffer,
|
||||||
|
|
18
client/src/typed_worker.ts
Normal file
18
client/src/typed_worker.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// It's like Worker but typed.
|
||||||
|
export class TypedWorker<TInput, TOutput> {
|
||||||
|
private worker;
|
||||||
|
public onMessage: null | ((m: TOutput) => void) = null;
|
||||||
|
|
||||||
|
constructor(uri: URL | string, opts?: WorkerOptions) {
|
||||||
|
this.worker = new Worker(uri, opts);
|
||||||
|
let self = this;
|
||||||
|
this.worker.addEventListener("message", (m: MessageEvent<TOutput>) => {
|
||||||
|
if (self.onMessage) self.onMessage(m.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
post<M extends TInput>(msg: M, transfer?: Transferable[]) {
|
||||||
|
if (transfer) this.worker.postMessage(msg, transfer);
|
||||||
|
else this.worker.postMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue