Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EmscriptenApplication doesn't play well with asyncify #455

Open
mosra opened this issue Jul 6, 2020 · 1 comment
Open

EmscriptenApplication doesn't play well with asyncify #455

mosra opened this issue Jul 6, 2020 · 1 comment
Milestone

Comments

@mosra
Copy link
Owner

mosra commented Jul 6, 2020

Reported by @ShaddyDC. Current workaround is using Sdl2Application instead.

Repro code -- after pressing the button, the value is printed, but Frame isn't anymore after that. WindowFlag::AlwaysRequestAnimationFrame doesn't help.

#include <emscripten.h>

EM_JS(int, get_digest_size, (const char* str), {
  // Note how we return the output of handleSleep() here.
  return Asyncify.handleSleep(function(wakeUp) {
    const text = UTF8ToString(str);
    const encoder = new TextEncoder();
    const data = encoder.encode(text);
    out("ask for digest for " + text);
    window.crypto.subtle.digest("SHA-256", data).then(digestValue => {
      out("got digest of length " + digestValue.byteLength);
      // Return the value by sending it to wakeUp(). It will then be returned
      // from handleSleep() on the outside.
      wakeUp(digestValue.byteLength);
    });
  });
});

void ImGuiExample::drawEvent() {
    GL::defaultFramebuffer.clear(GL::FramebufferClear::Color);

    _imgui.newFrame();

    Debug{} << "Frame";

    /* Enable text input, if needed */
    if(ImGui::GetIO().WantTextInput && !isTextInputActive())
        startTextInput();
    else if(!ImGui::GetIO().WantTextInput && isTextInputActive())
        stopTextInput();

    {
        const char* silly = "some silly text";
        static int value = 0;
        ImGui::Text("%s's digest size is: %d\n", silly, value);
        if(ImGui::Button("load")){
            value = get_digest_size(silly);
            Debug{} << value;
        }
    }

    /* Update application cursor */
    _imgui.updateApplicationCursor(*this);

    _imgui.drawFrame();

    swapBuffers();
    redraw();
}

@Squareys since you were originally implementing the idle loop, do you have any idea what could cause this?

@mosra mosra added this to the 2020.0b milestone Jul 6, 2020
@ShaddyDC
Copy link

ShaddyDC commented Jul 6, 2020

It also affects functions like emscripten_wget_data. After an asincify operation, future frames aren't requested anymore and the application freezes. Manually requesting the next frame draw seems to work around it. Code copied from here

if(ImGui::Button("load")){
    value = get_digest_size(silly);
    Magnum::Debug() << value;

    int (*_callback)(void*);
    _callback = [](void* userData) -> int {
        auto& app = *static_cast<ImGuiExample*>(userData);

        app.drawEvent();

        return true;
    };

    EM_ASM({
        /* Animation frame callback */
        var drawEvent = function() {
            var id = window.requestAnimationFrame(drawEvent);

            /* Call our callback via function pointer returning int with two
            int params */
            if(!dynCall('ii', $0, [$1])) {
                window.cancelAnimationFrame(id);
            }
        };

        window.requestAnimationFrame(drawEvent);
    }, _callback, this);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

2 participants