Skip to content

Commit

Permalink
Merge pull request #796 from majaha/devkit-and-devtools
Browse files Browse the repository at this point in the history
Devkit, devtools and developer experience improvements
  • Loading branch information
aduros authored Jan 2, 2025
2 parents 94e8e9f + 77d2110 commit fa5b273
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 21 deletions.
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

0 comments on commit fa5b273

Please sign in to comment.