javascript — Emscripten webworker — Собственные сообщения и зависимости

У меня есть проект C ++, который я компилирую в Javascript, используя emscripten. Это работает, однако, из-за ограничений ресурсов и по причинам интерактивности, я хотел бы запустить это внутри веб-работника.

Тем не менее, мой проект использует стандартный ввод. Я нашел способ предоставить свою собственную реализацию stdin, переписав Module [‘stdin’] с помощью функции, которая возвращает один символ за раз от общего stdin, и закрывается с 0 как EOF.
Это работает, когда скрипт выполняется внутри страницы, так как объект Module, представленный в html-файле, используется совместно со скриптом.

Когда вы работаете как веб-работник, этот объект модуля не является общим. Вместо этого, передача сообщений обеспечивает постоянную работу модуля. Это не включает ‘stdin’.

Я работал над этим путем изменения выходного JavaScript:

  • A: Добавление реализации объекта Module, включающего эту спецификацию stdin. Эта функция модифицирована, чтобы читать переменную веб-работника, как если бы это был стандартный ввод, и передавать ее по каждому символу.
  • B: Изменение сообщения веб-работника для вызова дополнительной функции, обрабатывающей мои собственные события.
  • C: Эта дополнительная функция прослушивает события и реагирует, когда событие является содержимым стандартного ввода, устанавливая переменную, которую читает указанная мной функция стандартного ввода.
  • D: добавление и удаление зависимостей выполнения для этого дополнительного события, чтобы код c ++ не работал без заданного stdin.

В коде:

Module['stdin_pointer'] = 0;
Module['stdin_content'] = "";

Module['stdin']=(function () {
if (Module['stdin_pointer'] < Module['stdin_content'].length) {
code = Module['stdin_content'].charCodeAt(Module['stdin_pointer']);
Module['stdin_pointer']=Module['stdin_pointer']+1;
return code;
} else {
return null;
}
});

external = function(message){
switch(message.data.target){
case 'stdin' : {
Module['idpCode'] = message.data.content;
removeRunDependency('stdin');
break;
}
default: throw 'wha? ' + message.data.target;
}
};

[...]

addRunDependency("stdin");

[...]
//Change this in the original onmessage function:
//      default: throw 'wha? ' + message.data.target;
//to
default: {external(message);}

Понятно, что это & Часть c довольно проста, потому что ее можно добавить в начале (или около начала) файла js, но b & d (добавление ваших собственных зависимостей и получение вашего собственного обработчика сообщений в цикле) требует от вас редактирования встроенного кода.
Поскольку мой проект очень большой, поиск необходимых строк для редактирования может быть очень громоздким, и только в оптимизированном и минимизированном коде emscripten.
Автоматические сценарии для этого, а также сам обходной путь, вероятно, сломаются в новых выпусках emscripten.

Есть ли более хороший и правильный способ достичь того же поведения?

Спасибо!

//РЕДАКТИРОВАТЬ:
--separate-asm flag очень полезен в том смысле, что файл, который я должен редактировать, теперь имеет всего несколько строк (в уменьшенном виде). Это значительно снижает нагрузку, но это все еще не совсем правильный путь, поэтому я не хочу отмечать это как решенное.

1

Решение

Единственный известный мне способ достижения того, чего вы хотите, — это не использовать рабочий API, предоставляемый Emscripten, а использовать свой собственный. Все детали, вероятно, выходят за рамки одного вопроса, но на высоком уровне вам нужно …

В качестве дополнительного примечания я обнаружил, что поставляемые Emscripten обертки C ++ для таких функций JavaScript, как рабочие, графика, аудио, http-запросы и т. Д., Хороши для начала, но имеют ограничения и не предоставляют всего, что технически возможно. Мне часто приходилось кататься самостоятельно, чтобы получить функционально необходимое. Хотя не по тем же причинам, мне также пришлось написать свой собственный API для рабочих.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]