以Web程序集为主循环和javascript回调的Web worker

以Web程序集为主循环和javascript回调的Web worker,web,worker,webassembly,pause,Web,Worker,Webassembly,Pause,我正在移植一个生成要显示的图形帧的应用程序。按照生活游戏的思路思考一些事情。主循环嵌套得很深,我将C程序编译成webassembly。在C程序中,我使用EM_ASM回调javascript,如下所示: EM_ASM({ SysDrawMap($0, $1, $2); }, (int)Used.MapWidth, (int)Used.MapHeight, imagedata); 这很有效。我得到了帧并可以渲染它。问题是,这会阻塞主线程,所以我永远看不到结果,直到模

我正在移植一个生成要显示的图形帧的应用程序。按照生活游戏的思路思考一些事情。主循环嵌套得很深,我将C程序编译成webassembly。在C程序中,我使用EM_ASM回调javascript,如下所示:

    EM_ASM({
        SysDrawMap($0, $1, $2);
    }, (int)Used.MapWidth, (int)Used.MapHeight, imagedata);
这很有效。我得到了帧并可以渲染它。问题是,这会阻塞主线程,所以我永远看不到结果,直到模拟结束,浏览器才会锁定

因此,我将代码移动到web worker,让它加载C程序,并使用postMessage队列系统将图像发布到主线程。在主线程上,我收到了图像并更新了画布。这种方法奏效了。问题是,工作线程创建帧的速度太快,并用图像填充队列(巨大的内存消耗),并且主线程在尝试接收图像时暂停

因此,我必须以某种方式限制生产方,但不能以导致太多减速的方式。我正在考虑使用5-10帧队列缓冲区,但如何在不重写主循环的情况下实现这一点

在worker中,当它将图像发布到队列时,它无法接收消息,因为控件直接返回到C程序,并且在它工作时,worker仍然不会接收消息

我甚至不能按下暂停按钮,因为web程序集全速向前运行,而不知道队列中的消息。而且似乎没有办法检查队列中的消息数量和任何一方


我担心我唯一的解决方案是重写C程序的深度嵌套循环,这样我就可以从javascript调用web程序集并生成1帧。但这能解决问题吗?我会有一个没完没了的while循环调用webassembly,这也会阻止新消息的接收。在web程序集运行之前,不会有任何空闲时间。

根本的问题是,您的模拟代码执行和输出帧的速度远远快于浏览器渲染帧的速度(以及您的计算机屏幕)。移动模拟代码并不能解决此问题

您需要重新思考模拟的运行方式。您应该更新代码,以便它导出一个“tick”函数,该函数在执行时生成模拟中的下一帧


浏览器公开在每次重新绘制之前调用的API。这允许您与显示屏同步。您可以使用它执行“勾选”功能,并将输出呈现到屏幕。

即重写深度嵌套的代码。我希望有办法解决这个问题,但我想没有-(