Fix await issue. But it doesn't work tho.

This commit is contained in:
msqr1
2024-02-08 20:19:38 -08:00
parent 5228c666a2
commit 18de98dd3b
12 changed files with 122 additions and 5988 deletions

View File

@@ -1,34 +1,50 @@
#include "genericModel.h"
genericModel::genericModel(const std::string& storepath, const std::string &id, int index) : storepath(storepath), id(id), index(index) {
if(!OPFSOk) {
fireEv("_continue", "OPFS isn't initialized or unavailable", index);
return;
}
fs::current_path("/opfs", tank);
if(tank.value() != 0) {
fireEv("_continue","Unable to cd OPFS root", index);
return;
}
fs::create_directories(storepath, tank);
if(tank.value() != 0) {
fireEv("_continue","Unable to create storepath", index);
}
fs::current_path(storepath, tank);
if(tank.value() != 0) {
fireEv("_continue", "Unable to cd storepath", index);
}
}
bool genericModel::checkModel() {
if(!checkModelFiles()) return false;
if(!fs::exists("id", tank)) return false;
std::ifstream file {"id", std::ifstream::binary};
if(!file.is_open()) return false;
long long size {file.seekg(0, std::ios::end).tellg()};
std::string oldid(size, ' ');
file.seekg(0);
file.read(&oldid[0], size);
return id.compare(oldid) == 0;
genericModel::genericModel(const std::string& storepath, const std::string &id, int index) : storepath(storepath), id(id), index(index) {}
void genericModel::checkModel() {
thrd.addTask([this](){
if(OPFSTried && !OPFSOk) {
fireEv("_checkMdl", "OPFS isn't available", index);
return;
}
if(!OPFSTried){
OPFSTried = true;
OPFSOk = wasmfs_create_directory("/opfs", 0777, wasmfs_create_opfs_backend()) == 0;
}
if(!OPFSOk) {
fireEv("_checkMdl", "OPFS initialization failed", index);
return;
}
fs::current_path("/opfs", tank);
if(tank.value() != 0) {
fireEv("_continue","Unable to cd OPFS root", index);
return;
}
fs::create_directories(storepath, tank);
if(tank.value() != 0) {
fireEv("_continue","Unable to create storepath", index);
}
fs::current_path(storepath, tank);
if(tank.value() != 0) {
fireEv("_continue", "Unable to cd storepath", index);
}
if(!checkModelFiles() && !fs::exists("id", tank)) {
fireEv("_checkMdl", "fetch", index);
return;
}
std::ifstream file {"id", std::ifstream::in};
if(!file.is_open()) {
fireEv("_checkMdl", "Couldn't open id file", index);
return;
}
long long size {file.seekg(0, std::ios::end).tellg()};
std::string oldid(size, ' ');
file.seekg(0);
file.read(&oldid[0], size);
if(id.compare(oldid) == 0) fireEv("_checkMdl", nullptr, index);
else fireEv("_checkMdl", "fetch", index);
file.close();
});
}
void genericModel::afterFetch() {
thrd.addTask([this](){
@@ -45,7 +61,7 @@ void genericModel::afterFetch() {
fireEv("_continue", "URL contains invalid model files", index);
return;
}
std::ofstream idFile("id");
std::ofstream idFile{"id"};
if(!idFile.is_open()) {
fs::current_path("/opfs", tank);
fs::remove_all(storepath, tank);
@@ -76,10 +92,7 @@ bool genericModel::extractModel() {
fd = open(path.c_str(), O_CREAT | O_WRONLY | O_TRUNC);
archive_read_data_into_fd(src, fd);
close(fd);
if(archive_errno(src) != 0) {
emscripten_console_log(archive_error_string(src));
return false;
}
if(archive_errno(src) != 0) return false;
}
archive_read_free(src);
return true;

View File

@@ -19,8 +19,8 @@ struct genericModel {
int index{};
static bool extractModel();
virtual bool checkModelFiles() = 0;
virtual void load(bool newThrd) = 0;
bool checkModel();
virtual void load(bool newTask) = 0;
void checkModel();
void afterFetch();
genericModel(const std::string &storepath, const std::string &id, int index);
};

View File

@@ -3,8 +3,8 @@
pthread_t dstThrd{pthread_self()};
std::error_code tank{};
bool OPFSOk{};
bool OPFSTried{};
ProxyingQueue glbQ{};
void fireEv(const char *type, const char *content, int index) {
auto proxy{[index, type, content](){
EM_ASM({
@@ -17,31 +17,23 @@ void fireEv(const char *type, const char *content, int index) {
}
glbQ.proxySync(dstThrd, proxy);
}
void reusableThrd::addTask(std::function<void()> task) {
void reusableThrd::addTask(std::function<void()>&& task) {
static std::thread thrd{[this](){
pthread_detach(pthread_self());
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()) {
queue.front()();
queue.pop();
}
blocker.wait(done.test(std::memory_order_relaxed) || queue.empty(), std::memory_order_relaxed);
blocker.clear(std::memory_order_relaxed);
}
}};
thrd.detach();
queue.emplace(std::move(task));
queue.emplace(task);
blocker.test_and_set(std::memory_order_relaxed);
blocker.notify_one();
}
reusableThrd::~reusableThrd() {
done.test_and_set(std::memory_order_relaxed);
done.notify_one();
}
int main() {
std::thread t{[](){
OPFSOk = wasmfs_create_directory("/opfs", 0777, wasmfs_create_opfs_backend()) == 0;
}};
t.detach();
emscripten_exit_with_live_runtime();
}

View File

@@ -10,17 +10,16 @@
using namespace emscripten;
extern bool OPFSOk;
extern bool OPFSTried;
extern std::error_code tank;
extern pthread_t dstThrd;
extern ProxyingQueue glbQ;
void fireEv(const char *type, const char *content, int index);
int main();
struct reusableThrd {
std::queue<std::function<void()>> queue{};
std::atomic_flag blocker{};
std::atomic_flag done{};
void addTask(std::function<void()> task);
void addTask(std::function<void()>&& task);
~reusableThrd();
};
};

View File

@@ -7,19 +7,19 @@ model::~model() {
void model::afterFetch() {
genericModel::afterFetch();
}
bool model::checkModel() {
return genericModel::checkModel();
void model::checkModel() {
genericModel::checkModel();
}
void model::load(bool newThrd) {
void model::load(bool newTask) {
auto main{[this](){
mdl = vosk_model_new(".");
if(mdl == nullptr) {
fireEv("_continue", "Unable to load model for recognition", index);
return;
}
fireEv("_continue", ".", index);
fireEv("_continue", nullptr, index);
}};
if(!newThrd) {
if(!newTask) {
main();
return;
}

View File

@@ -5,9 +5,9 @@ struct model : genericModel {
bool checkModelFiles();
VoskModel* mdl{};
model(const std::string& storepath, const std::string& id, int index);
bool checkModel();
void checkModel();
void afterFetch();
void load(bool newThrd);
void load(bool newTask);
~model();
};

View File

@@ -17,41 +17,45 @@ class genericModel extends EventTarget {
let mdl = new genericModel()
return new Promise((resolve, reject) => {
mdl.addEventListener("_continue", (ev) => {
if(ev.detail === ".") {
if(ev.detail === "0") {
return resolve(mdl)
}
mdl.delete()
reject(ev.detail)
}, {once : true})
if(normalMdl) {
mdl.obj = new Module.model(storepath, id, objs.length-1)
}
else {
mdl.obj = new Module.spkModel(storepath, id, objs.length-1)
}
if(mdl.obj.checkModel()) {
mdl.obj.load(true)
return;
}
(async () => {
let res = await fetch(url)
if(!res.ok) {
return reject("Unable to download model")
mdl.addEventListener("_checkMdl", (ev) => {
switch(ev.detail) {
case "0":
mdl.load(true);
break;
case "fetch":
(async () => {
let res = await fetch(url)
if(!res.ok) {
return reject("Unable to download model")
}
let wStream = await (await (await navigator.storage.getDirectory()).getFileHandle("m0dEl.tar", {create : true})).createWritable()
let tarReader = res.body.pipeThrough(dStream).getReader()
while(true) {
let readRes = await tarReader.read()
if(!readRes.done) await wStream.write(readRes.value)
else break
}
await wStream.close()
mdl.obj.afterFetch()
})()
break;
default:
reject(ev.detail)
}
let wStream = await (await (await navigator.storage.getDirectory()).getFileHandle("m0dEl.tar", {create : true})).createWritable()
let tarReader = res.body.pipeThrough(dStream).getReader()
while(true) {
let readRes = await tarReader.read()
if(!readRes.done) await wStream.write(readRes.value)
else break
}
await wStream.close()
mdl.obj.afterFetch()
})()
}, {once : true})
if(normalMdl) mdl.obj = new Module.model(storepath, id, objs.length-1)
else mdl.obj = new Module.spkModel(storepath, id, objs.length-1)
mdl.obj.checkModel()
})
}
delete() {
this.obj.delete()
if (this.obj) this.obj.delete()
}
}
Module.makeModel = async (url, storepath, id) => {
@@ -69,15 +73,14 @@ class Recognizer extends EventTarget {
let rec = new Recognizer()
return new Promise((resolve, reject) => {
rec.addEventListener("_continue", (ev) => {
if(ev.detail == ".") {
objs.push(rec)
if(ev.detail == "0") {
rec.ptr = Module._malloc(512)
return resolve(rec)
}
rec.delete()
reject(ev.detail)
}, {once : true})
rec.obj = new Module.recognizer(model, sampleRate, objs.length-1)
rec.ptr = Module._malloc(512)
})
}
async getNode(ctx, channelIndex = 0) {
@@ -96,10 +99,8 @@ class Recognizer extends EventTarget {
this.obj.acceptWaveForm()
}
delete() {
this.obj.delete()
if(typeof this.node !== "undefined") {
this.node.port.postMessage(".")
}
if (this.obj) this.obj.delete()
if(this.node) this.node.postMessage("0")
}
setWords(words) {
this.obj.setWords(words)
@@ -136,7 +137,7 @@ let processorUrl = URL.createObjectURL(new Blob(['(',
process(inputs, outputs, params) {
if(this.done) return false;
this.wasmMem.set(inputs[0].getChannelData(this.channelIndex));
this.recognizerPort.postMessage(".")
this.recognizerPort.postMessage("0")
outputs = inputs
return true
}

View File

@@ -1,17 +1,13 @@
#include "recognizer.h"
recognizer::recognizer(model* mdl, float sampleRate, int index) : index(index) {
if(!OPFSOk) {
fireEv("_continue", "OPFS isn't initialized or unavailable", index);
return;
}
auto main{[this, mdl, sampleRate](){
rec = vosk_recognizer_new(mdl->mdl,sampleRate);
if(rec == nullptr) {
fireEv("_continue", "Unable to initialize recognizer", this->index);
return;
}
fireEv("_continue", "." ,this->index);
fireEv("_continue", nullptr, this->index);
while(!done.test(std::memory_order_relaxed)) {
controller.wait(!done.test(std::memory_order_relaxed), std::memory_order_relaxed);
controller.clear(std::memory_order_relaxed);

View File

@@ -8,22 +8,22 @@ spkModel::spkModel(const std::string& storepath, const std::string& id, int inde
spkModel::~spkModel() {
vosk_spk_model_free(mdl);
}
bool spkModel::checkModel() {
return genericModel::checkModel();
void spkModel::checkModel() {
genericModel::checkModel();
}
void spkModel::afterFetch() {
genericModel::afterFetch();
}
void spkModel::load(bool newThrd) {
void spkModel::load(bool newTask) {
auto main{[this](){
mdl = vosk_spk_model_new(".");
if(mdl == nullptr) {
fireEv("_continue", "Unable to load model for recognition", index);
return;
}
fireEv("_continue", ".", index);
fireEv("_continue", nullptr, index);
}};
if(!newThrd) {
if(!newTask) {
main();
return;
}

View File

@@ -5,8 +5,8 @@ struct spkModel : genericModel {
bool checkModelFiles();
VoskSpkModel* mdl{};
spkModel(const std::string& storepath, const std::string& id, int index);
bool checkModel();
void checkModel();
void afterFetch();
void load(bool newThrd);
void load(bool newTask);
~spkModel();
};