ArthurSonzogni / smk

SMK - Simple multimedia kit - C++ WebAssembly
MIT License
123 stars 18 forks source link

Script terminated by timeout #1

Closed abarichello closed 4 years ago

abarichello commented 4 years ago

Using Firefox with the sample 'draw a circle' code freezes the tab for seconds, only loads the webpage after it prompts you to stop the unresponsible script.

Console output:

Error: Script terminated by timeout at:
_usleep@http://localhost:8000/smkstarter.js:7172:16
_nanosleep@http://localhost:8000/smkstarter.js:7198:14
@http://localhost:8000/smkstarter.wasm:wasm-function[2336]:0x41953
@http://localhost:8000/smkstarter.wasm:wasm-function[2334]:0x41859
@http://localhost:8000/smkstarter.wasm:wasm-function[945]:0x20735
@http://localhost:8000/smkstarter.wasm:wasm-function[941]:0x20440
@http://localhost:8000/smkstarter.wasm:wasm-function[84]:0x1aeb
@http://localhost:8000/smkstarter.wasm:wasm-function[94]:0x1e5f
Module._main@http://localhost:8000/smkstarter.js:7630:32
callMain@http://localhost:8000/smkstarter.js:7967:28
doRun@http://localhost:8000/smkstarter.js:8028:31
run@http://localhost:8000/smkstarter.js:8043:5
runCaller@http://localhost:8000/smkstarter.js:7941:19
removeRunDependency@http://localhost:8000/smkstarter.js:1579:7
receiveInstance@http://localhost:8000/smkstarter.js:1692:24
receiveInstantiatedSource@http://localhost:8000/smkstarter.js:1709:20
smkstarter.js:7172:16
ArthurSonzogni commented 4 years ago

Thanks for reporting this!

Could you please help me understand what is the example you are talking about? Is it one of: https://arthursonzogni.github.io/smk/examples/?

I don't see any "draw a circle" here. Maybe "shape_2d" ?

I am surprised you see _nanosleep being called. It shouldn't happen when webassembly is being used. Maybe I need to build and update the examples.

abarichello commented 4 years ago

Using this example:


#include <smk/Color.hpp>
#include <smk/Shape.hpp>
#include <smk/Window.hpp>

int main() {
    auto window = smk::Window(640, 480, "test");
    auto circle = smk::Shape::Circle(200);
    circle.SetColor(smk::Color::Red);
    circle.SetPosition(320, 240);

    while (!window.input().IsKeyPressed(GLFW_KEY_ESCAPE)) {
        window.PoolEvents();
        window.Clear(smk::Color::Blue);
        window.Draw(circle);
        window.Display();
        window.LimitFrameRate(60);
    }
    return 0;
}

The webpage loads but it's really inconvenient to wait around10seconds with a frozen tab to test the wasm result.

ArthurSonzogni commented 4 years ago

I see! Your code works in a desktop environment, but it won't in a web browser environment.

You are doing a infinite "while" loop. It means your "javascript" task will take forever and block the page. Instead you must set a callback that will be called periodically by the web browser using emscripten_set_main_loop.

You should start from the starter project: smk-starter or any other examples in /examples.

Your example will look like:

main.cpp


#include <smk/Color.hpp>
#include <smk/Shape.hpp>
#include <smk/Window.hpp>
#include "./util.hpp"  // ExecuteMainLoop

int main() {
  auto window = smk::Window(640, 480, "test");
  auto circle = smk::Shape::Circle(200);
  circle.SetColor(smk::Color::Red);
  circle.SetPosition(320, 240);
  ExecuteMainLoop(window, [&] {
    window.PoolEvents();
    window.Clear(smk::Color::Blue);
    window.Draw(circle);
    window.Display();
  });
  return EXIT_SUCCESS;
}

util.hpp

std::function<void()> main_loop;
void MainLoop() {
  main_loop();
}

void ExecuteMainLoop(smk::Window& window, std::function<void()> loop) {
  main_loop = loop;
  #ifdef __EMSCRIPTEN__
    (void)window; // unused parameter.
    emscripten_set_main_loop(&MainLoop, 0, 1);
  #else
    while (!window.input().IsKeyPressed(GLFW_KEY_ESCAPE)) {
      MainLoop();
      window.LimitFrameRate(60.0f);
    }
  #endif
}

Do you think I should make "ExecuteMainLoop" part of the library?

ArthurSonzogni commented 4 years ago

I added an helper function for you in commit 36f90f0. You can now use:

#include <smk/Color.hpp>
#include <smk/Shape.hpp>
#include <smk/Window.hpp>

int main() {
    auto window = smk::Window(640, 480, "test");
    auto circle = smk::Shape::Circle(200);
    circle.SetColor(smk::Color::Red);
    circle.SetPosition(320, 240);

    window.ExecuteMainLoop([&]{
        window.PoolEvents();
        window.Clear(smk::Color::Blue);
        window.Draw(circle);
        window.Display();
    }
    return 0;
}

Does it addresses you issue?

abarichello commented 4 years ago

Thanks! The abstraction being included in the lib is really handy.