From 52c74a1c33ce12b93ec5830f5a6348d9578c7c6e Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Thu, 5 Jun 2025 08:37:34 +0200 Subject: Simplify callback business (web version) --- web/adapter.cpp | 27 +++++++++++++------------ web/callback.js | 52 ------------------------------------------------ web/http/start-server.sh | 8 ++++++++ web/http/worker.mjs | 14 +++++++------ web/logging.h | 16 ++++++++------- 5 files changed, 39 insertions(+), 78 deletions(-) delete mode 100644 web/callback.js create mode 100755 web/http/start-server.sh (limited to 'web') diff --git a/web/adapter.cpp b/web/adapter.cpp index 0022b0d..3df3a54 100644 --- a/web/adapter.cpp +++ b/web/adapter.cpp @@ -1,15 +1,10 @@ -extern "C" { - extern int addCallbackFunction(/* args intentionally unspecified */); - extern void callFunction(int, const char *); - extern int callFunctionInt(int); -} - #include "../cpp/nissy.h" #include "storage.h" #include "logging.h" #include #include +#include #include #include #include @@ -17,6 +12,8 @@ extern "C" { EM_ASYNC_JS(void, fake_async, (), {}); +std::map loaded_solvers; + const std::set available_solvers { "h48h0k4", @@ -27,8 +24,6 @@ const std::set available_solvers "h48h5k2", }; -std::map loaded_solvers; - bool is_solver_available(const std::string& name) { return available_solvers.contains(name); @@ -153,16 +148,20 @@ bool init_solver_generate(const std::string& name) int poll_status(void *arg) { - if (arg == NULL || *(int *)arg == -1) + if (arg == nullptr) return nissy::status::RUN.value; - return callFunctionInt(*(int *)arg); + std::function poll((int (*)(void))arg); + return poll(); } +// The parameter js_poll_status is of type int here, but actually it is a +// pointer to a JS function. The type will have to be changed to a 64-bit +// integer when we move to WASM64. nissy::solver::solve_result solve(std::string name, nissy::cube cube, nissy::nissflag nissflag, unsigned minmoves, unsigned maxmoves, unsigned maxsols, unsigned optimal, unsigned threads, - int poll_status_id) + int js_poll_status) { // Here we use a dirty trick to make this function always return the // same kind of JavaScript object. If we did not do this, the returned @@ -178,8 +177,11 @@ nissy::solver::solve_result solve(std::string name, {.err = nissy::error::INVALID_SOLVER}; } + // TODO: when running multiple solvers at the same time, we could use + // poll_status_id as intended (i.e. an id of some sort) return loaded_solvers.at(name).solve(cube, nissflag, minmoves, - maxmoves, maxsols, optimal, threads, poll_status, &poll_status_id); + maxmoves, maxsols, optimal, threads, + poll_status, &js_poll_status); } EMSCRIPTEN_BINDINGS(Nissy) @@ -244,5 +246,4 @@ EMSCRIPTEN_BINDINGS(Nissy) emscripten::return_value_policy::take_ownership()); emscripten::function("setLogger", &set_logger, emscripten::allow_raw_pointers()); - emscripten::function("addCallbackFunction", &addCallbackFunction); } diff --git a/web/callback.js b/web/callback.js deleted file mode 100644 index e277cf5..0000000 --- a/web/callback.js +++ /dev/null @@ -1,52 +0,0 @@ -addToLibrary({ - -cbfl: [], - -validateCallbackId__deps: [ 'cbfl' ], -validateCallbackId: function(i) { - if (i < 0) { - console.log("--- WARNING ---"); - console.log("Trying to access callback function of invalid id " + i); - console.log("--- WARNING ---"); - return false; - } - - if (i >= _cbfl.length) { - console.log("--- WARNING ---"); - console.log("Trying to access callback function " + i + ", but only " - + _cbfl.length + " have been registered. This may be caused by a " - + "call outside of the main thread."); - console.log("--- WARNING ---"); - return false; - } - - return true; -}, - -addCallbackFunction__deps: [ 'cbfl' ], -addCallbackFunction: function(f) { - _cbfl.push(f) - return _cbfl.length - 1 -}, - -callFunction__deps: [ 'cbfl', 'validateCallbackId' ], -callFunction: function(id, arg) { - // This is a workaround related to usign WASM64 - // JavaScript's UTF8ToString expects a pointer argument, which for JS is - // of type "number", but WASM64 is passing a BigInt. See also: - // https://github.com/emscripten-core/emscripten/issues/21541 - // (but I could not make the suggested solution work in this case). - // TODO: check if there is a better workaround. - const non64_arg = Number(arg); - if (_validateCallbackId(id)) - _cbfl[id](UTF8ToString(non64_arg)); -}, - -callFunctionInt__deps: [ 'cbfl', 'validateCallbackId' ], -callFunctionInt: function(id) { - if (_validateCallbackId(id)) - return _cbfl[id](); - return 0; -}, - -}); diff --git a/web/http/start-server.sh b/web/http/start-server.sh new file mode 100755 index 0000000..c827146 --- /dev/null +++ b/web/http/start-server.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +# Run this script from the main folder (../../) + +darkhttpd web/http \ + --header 'Cross-Origin-Opener-Policy: same-origin' \ + --header 'Cross-Origin-Embedder-Policy: require-corp' \ + --mimetypes web/http/mime diff --git a/web/http/worker.mjs b/web/http/worker.mjs index d912e8b..0c1acb9 100644 --- a/web/http/worker.mjs +++ b/web/http/worker.mjs @@ -1,14 +1,16 @@ import Nissy from "./nissy_web_module.mjs" const nissy = await Nissy(); -const log = (msg) => postMessage({ command: "log", id: -1, object: msg }); -nissy.setLogger(nissy._addCallbackFunction(log)); -var solveStatus = nissy.statusRUN; // For now this is a global variable -const pollStatusCallback = nissy._addCallbackFunction(() => { -console.log("Calling pollstatus, returning " + solveStatus); -return solveStatus; +const log = (cstr) => postMessage({ + command: "log", id: -1, + object: nissy.UTF8ToString(cstr) }); +nissy.setLogger(nissy.addFunction(log, "vp")); + +var solveStatus = nissy.statusRUN; // For now this is a global variable +const pollStatus = () => solveStatus; +const pollStatusCallback = nissy.addFunction(pollStatus, "i"); const commands = [ { name: "load solver data", exec: loadSolverDataFromStorage }, diff --git a/web/logging.h b/web/logging.h index 9ed4835..14609a0 100644 --- a/web/logging.h +++ b/web/logging.h @@ -1,11 +1,9 @@ -static int logger_id = -1; +static void (*js_log)(const char *) = nullptr; void log(std::string s) { - if (logger_id == -1) - return; - - callFunction(logger_id, s.c_str()); + if (js_log != nullptr) + js_log(s.c_str()); } void log_wrapper(const char *cstr, void *data) @@ -13,8 +11,12 @@ void log_wrapper(const char *cstr, void *data) log(cstr); } -void set_logger(int id) +/* +To receive a function pointer for JS, we use an int parameter. +This will have to be changed to a 64-bit integer when we move to WASM64. +*/ +void set_logger(int f) { - logger_id = id; + js_log = (void (*)(const char *))f; nissy::set_logger(log_wrapper, NULL); } -- cgit v1.3