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

Bootstrap hangs on await #2

Closed
hopeless-programmer-online opened this issue Jul 5, 2020 · 4 comments
Closed

Bootstrap hangs on await #2

hopeless-programmer-online opened this issue Jul 5, 2020 · 4 comments

Comments

@hopeless-programmer-online

It seems that handling bootstrap with await Ammo() instead of Ammo().then() cause browser to stop responding.

While this code works perfectly:

import Ammo from "ammojs-typed";

window.addEventListener(`load`, main);

async function main() {
  Ammo().then(ammo => {
    console.log(ammo);
  });
}

The similar approach with await hangs the browser:

import Ammo from "ammojs-typed";

window.addEventListener(`load`, main);

async function main() {
  const ammo = await Ammo();
  console.log(ammo);
}

I thought that Ammo.then implementation might be different from what is needed to make await works, so I've tried to wrap it into the additional Promise:

import Ammo from "ammojs-typed";

window.addEventListener(`load`, main);

async function bool() {
  return new Promise(resolve => {
    Ammo.then(ammo => resolve(ammo));
  });
}

async function main() {
  const ammo = await boot();
  console.log(ammo);
}

But it still freeze the window.

Any thoughts on this?

@giniedp
Copy link
Owner

giniedp commented Jul 5, 2020

Thanks for pointing out. After digging around a bit i thinks the issue is, because the ammo object itself looks like a promise even after it has been initialized

calling Ammo() returns the ammo api object, which has a then method.

we can use the then method to run code after the module has been initialized

however, then resolves into the same api object, which still has a then method.

When we try to resolve ammo with a native promise, it runs into a resolve loop because the resolved object always looks like a promise which is then tried to be resolved.

One can see this with the following js snippet

var count = 10
var loop = {
  then: (fn) => {
    console.log(count)
    count--
    fn(count ? loop : count)
  }
}
Promise.resolve(loop).then((result) => console.log(result))

You could go around that by writing a custom ammo initializer routine for example

// my-ammo.ts
import Ammo from 'ammojs-typed'

let loader: Promise<{ ammo: typeof Ammo }>
export function loadAmmo(): Promise<{ ammo: typeof Ammo }> {
    loader = loader || new Promise((resolve) => {
        Ammo.apply(globalThis).then((api: typeof Ammo) => {
            return resolve({ ammo: api })
        })
    })
    return loader
}

and then use it from everywhere you need

// some-file.ts

import { loadAmmo } from 'my-ammo'

window.addEventListener(`load`, main);

async function main() {
    const { ammo } = await loadAmmo()
    console.log(ammo)
}

I would file an issue at the ammo.js repository. But maybe it is a general issue with emscripten libraries?!?

@giniedp
Copy link
Owner

giniedp commented Jul 5, 2020

its an emscripten issue emscripten-core/emscripten#5820

@giniedp giniedp closed this as completed in 467397a Jul 5, 2020
@giniedp
Copy link
Owner

giniedp commented Jul 5, 2020

the issue has been resolved at emscripten and ammo.js has been updated. I released a new version which now behaves as you would expect it.

@hopeless-programmer-online
Copy link
Author

Thanks!

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

No branches or pull requests

2 participants