Skip to content

Commit

Permalink
Locking implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
x0k committed Feb 22, 2024
1 parent 1f23219 commit a54d235
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 17 deletions.
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
case IMPL.GAME_FRAME:
return `wasm/${example}.wasm`
case IMPL.BLOCKING:
case IMPL.LOCKING:
return `wasm/${example}.native.wasm`
}
}
Expand Down Expand Up @@ -239,7 +240,8 @@

const impls = {
[IMPL.GAME_FRAME]: "game frame",
[IMPL.BLOCKING]: "blocking"
[IMPL.BLOCKING]: "blocking",
[IMPL.LOCKING]: "locking",
}
const defaultImpl = IMPL.GAME_FRAME
const raylibImplSelect = document.getElementById("raylib-impl-select");
Expand Down
17 changes: 17 additions & 0 deletions raylib.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,23 @@ export class BlockingRaylibJs extends RaylibJsBase {

}


export class LockingRaylibJs extends BlockingRaylibJs {
constructor(canvas, platform, eventsQueue, statusBuffer) {
super(canvas, platform, eventsQueue);
this.status = new Int32Array(statusBuffer);
}

BeginDrawing() {
Atomics.wait(this.status, 0, 0);
this.eventsQueue.pop(this.handleEvent)
const now = performance.now();
this.dt = (now - this.previous)/1000.0;
this.previous = now;
}

}

export const glfwKeyMapping = {
"Space": 32,
"Quote": 39,
Expand Down
9 changes: 8 additions & 1 deletion raylib_factory.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { BlockingRaylibJs, RaylibJs } from './raylib.js'
import { BlockingRaylibJs, RaylibJs, LockingRaylibJs } from './raylib.js'

export const IMPL = {
GAME_FRAME: "gameFrame",
BLOCKING: "blocking",
LOCKING: "locking",
}

export const RENDERING_CTX = {
Expand All @@ -23,6 +24,7 @@ export function createRaylib({
platform,
rendering,
eventsQueue,
statusBuffer,
}) {
switch (impl) {
case IMPL.GAME_FRAME: {
Expand All @@ -34,6 +36,11 @@ export function createRaylib({
const ctx = remoteContextFactories[rendering](canvas)
return new BlockingRaylibJs(ctx, platform, eventsQueue)
}
case IMPL.LOCKING: {
const canvas = new OffscreenCanvas(0, 0)
const ctx = remoteContextFactories[rendering](canvas)
return new LockingRaylibJs(ctx, platform, eventsQueue, statusBuffer)
}
default:
throw new Error(`Unknown impl: ${impl}`)
}
Expand Down
70 changes: 55 additions & 15 deletions raylib_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,14 @@ function makePlatform({ self, impl, rendering, renderer, rendererPort }) {
family,
fileName,
})
}
},
[IMPL.LOCKING]: (family, fileName) => {
self.postMessage({
type: RESPONSE_MESSAGE_TYPE.LOAD_FONT,
family,
fileName,
})
},
}[impl]
const render = {
[RENDERING_CTX.DD]: (ctx) => {
Expand Down Expand Up @@ -118,7 +125,8 @@ export function makeWorkerMessagesHandler(self) {
rendering,
renderer,
rendererPort,
eventsBuffer
eventsBuffer,
statusBuffer,
}) => {
if (raylibJs) {
raylibJs.stop()
Expand All @@ -135,6 +143,7 @@ export function makeWorkerMessagesHandler(self) {
}),
rendering,
eventsQueue: new EventsQueue(eventsBuffer),
statusBuffer,
})
}
handlers[REQUEST_MESSAGE_TYPE.START] = async ({ params }) => {
Expand Down Expand Up @@ -254,7 +263,7 @@ export class RaylibJsWorker {
this.rendererWorker = rendererWorker
// For manage event commits
this.impl = impl
this.nextCommitId = undefined
this.animationFrameId = undefined
this.startPromise = undefined
this.onStartSuccess = undefined
this.onStartFail = undefined
Expand Down Expand Up @@ -298,14 +307,25 @@ export class RaylibJsWorker {
this.eventsSender = {
[IMPL.GAME_FRAME]: (event) => this.worker.postMessage(event),
[IMPL.BLOCKING]: (event) => this.eventsQueue.push(event),
[IMPL.LOCKING]: (event) => this.eventsQueue.push(event),
}[impl]

const statusBuffer = window.SharedArrayBuffer
? new SharedArrayBuffer(4)
: new ArrayBuffer(4)
this.status = new Int32Array(statusBuffer)

const channel = new MessageChannel()
// https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
const offscreen = {
[IMPL.GAME_FRAME]: () => canvas.transferControlToOffscreen(),
[IMPL.BLOCKING]: () => {
switch (renderer) {
let offscreen = undefined
switch (impl) {
case IMPL.GAME_FRAME: {
offscreen = canvas.transferControlToOffscreen()
break
}
case IMPL.LOCKING:
case IMPL.BLOCKING: {
switch (renderer) {
case RENDERER.MAIN_THREAD: {
this.handlers[RESPONSE_MESSAGE_TYPE.UPDATE_WINDOW] = ({ title, width, height }) => {
platform.updateWindow(title, width, height)
Expand All @@ -330,14 +350,18 @@ export class RaylibJsWorker {
throw new Error(`Unknown renderer: ${renderer}`)
}
// Fake canvas to measure the text in worker thread
return new OffscreenCanvas(800, 600)
}
}[impl]()
offscreen = new OffscreenCanvas(800, 600)
break
}
default:
throw new Error(`Unknown impl: ${impl}`)
}
this.worker.addEventListener("message", this.handleMessage)
this.worker.postMessage({
type: REQUEST_MESSAGE_TYPE.INIT,
canvas: offscreen,
eventsBuffer,
statusBuffer,
rendering,
impl,
renderer,
Expand All @@ -361,19 +385,35 @@ export class RaylibJsWorker {
type: REQUEST_MESSAGE_TYPE.START,
params
})
if (this.impl === IMPL.BLOCKING) {
switch (this.impl) {
case IMPL.BLOCKING: {
const commitEvents = () => {
this.eventsQueue.commit()
this.animationFrameId = requestAnimationFrame(commitEvents)
}
this.animationFrameId = requestAnimationFrame(commitEvents)
break
}
case IMPL.LOCKING: {
const commitEvents = () => {
this.eventsQueue.commit()
this.nextCommitId = requestAnimationFrame(commitEvents)
Atomics.notify(this.status, 0)
this.animationFrameId = requestAnimationFrame(commitEvents)
}
this.nextCommitId = requestAnimationFrame(commitEvents)
this.animationFrameId = requestAnimationFrame(commitEvents)
break
}
}
return this.startPromise
}

stop() {
if (this.impl === IMPL.BLOCKING) {
cancelAnimationFrame(this.nextCommitId)
switch (this.impl) {
case IMPL.BLOCKING:
case IMPL.LOCKING: {
cancelAnimationFrame(this.animationFrameId)
break
}
}
this.eventsSender({
type: REQUEST_MESSAGE_TYPE.STOP,
Expand Down

0 comments on commit a54d235

Please sign in to comment.