Still trying to fix only working at -O0

This commit is contained in:
msqr1
2024-03-10 00:56:41 -08:00
parent 05f14c3671
commit 9a40cdaa7f
9 changed files with 10659 additions and 4696 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1,165 @@
"use strict";var Module={};var initializedJS=false;function threadPrintErr(...args){var text=args.join(" ");console.error(text)}function threadAlert(...args){var text=args.join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason||e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}loadVosklet(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err(`worker.js received unknown command ${e.data.cmd}`);err(e.data)}}catch(ex){Module["__emscripten_thread_crashed"]?.();throw ex}}self.onmessage=handleMessage;
/**
* @license
* Copyright 2015 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/
// Pthread Web Worker startup routine:
// This is the entry point file that is loaded first by each Web Worker
// that executes pthreads on the Emscripten application.
'use strict';
var Module = {};
// Thread-local guard variable for one-time init of the JS state
var initializedJS = false;
function assert(condition, text) {
if (!condition) abort('Assertion failed: ' + text);
}
function threadPrintErr(...args) {
var text = args.join(' ');
console.error(text);
}
function threadAlert(...args) {
var text = args.join(' ');
postMessage({cmd: 'alert', text, threadId: Module['_pthread_self']()});
}
// We don't need out() for now, but may need to add it if we want to use it
// here. Or, if this code all moves into the main JS, that problem will go
// away. (For now, adding it here increases code size for no benefit.)
var out = () => { throw 'out() is not defined in worker.js.'; }
var err = threadPrintErr;
self.alert = threadAlert;
var dbg = threadPrintErr;
Module['instantiateWasm'] = (info, receiveInstance) => {
// Instantiate from the module posted from the main thread.
// We can just use sync instantiation in the worker.
var module = Module['wasmModule'];
// We don't need the module anymore; new threads will be spawned from the main thread.
Module['wasmModule'] = null;
var instance = new WebAssembly.Instance(module, info);
// TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193,
// the above line no longer optimizes out down to the following line.
// When the regression is fixed, we can remove this if/else.
return receiveInstance(instance);
}
// Turn unhandled rejected promises into errors so that the main thread will be
// notified about them.
self.onunhandledrejection = (e) => {
throw e.reason || e;
};
function handleMessage(e) {
try {
if (e.data.cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code.
// Until we initialize the runtime, queue up any further incoming messages.
let messageQueue = [];
self.onmessage = (e) => messageQueue.push(e);
// And add a callback for when the runtime is initialized.
self.startWorker = (instance) => {
Module = instance;
// Notify the main thread that this thread has loaded.
postMessage({ 'cmd': 'loaded' });
// Process any messages that were queued before the thread was ready.
for (let msg of messageQueue) {
handleMessage(msg);
}
// Restore the real message handler.
self.onmessage = handleMessage;
};
// Module and memory were sent from main thread
Module['wasmModule'] = e.data.wasmModule;
// Use `const` here to ensure that the variable is scoped only to
// that iteration, allowing safe reference from a closure.
for (const handler of e.data.handlers) {
Module[handler] = (...args) => {
dbg(`calling handler on main thread: ${handler}`);
postMessage({ cmd: 'callHandler', handler, args: args });
}
}
Module['wasmMemory'] = e.data.wasmMemory;
Module['wasmOffsetData'] = e.data.wasmOffsetConverter;
Module['buffer'] = Module['wasmMemory'].buffer;
Module['workerID'] = e.data.workerID;
Module['ENVIRONMENT_IS_PTHREAD'] = true;
if (typeof e.data.urlOrBlob == 'string') {
importScripts(e.data.urlOrBlob);
} else {
var objectUrl = URL.createObjectURL(e.data.urlOrBlob);
importScripts(objectUrl);
URL.revokeObjectURL(objectUrl);
}
loadVosklet(Module);
} else if (e.data.cmd === 'run') {
// Pass the thread address to wasm to store it for fast access.
Module['__emscripten_thread_init'](e.data.pthread_ptr, /*is_main=*/0, /*is_runtime=*/0, /*can_block=*/1);
// Await mailbox notifications with `Atomics.waitAsync` so we can start
// using the fast `Atomics.notify` notification path.
Module['__emscripten_thread_mailbox_await'](e.data.pthread_ptr);
assert(e.data.pthread_ptr);
// Also call inside JS module to set up the stack frame for this pthread in JS module scope
Module['establishStackSpace']();
Module['PThread'].receiveObjectTransfer(e.data);
Module['PThread'].threadInitTLS();
if (!initializedJS) {
// Embind must initialize itself on all threads, as it generates support JS.
// We only do this once per worker since they get reused
Module['__embind_initialize_bindings']();
initializedJS = true;
}
try {
Module['invokeEntryPoint'](e.data.start_routine, e.data.arg);
} catch(ex) {
if (ex != 'unwind') {
// The pthread "crashed". Do not call `_emscripten_thread_exit` (which
// would make this thread joinable). Instead, re-throw the exception
// and let the top level handler propagate it back to the main thread.
throw ex;
}
dbg(`Pthread 0x${Module['_pthread_self']().toString(16)} completed its main entry point with an 'unwind', keeping the worker alive for asynchronous operation.`);
}
} else if (e.data.cmd === 'cancel') { // Main thread is asking for a pthread_cancel() on this thread.
if (Module['_pthread_self']()) {
Module['__emscripten_thread_exit'](-1);
}
} else if (e.data.target === 'setimmediate') {
// no-op
} else if (e.data.cmd === 'checkMailbox') {
if (initializedJS) {
Module['checkMailbox']();
}
} else if (e.data.cmd) {
// The received message looks like something that should be handled by this message
// handler, (since there is a e.data.cmd field present), but is not one of the
// recognized commands:
err(`worker.js received unknown command ${e.data.cmd}`);
err(e.data);
}
} catch(ex) {
err(`worker.js onmessage() captured an uncaught exception: ${ex}`);
if (ex?.stack) err(ex.stack);
Module['__emscripten_thread_crashed']?.();
throw ex;
}
};
self.onmessage = handleMessage;

View File

@@ -2,5 +2,10 @@
<html>
<head>
<script src="Vosklet.js"></script>
<script>
window.onload = async () => {
window.module = await loadVosklet();
}
</script>
</head>
</html>

View File

@@ -9,7 +9,7 @@ LIBARCHIVE=$(realpath libarchive) &&
CLAPACK_WASM=$(realpath clapack-wasm) &&
MAX_MEMORY=${MAX_MEMORY:-300mb} &&
MAX_THREADS=${MAX_THREADS:-3} &&
MAX_THREADS=${MAX_THREADS:-2} &&
EMSDK=${EMSDK:-$(realpath emsdk)} &&
if [ ! -d $EMSDK ]; then
@@ -28,9 +28,12 @@ fi
. $EMSDK/emsdk_env.sh &&
cd $SRC &&
MODE=1 &&
MODE=2 && # 0: Ultra debug info, 1: Extremely optimized release, else custom
echo "Mode = $MODE" &&
if [ $MODE = 0 ]; then
em++ -O0 global.cc genericModel.cc recognizer.cc bindings.cc -sWASMFS -sWASM_BIGINT -sSINGLE_FILE -sGZIP_EMBEDDINGS -sMODULARIZE -sEMBIND_STD_STRING_IS_UTF8 -sPTHREAD_POOL_DELAY_LOAD -sRUNTIME_DEBUG -sSTACK_OVERFLOW_CHECK=2 -sTEXTDECODER=2 -sPTHREAD_POOL_SIZE_STRICT=2 -sASSERTIONS=2 -sINITIAL_MEMORY=$MAX_MEMORY -sPTHREAD_POOL_SIZE=$MAX_THREADS -sDISABLE_EXCEPTION_CATCHING=0 -sEXIT_RUNTIME=0 -sPOLYFILL=0 -sEXPORTED_FUNCTIONS=_malloc -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sEXPORTED_RUNTIME_METHODS=UTF8ToString,stringToUTF8OnStack -sENVIRONMENT=web,worker -I. -I$LIBARCHIVE/include -I$VOSK/src -L$LIBARCHIVE/lib -larchive -L$KALDI/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L$OPENFST/lib -l:libfst.a -l:libfstngram.a -L$CLAPACK_WASM -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L$VOSK/src -l:vosk.a -lopfs.js -lembind -pthread -flto -msimd128 --emit-symbol-map --embind-emit-tsd Vosklet.d.ts --pre-js pre.js -fsanitize=undefined -fsanitize=address -o ../devel/Vosklet.js
em++ -O0 global.cc genericModel.cc recognizer.cc bindings.cc -sWASMFS -sWASM_BIGINT -sSINGLE_FILE -sGZIP_EMBEDDINGS -sMODULARIZE -sEMBIND_STD_STRING_IS_UTF8 -sPTHREAD_POOL_DELAY_LOAD -sRUNTIME_DEBUG -sSTACK_OVERFLOW_CHECK=2 -sTEXTDECODER=2 -sPTHREAD_POOL_SIZE_STRICT=2 -sASSERTIONS=2 -sINITIAL_MEMORY=$MAX_MEMORY -sPTHREAD_POOL_SIZE=$MAX_THREADS -sDISABLE_EXCEPTION_CATCHING=0 -sINVOKE_RUN=0 -sPOLYFILL=0 -sEXPORTED_FUNCTIONS=_malloc -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sEXPORTED_RUNTIME_METHODS=UTF8ToString,stringToUTF8OnStack -sENVIRONMENT=web,worker -I. -I$LIBARCHIVE/include -I$VOSK/src -L$LIBARCHIVE/lib -larchive -L$KALDI/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L$OPENFST/lib -l:libfst.a -l:libfstngram.a -L$CLAPACK_WASM -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L$VOSK/src -l:vosk.a -lopfs.js -lembind -pthread -flto -msimd128 --emit-symbol-map --embind-emit-tsd Vosklet.d.ts -fsanitize=undefined -fsanitize=address -fsanitize=leak -g3 --pre-js pre.js -o ../devel/Vosklet.js
elif [ $MODE = 1 ]; then
em++ -O3 global.cc genericModel.cc recognizer.cc bindings.cc -sWASMFS -sWASM_BIGINT -sSINGLE_FILE -sGZIP_EMBEDDINGS -sMODULARIZE -sEMBIND_STD_STRING_IS_UTF8 -sPTHREAD_POOL_DELAY_LOAD -sTEXTDECODER=2 -sPTHREAD_POOL_SIZE_STRICT=2 -sINITIAL_MEMORY=$MAX_MEMORY -sPTHREAD_POOL_SIZE=$MAX_THREADS -sPOLYFILL=0 -sINVOKE_RUN=0 -sSUPPORT_LONGJMP=0 -sEXPORTED_FUNCTIONS=_malloc -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sEXPORTED_RUNTIME_METHODS=UTF8ToString,stringToUTF8OnStack -sENVIRONMENT=web,worker -I. -I$LIBARCHIVE/include -I$VOSK/src -L$LIBARCHIVE/lib -larchive -L$KALDI/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L$OPENFST/lib -l:libfst.a -l:libfstngram.a -L$CLAPACK_WASM -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L$VOSK/src -l:vosk.a -lopfs.js -lembind -pthread -flto -msimd128 --pre-js pre.js -o ../devel/Vosklet.js
else
em++ -O3 global.cc genericModel.cc recognizer.cc bindings.cc -sWASMFS -sWASM_BIGINT -sSINGLE_FILE -sGZIP_EMBEDDINGS -sMODULARIZE -sEMBIND_STD_STRING_IS_UTF8 -sPTHREAD_POOL_DELAY_LOAD -sTEXTDECODER=2 -sPTHREAD_POOL_SIZE_STRICT=2 -sINITIAL_MEMORY=$MAX_MEMORY -sPTHREAD_POOL_SIZE=$MAX_THREADS -sPOLYFILL=0 -sEXIT_RUNTIME=0 -sSUPPORT_LONGJMP=0 -sEXPORTED_FUNCTIONS=_malloc -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sEXPORTED_RUNTIME_METHODS=UTF8ToString,stringToUTF8OnStack -sENVIRONMENT=web,worker -I. -I$LIBARCHIVE/include -I$VOSK/src -L$LIBARCHIVE/lib -larchive -L$KALDI/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L$OPENFST/lib -l:libfst.a -l:libfstngram.a -L$CLAPACK_WASM -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L$VOSK/src -l:vosk.a -lopfs.js -lembind -pthread -flto -msimd128 --pre-js pre.js -o ../devel/Vosklet.js
em++ -O0 global.cc genericModel.cc recognizer.cc bindings.cc -sWASMFS -sWASM_BIGINT -sSINGLE_FILE -sGZIP_EMBEDDINGS -sMODULARIZE -sEMBIND_STD_STRING_IS_UTF8 -sPTHREAD_POOL_DELAY_LOAD -sRUNTIME_DEBUG -sSTACK_OVERFLOW_CHECK=2 -sTEXTDECODER=2 -sPTHREAD_POOL_SIZE_STRICT=2 -sASSERTIONS=2 -sINITIAL_MEMORY=$MAX_MEMORY -sPTHREAD_POOL_SIZE=$MAX_THREADS -sDISABLE_EXCEPTION_CATCHING=0 -sEXIT_RUNTIME=0 -sPOLYFILL=0 -sEXPORTED_FUNCTIONS=_malloc -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sEXPORTED_RUNTIME_METHODS=UTF8ToString,stringToUTF8OnStack -sENVIRONMENT=web,worker -I. -I$LIBARCHIVE/include -I$VOSK/src -L$LIBARCHIVE/lib -larchive -L$KALDI/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L$OPENFST/lib -l:libfst.a -l:libfstngram.a -L$CLAPACK_WASM -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L$VOSK/src -l:vosk.a -lopfs.js -lembind -pthread -flto -msimd128 --emit-symbol-map --embind-emit-tsd Vosklet.d.ts -fsanitize=undefined -fsanitize=address -fsanitize=leak -g3 --pre-js pre.js -o ../devel/Vosklet.js
fi

View File

@@ -45,93 +45,113 @@ bool genericModel::checkFiles() {
fs::exists("transform.mat", tank);
}
genericModel::~genericModel() {
if(normalMdl) {
vosk_model_free(std::get<0>(mdl));
return;
}
vosk_spk_model_free(std::get<1>(mdl));
if(normalMdl) vosk_model_free(std::get<0>(mdl));
else vosk_spk_model_free(std::get<1>(mdl));
}
void genericModel::check() {
thrd.addTask([this](){
if(OPFSTried && !OPFSOk) {
emscripten_console_log("OPFS isn't available");
fireEv("_checkMdl", "OPFS isn't available", index);
return;
}
if(!OPFSTried){
emscripten_console_log("Trying to acquire OPFS");
OPFSTried = true;
OPFSOk = wasmfs_create_directory("/opfs", 0777, wasmfs_create_opfs_backend()) == 0;
};
emscripten_console_log("Initializing OPFS");
if(!OPFSOk) {
emscripten_console_log("OPFS initialization failed");
fireEv("_checkMdl", "OPFS initialization failed", index);
return;
}
fs::current_path("/opfs", tank);
if(tank.value() != 0) {
emscripten_console_log("Unable to cd OPFS root");
fireEv("_continue","Unable to cd OPFS root", index);
return;
}
fs::create_directories(storepath, tank);
if(tank.value() != 0) {
emscripten_console_log("Unable to create storepath");
fireEv("_continue","Unable to create storepath", index);
}
fs::current_path(storepath, tank);
if(tank.value() != 0) {
emscripten_console_log("Unable to cd storepath");
fireEv("_continue", "Unable to cd storepath", index);
}
if(!checkFiles() && !fs::exists("id", tank)) {
emscripten_console_log("Model is not available, fetching...");
fireEv("_checkMdl", "fetch", index);
return;
}
emscripten_console_log("Model is available, verifying ID");
FILE* idFile {fopen("id", "r")};
if(idFile == nullptr) {
emscripten_console_log("Couldn't open id file");
fireEv("_checkMdl", "Couldn't open id file", index);
return;
}
emscripten_console_log("1");
if(fseek(idFile, 0, SEEK_END) != 0) {
emscripten_console_log("Id file end seeking fail");
fireEv("_checkMdl", "Id file end seeking fail", index);
fclose(idFile);
return;
};
emscripten_console_log("1");
long long oldsize{ftell(idFile)};
char* oldid {new char[oldsize]};
if(fseek(idFile, 0L, SEEK_SET) != 0) {
emscripten_console_log("Id file start seeking fail");
fireEv("_checkMdl", "Id file start seeking fail", index);
fclose(idFile);
return;
};
emscripten_console_log("1");
fread(oldid, 1, oldsize, idFile);
fclose(idFile);
if(strcmp(oldid, id.c_str()) != 0) fireEv("_checkMdl", "fetch", index);
else fireEv("_checkMdl", nullptr, index);
if(strcmp(oldid, id.c_str()) != 0) {
emscripten_console_log("ID doesn't match, fetching...");
fireEv("_checkMdl", "fetch", index);
}
else {
emscripten_console_log("ID match, returning instance");
fireEv("_checkMdl", nullptr, index);
}
delete[] oldid;
emscripten_console_log("1");
emscripten_console_log("Success! Model is ready!");
});
}
void genericModel::afterFetch() {
thrd.addTask([this](){
emscripten_console_log("Trying to extract...");
if(!extract()) {
fs::remove("/opfs/m0dEl.tar",tank);
fs::current_path("/opfs", tank);
fs::remove_all(storepath, tank);
emscripten_console_log("Unable to extract model");
fireEv("_continue", "Unable to extract model", index);
return;
}
emscripten_console_log("Extract done, checking files...");
if(!checkFiles()) {
emscripten_console_log("URL points to invalid model files");
fireEv("_continue", "URL points to invalid model files", index);
return;
}
emscripten_console_log("Creating ID file...");
int idFd {creat("id",0777)};
if(idFd == -1) {
fireEv("_continue", "Unable create ID file", index);
emscripten_console_log("Unable to create ID file");
fireEv("_continue", "Unable to create ID file", index);
fs::remove("/opfs/m0dEl.tar",tank);
fs::current_path("/opfs", tank);
fs::remove_all(storepath, tank);
return;
}
emscripten_console_log("Writing ID...");
if(write(idFd, id.c_str(), id.size()) == -1) {
emscripten_console_log("Unable to write new ID");
fireEv("_continue", "Unable to write new ID", index);
fs::remove("/opfs/m0dEl.tar",tank);
fs::current_path("/opfs", tank);
@@ -140,14 +160,15 @@ void genericModel::afterFetch() {
return;
};
close(idFd);
emscripten_console_log("Success! Model is ready!");
});
load();
//load();
}
bool genericModel::extract() {
static fs::path path{};
static int fd{};
static archive* src {archive_read_new()};
archive_entry* entry{archive_entry_new()};
static archive_entry* entry{archive_entry_new()};
archive* src {archive_read_new()};
archive_read_support_format_tar(src);
archive_read_open_filename(src, "/opfs/m0dEl.tar", 10240);
if(archive_errno(src) != 0) return false;
@@ -156,7 +177,7 @@ bool genericModel::extract() {
path = archive_entry_pathname(entry);
// Strip 1st component, keep relative path
path = "." + path.generic_string().substr(path.generic_string().find("/"));
emscripten_console_log(path.c_str());
emscripten_console_logf("Creating file/dir %s", path.c_str());
if(!path.has_extension()) {
fs::create_directory(path);
continue;
@@ -164,8 +185,11 @@ bool genericModel::extract() {
fd = creat(path.c_str(),0777);
if(fd == -1) return false;
archive_read_data_into_fd(src, fd);
if(archive_errno(src) != 0) return false;
close(fd);
if(archive_errno(src) != 0) {
emscripten_console_log(archive_error_string(src));
return false;
}
}
fs::remove("README",tank);
fs::remove("/opfs/m0dEl.tar",tank);

View File

@@ -14,18 +14,21 @@ void fireEv(const char *type, const char *content, int index) {
if(dstThrd == pthread_self()) proxy();
else glbQ.proxySync(dstThrd, proxy);
}
void reusableThrd::addTask(std::function<void()>&& task) {
static std::thread thrd{[this](){
pthread_detach(pthread_self());
reusableThrd::reusableThrd() {
std::thread thrd{[this](){
while(!done.test()) {
blocker.wait(done.test(std::memory_order_relaxed) || queue.empty(), std::memory_order_relaxed);
blocker.clear(std::memory_order_relaxed);
while(!queue.empty()) {
emscripten_console_log("Executing task...");
queue.front()();
queue.pop();
}
}
}};
thrd.detach();
}
void reusableThrd::addTask(std::function<void()>&& task) {
queue.emplace(task);
blocker.test_and_set(std::memory_order_relaxed);
blocker.notify_one();

View File

@@ -21,5 +21,6 @@ struct reusableThrd {
std::atomic_flag blocker{};
std::atomic_flag done{};
void addTask(std::function<void()>&& task);
reusableThrd();
~reusableThrd();
};

View File

@@ -41,6 +41,7 @@ class genericModel extends EventTarget {
if(!readRes.done) await wStream.write(readRes.value)
else break
}
tarReader.releaseLock()
await wStream.close()
mdl.obj.afterFetch()
break;