Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Devkit, devtools and developer experience improvements #796

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion devtools/web/src/components/palette/palette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class Wasm4Palette extends LitElement {
${this.heading && html`<h4>${this.heading}</h4>`}
<div class="palette-grid">
${this.palette.slice(0, 4).map((color) => {
const colorHex = formatColor(color);
const colorHex = formatColor(color & 0xffffff);

const shouldInvertColor =
((color & 0xff) + ((color >> 8) & 0xff) + (color >> 16)) / 3 > 128;
Expand Down
21 changes: 12 additions & 9 deletions devtools/web/src/devtools-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ interface RuntimeInfo {
wasmBufferByteLen: number;
}

const INTER_FRAME_TIME_BUFFER_SIZE = 30;
export class DevtoolsManager {
/**
* @private
Expand All @@ -58,17 +59,19 @@ export class DevtoolsManager {
*/
private _bufferedData = new BufferedRuntimeData();

private _fpsBuffer : number[] = [0,0,0,0,0,0,0,0,0,0];
private _interFrameTimeBuffer : number[] = new Array(INTER_FRAME_TIME_BUFFER_SIZE).fill(1000/60);
private _fpsBufferIdx = 0;
//calculate an average FPS for the last 10 frames
private _calcAvgFPS = () => {
let sum = this._fpsBuffer[0];
for (let i = 1; i < 10; i++)
sum += this._fpsBuffer[i];
return Math.floor(sum / 10);
let totalFramesTimeMs = this._interFrameTimeBuffer[0];
for (let i = 1; i < INTER_FRAME_TIME_BUFFER_SIZE; i++)
totalFramesTimeMs += this._interFrameTimeBuffer[i];
return Math.round(INTER_FRAME_TIME_BUFFER_SIZE * 1000 / totalFramesTimeMs);
}
private _nextFPSBufferIdx = () => {
(this._fpsBufferIdx == 9) ? this._fpsBufferIdx = 0 : this._fpsBufferIdx++;
this._fpsBufferIdx++;
if (this._fpsBufferIdx == INTER_FRAME_TIME_BUFFER_SIZE) {
this._fpsBufferIdx = 0;
}
return this._fpsBufferIdx;
}

Expand All @@ -77,10 +80,10 @@ export class DevtoolsManager {
*/
updateCompleted = <Info extends RuntimeInfo>(
runtimeInfo: Info,
deltaFrame: number
interFrameTime: number
) => {
if (this._enabled) {
this._fpsBuffer[this._nextFPSBufferIdx()] = 1_000 / deltaFrame;
this._interFrameTimeBuffer[this._nextFPSBufferIdx()] = interFrameTime;
this._bufferedData.update(runtimeInfo.data);
this._notifyUpdateCompleted(
runtimeInfo.data,
Expand Down
7 changes: 7 additions & 0 deletions runtimes/web/src/config-constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** True if the runtime is in Game Developer mode, with access to the devtools window. */
// WASM4_GAMEDEV_MODE is defined in vite.config.ts
export const GAMEDEV_MODE = WASM4_GAMEDEV_MODE;

/** True if we're developers of the WASM4 runtime itself, and are running the runtime
using `npm start` or `vite` etc. */
export const PLATFORM_DEVELOPER_MODE = import.meta.env.MODE === "development";
1 change: 0 additions & 1 deletion runtimes/web/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export const GAMEDEV_MODE = WASM4_GAMEDEV_MODE;
export const WIDTH = 160;
export const HEIGHT = 160;

Expand Down
8 changes: 6 additions & 2 deletions runtimes/web/src/devkit.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import * as constants from "./constants";
export const websocket = constants.GAMEDEV_MODE
import { GAMEDEV_MODE, PLATFORM_DEVELOPER_MODE } from "./config-constants";

// The w4 CLI web socket only exists for gamedev mode.
// But if we're running `npm start` or `vite` there is no w4 CLI to connect to,
// but there is a vite websocket we may be fighting for, causing issues with vite.
export const cli_websocket = GAMEDEV_MODE && !PLATFORM_DEVELOPER_MODE
? new WebSocket((location.protocol == "https:" ? "wss" : "ws") + "://" + location.host)
: null;
7 changes: 4 additions & 3 deletions runtimes/web/src/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Framebuffer } from "./framebuffer";
import { WebGLCompositor } from "./compositor";
import * as devkit from "./devkit";
import { wasmPatchExportGlobals } from "./wasm-patch";
import * as configConstants from "./config-constants";

export class Runtime {
canvas: HTMLCanvasElement;
Expand Down Expand Up @@ -120,7 +121,7 @@ export class Runtime {
this.wasm = null;

if (wasmBuffer.byteLength > limit) {
if (constants.GAMEDEV_MODE) {
if (configConstants.GAMEDEV_MODE) {
if (!this.warnedFileSize) {
this.warnedFileSize = true;
this.print(`Warning: Cart is larger than ${limit} bytes. Ensure the release build of your cart is small enough to be bundled.`);
Expand Down Expand Up @@ -262,8 +263,8 @@ export class Runtime {
}

printToServer (str: string) {
if (devkit.websocket != null && devkit.websocket.readyState == 1) {
devkit.websocket.send(str);
if (devkit.cli_websocket != null && devkit.cli_websocket.readyState == 1) {
devkit.cli_websocket.send(str);
}
}

Expand Down
10 changes: 5 additions & 5 deletions runtimes/web/src/ui/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LitElement, html, css } from "lit";
import { customElement, state, query } from 'lit/decorators.js';

import * as constants from "../constants";
import * as configConstants from "../config-constants";
import * as devkit from "../devkit";
import * as utils from "./utils";
import * as z85 from "../z85";
Expand Down Expand Up @@ -141,7 +142,7 @@ export class App extends LitElement {
// Nothing
},
};
if (constants.GAMEDEV_MODE) {
if (configConstants.GAMEDEV_MODE) {
devtoolsManager = await import('@wasm4/web-devtools').then(({ DevtoolsManager}) => new DevtoolsManager());
}

Expand All @@ -153,8 +154,8 @@ export class App extends LitElement {
this.copyNetplayLink();
}

if (constants.GAMEDEV_MODE) {
devkit.websocket?.addEventListener("message", async event => {
if (configConstants.GAMEDEV_MODE) {
devkit.cli_websocket?.addEventListener("message", async event => {
switch (event.data) {
case "reload":
this.resetCart(await loadCartWasm());
Expand Down Expand Up @@ -481,8 +482,7 @@ export class App extends LitElement {

runtime.composite();

if (constants.GAMEDEV_MODE) {
// FIXED(2023-12-13): Pass the correct FPS for display
if (configConstants.GAMEDEV_MODE) {
devtoolsManager.updateCompleted(runtime, timeFrameStart - lastTimeFrameStart);
lastTimeFrameStart = timeFrameStart;
}
Expand Down
Loading