Scaffold vpinball-wasm: Emscripten port of Visual Pinball
Build scripts, CMake/source patches, npm packaging, and a Gitea CI workflow to compile the real Visual Pinball engine (SDL3 + WebGL2 + libwinevbs for real VBScript) to WebAssembly. The patches are validated end-to-end: the patched engine boots in a real browser, loads a real .vpx table, compiles its real GLSL shaders, computes environment map radiance, initializes physics, and starts the VBScript engine, before hanging on the one deliberately-deferred piece of work (game loop rewrite around emscripten_set_main_loop), documented in the README's roadmap.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
--- a/third-party/include/ThreadPool.h
|
||||
+++ b/third-party/include/ThreadPool.h
|
||||
@@ -110,9 +110,20 @@
|
||||
: pool_size(threads)
|
||||
, in_flight(0)
|
||||
{
|
||||
+#ifndef __EMSCRIPTEN__
|
||||
const std::unique_lock<std::mutex> lock(this->queue_mutex);
|
||||
for (std::size_t i = 0; i != threads; ++i)
|
||||
start_worker(i, lock);
|
||||
+#else
|
||||
+ // vpinball-wasm: a single-threaded Emscripten build (no -pthread /
|
||||
+ // SharedArrayBuffer for v1) cannot construct real std::thread workers -
|
||||
+ // std::thread's constructor throws at runtime otherwise ("thread
|
||||
+ // constructor failed"). Run zero real workers; enqueue() below executes
|
||||
+ // tasks synchronously and inline instead, matching the porting plan's
|
||||
+ // "run ThreadPool work serially" decision for one-off parallel work
|
||||
+ // (parallel .vpx item deserialization at load, env-map baking, etc.).
|
||||
+ (void)pool_size;
|
||||
+#endif
|
||||
}
|
||||
|
||||
// add new work item to the pool
|
||||
@@ -139,6 +150,15 @@
|
||||
|
||||
std::future<return_type> res = task->get_future();
|
||||
|
||||
+#ifdef __EMSCRIPTEN__
|
||||
+ // vpinball-wasm: no real worker threads exist (see the constructor) -
|
||||
+ // run the task synchronously inline so callers still get a valid,
|
||||
+ // already-ready future, exactly as if it had run on a worker.
|
||||
+ (void)std::atomic_fetch_add_explicit(&in_flight, std::size_t(1), std::memory_order_relaxed);
|
||||
+ (*task)();
|
||||
+ (void)std::atomic_fetch_sub_explicit(&in_flight, std::size_t(1), std::memory_order_acq_rel);
|
||||
+ return res;
|
||||
+#else
|
||||
std::unique_lock<std::mutex> lock(queue_mutex);
|
||||
if (tasks.size () >= max_queue_size)
|
||||
// wait for the queue to empty or be stopped
|
||||
@@ -160,6 +180,7 @@
|
||||
condition_consumers.notify_one();
|
||||
|
||||
return res;
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user