emscripten web assembly 运行期间更新进度条?

问题描述 投票:0回答:3

我想在 Emscripten WebAssembly 运行期间显示进度条。但进度条会在 WebAssembly 完成后更新。有没有办法中断 WebAssembly(主线程)然后继续或强制 javascript(主线程)渲染 GUI?

main.js

Module.cwrap('calc', 'undefined', [])();

计算.cpp

void calc() {
   EM_ASM({ progressBar($0); }, value); // here the progress bar should be updated immedately
   ...
   calc something
   ...
}
// but it's updated only here

我也尝试过

progressbar(val) {
   setTimeout(function(){ updateBar(val); }, 0);
}

不幸的是,对我来说,不可能在单独的文件中使用网络工作者。 谢谢...

c++ multithreading webassembly emscripten
3个回答
1
投票

不幸的是,无法强制 UI 渲染。我不知道是否可以打断 wasm,但这里有一个替代的想法。

考虑随着时间的推移分散计算,并给主线程(和事件循环)一些“呼吸空间”来更新 UI。

假设您正在计算总和,总共需要很多时间。您可以拆分计算,以便一次计算总和的一部分:

var sum = 0;
var i = setInterval(() => {
    sum = calculatePartialSum(sum);
    if(isDone(sum))
        clearInterval(i); // stop
},0);

超时设置为 0 的 setInterval 将尽可能频繁地运行内部代码,但主线程(和 UI)可以在每次调用之间更新。


0
投票

@schteppe:谢谢!对于有同样问题的人。我用 emscripten_async_call() 解决了它。

main.js

Module.cwrap('calc', 'undefined', [])();

计算.cpp

void calc() {
   EM_ASM({ progressBar($0); }, value);
   emscripten_async_call("calcfunction, NULL, msec");
}
void calcfunction() {
   ...
   calc something
   ...
}


0
投票

我用 SDL3 测试过的更完整的示例代码:

  1. 将此代码添加到
    CMakeLists.txt
target_link_options(${EXECUTABLE_NAME} PRIVATE
        -sEXPORTED_RUNTIME_METHODS=["cwrap"])

target_link_options(${EXECUTABLE_NAME} PRIVATE
        -sEXPORTED_FUNCTIONS=["_calc"])
  1. 将此代码添加到
    index.js
function progressBar(val) {
   console.log(val);
}

Module["onRuntimeInitialized"] = function() {

    const calc = Module.cwrap("calc", null, []);
    calc();

};
  1. 将此代码添加到
    main.cpp
#include <emscripten.h>

void calcfunction(void *)
{
    std::cout << "calc something" << std::endl;
}

extern "C"
{
    void calc()
    {
        EM_ASM({ progressBar($0); }, 10);

        emscripten_async_call(calcfunction, NULL, 0);
    }
}

或使用这个:

extern "C"
{
    void calc()
    {
        EM_ASM({ progressBar($0); }, 10);

        emscripten_async_call(+[](void *){
            std::cout << "calc something" << std::endl;
        }, NULL, 0);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.