Skip to content

Commit 379ff66

Browse files
committed
Implement async using workers
1 parent a71e743 commit 379ff66

File tree

8 files changed

+556
-179
lines changed

8 files changed

+556
-179
lines changed

EventWorker.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Adapted from https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#passing_data_examples
2+
export default class EventWorker {
3+
#worker;
4+
#listeners;
5+
6+
constructor(scriptUrl, options) {
7+
this.#worker = new Worker(scriptUrl, options);
8+
this.#listeners = {};
9+
this.#worker.onmessage = (event) => {
10+
if (
11+
event.data instanceof Object &&
12+
Object.hasOwn(event.data, "event") &&
13+
Object.hasOwn(event.data, "message")
14+
) {
15+
this.#listeners[event.data.event].apply(
16+
this,
17+
event.data.message,
18+
);
19+
} else {
20+
console.error(event);
21+
throw new TypeError("EventWorker got illegal event");
22+
}
23+
};
24+
this.#worker.onmessageerror = (event) => {
25+
console.error("[MAIN] onmessageerror:", event);
26+
throw new Error(event);
27+
}
28+
this.#worker.onerror = (event) => {
29+
console.error("[MAIN] onerror:", event);
30+
throw new Error(event);
31+
}
32+
}
33+
34+
terminate() {
35+
this.#worker.terminate();
36+
this.#worker = null;
37+
}
38+
39+
setListener(name, handler) {
40+
this.#listeners[name] = handler;
41+
}
42+
43+
removeListener(name) {
44+
delete this.#listeners[name];
45+
}
46+
47+
send(event, ...message) {
48+
if (!event) {
49+
throw new TypeError("EventWorker.send takes at least one argument");
50+
}
51+
this.#worker.postMessage({
52+
event,
53+
message,
54+
});
55+
}
56+
}
57+
58+
/**
59+
* @param {Record<string, WorkerHandler>} handlers
60+
* @typedef {(this: typeof self, ...message: any[])} WorkerHandler
61+
*/
62+
export function registerWorkerEvents(handlers) {
63+
onmessage = (event) => {
64+
if (
65+
event.data instanceof Object &&
66+
Object.hasOwn(event.data, "event") &&
67+
Object.hasOwn(event.data, "message")
68+
) {
69+
handlers[event.data.event].apply(self, event.data.message);
70+
} else {
71+
console.error(event);
72+
throw new TypeError("Illegal postMessage!");
73+
}
74+
};
75+
onmessageerror = (event) => {
76+
console.error("[WORKER] onmessageerror:", event);
77+
};
78+
onerror = (event) => {
79+
console.error("[WORKER] error:", event);
80+
};
81+
}
82+
83+
export function reply(event, ...message) {
84+
if (!event) {
85+
throw new TypeError("reply - not enough arguments");
86+
}
87+
postMessage({
88+
event,
89+
message,
90+
});
91+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*******************************************************************************************
2+
*
3+
* raylib [shapes] example - Colors palette
4+
*
5+
* Example originally created with raylib 1.0, last time updated with raylib 2.5
6+
*
7+
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
8+
* BSD-like license that allows static linking with closed source software
9+
*
10+
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
11+
*
12+
********************************************************************************************/
13+
14+
#include "raylib.h"
15+
16+
#define MAX_COLORS_COUNT 21 // Number of colors available
17+
18+
//------------------------------------------------------------------------------------
19+
// Program main entry point
20+
//------------------------------------------------------------------------------------
21+
int main(void)
22+
{
23+
// Initialization
24+
//--------------------------------------------------------------------------------------
25+
const int screenWidth = 800;
26+
const int screenHeight = 450;
27+
28+
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - colors palette");
29+
30+
Color colors[MAX_COLORS_COUNT] = {
31+
DARKGRAY, MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, DARKBROWN,
32+
GRAY, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, YELLOW,
33+
GREEN, SKYBLUE, PURPLE, BEIGE };
34+
35+
const char *colorNames[MAX_COLORS_COUNT] = {
36+
"DARKGRAY", "MAROON", "ORANGE", "DARKGREEN", "DARKBLUE", "DARKPURPLE",
37+
"DARKBROWN", "GRAY", "RED", "GOLD", "LIME", "BLUE", "VIOLET", "BROWN",
38+
"LIGHTGRAY", "PINK", "YELLOW", "GREEN", "SKYBLUE", "PURPLE", "BEIGE" };
39+
40+
Rectangle colorsRecs[MAX_COLORS_COUNT] = { 0 }; // Rectangles array
41+
42+
// Fills colorsRecs data (for every rectangle)
43+
for (int i = 0; i < MAX_COLORS_COUNT; i++)
44+
{
45+
colorsRecs[i].x = 20.0f + 100.0f *(i%7) + 10.0f *(i%7);
46+
colorsRecs[i].y = 80.0f + 100.0f *(i/7) + 10.0f *(i/7);
47+
colorsRecs[i].width = 100.0f;
48+
colorsRecs[i].height = 100.0f;
49+
}
50+
51+
int colorState[MAX_COLORS_COUNT] = { 0 }; // Color state: 0-DEFAULT, 1-MOUSE_HOVER
52+
53+
Vector2 mousePoint = { 0.0f, 0.0f };
54+
55+
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
56+
//--------------------------------------------------------------------------------------
57+
58+
// Main game loop
59+
while (!WindowShouldClose()) // Detect window close button or ESC key
60+
{
61+
// Update
62+
//----------------------------------------------------------------------------------
63+
mousePoint = GetMousePosition();
64+
65+
for (int i = 0; i < MAX_COLORS_COUNT; i++)
66+
{
67+
if (CheckCollisionPointRec(mousePoint, colorsRecs[i])) colorState[i] = 1;
68+
else colorState[i] = 0;
69+
}
70+
//----------------------------------------------------------------------------------
71+
72+
// Draw
73+
//----------------------------------------------------------------------------------
74+
BeginDrawing();
75+
76+
ClearBackground(RAYWHITE);
77+
78+
DrawText("raylib colors palette", 28, 42, 20, BLACK);
79+
DrawText("press SPACE to see all colors", GetScreenWidth() - 180, GetScreenHeight() - 40, 10, GRAY);
80+
81+
for (int i = 0; i < MAX_COLORS_COUNT; i++) // Draw all rectangles
82+
{
83+
DrawRectangleRec(colorsRecs[i], Fade(colors[i], colorState[i]? 0.6f : 1.0f));
84+
85+
if (IsKeyDown(KEY_SPACE) || colorState[i])
86+
{
87+
DrawRectangle((int)colorsRecs[i].x, (int)(colorsRecs[i].y + colorsRecs[i].height - 26), (int)colorsRecs[i].width, 20, BLACK);
88+
DrawRectangleLinesEx(colorsRecs[i], 6, Fade(BLACK, 0.3f));
89+
DrawText(colorNames[i], (int)(colorsRecs[i].x + colorsRecs[i].width - MeasureText(colorNames[i], 10) - 12),
90+
(int)(colorsRecs[i].y + colorsRecs[i].height - 20), 10, colors[i]);
91+
}
92+
}
93+
94+
EndDrawing();
95+
//----------------------------------------------------------------------------------
96+
}
97+
98+
// De-Initialization
99+
//--------------------------------------------------------------------------------------
100+
CloseWindow(); // Close window and OpenGL context
101+
//--------------------------------------------------------------------------------------
102+
103+
return 0;
104+
}

index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
src: url(fonts/acme_7_wide_xtnd.woff);
5858
}
5959
</style>
60-
<script src="raylib.js"></script>
60+
<script src="raylib-wrapper.js"></script>
6161
</head>
6262
<body>
6363
<label for="raylib-example-select">Choose an Example:</label>
@@ -69,7 +69,7 @@
6969
const wasmPaths = {
7070
"tsoding": ["tsoding_ball", "tsoding_snake",],
7171
"core": ["core_basic_window", "core_basic_screen_manager", "core_input_keys", "core_input_mouse_wheel",],
72-
"shapes": ["shapes_colors_palette"],
72+
"shapes": ["shapes_colors_palette", "shapes_colors_palette_async"],
7373
"text": ["text_writing_anim"],
7474
"textures": ["textures_logo_raylib"],
7575
}

nob.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ Example examples[] = {
2828
.bin_path = "./build/shapes_colors_palette",
2929
.wasm_path = "./wasm/shapes_colors_palette.wasm",
3030
},
31+
{
32+
.src_path = "./examples/shapes_colors_palette_async.c",
33+
.bin_path = "./build/shapes_colors_palette_async",
34+
.wasm_path = "./wasm/shapes_colors_palette_async.wasm",
35+
},
3136
{
3237
.src_path = "./examples/tsoding_ball.c",
3338
.bin_path = "./build/tsoding_ball",

0 commit comments

Comments
 (0)