ted537 / tsembind

Generate typescript bindings for Embind projects
23 stars 3 forks source link

Support symbol methods #11

Closed JeanChristopheMorinPerso closed 1 year ago

JeanChristopheMorinPerso commented 1 year ago

This PR adds support for bound functions (method) that start with @@. Embind converts these methods into [Symbol.<method>] as documented at https://emscripten.org/docs/api_reference/bind.h.html#_CPPv4NK6class_8functionEv.

ted537 commented 1 year ago

Cool! So defining a @@iterator method in the C++ Embind lines lets us do for (const entry of object) { ... } in JS. Do I have that right?

JeanChristopheMorinPerso commented 1 year ago

Almost! In practice, it looks like this:

// Iterator
ems::class_<CustomIterator>("CustomIterator")
    .function("next", &CustomIterator::next);

// Object that you want to iterate on
ems::class_<IterableObject>("IterableObject")
    .constructor<>()
    .function(
        "@@iterator",
        ems::optional_override([](IterableObject* sc) {
            return new CustomIterator(sc);
        }),
        ems::allow_raw_pointers())

And then in JS:

const myObject = new IterableObject();
for (const item of myObject) {
    // ...
}

Your object basically has to adhere to iterable protocol. The returned value of @@iterator needs to adhere to the iterator protocol.

JeanChristopheMorinPerso commented 1 year ago

The alternative to using @@ is to use EM_ASM:

EM_ASM(
    Module['IterableObject']['prototype'][Symbol.iterator] = function() { ... };
);

Which is not great because this wouldn't be exposed in the TS declarations.

ted537 commented 1 year ago

Right of course, that makes sense. Ok looks good! Thanks Jean!