pmed / v8pp

Bind C++ functions and classes into V8 JavaScript engine
http://pmed.github.io/v8pp/
Other
898 stars 120 forks source link

Please go back in time and tell me about this project... #24

Closed xaxxon closed 8 years ago

xaxxon commented 8 years ago

before I did this:

https://github.com/xaxxon/v8toolkit

pmed commented 8 years ago

@xaxxon Your solution is viable, so why not to have another one :+1:

xaxxon commented 8 years ago

Do you have "static methods" working?

var = new SomeClass();

SomeClass.some_static_method(5); <=== This?

I'm trying to add this feature to v8toolkit but I'm having trouble figuring out the right sequence of prototypes and templates and....

On Mon, Jun 20, 2016 at 7:14 AM, Pavel Medvedev notifications@github.com wrote:

@xaxxon https://github.com/xaxxon Your solution is viable, so why not to have another one 👍

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pmed/v8pp/issues/24#issuecomment-227154302, or mute the thread https://github.com/notifications/unsubscribe/AAIycrG-c2g03rpNSSIeK31Qg8LJuaGeks5qNqBSgaJpZM4I5HLY .

pmed commented 8 years ago

Yes I have, see one of v8::class_::set() overloads, it accepts any callable - static member function, free function, lambda. And usage example in test_class.cpp

xaxxon commented 8 years ago

Ooh,does it DETECT that it's a static function automatically? It looks that way. I likeeee.

On Mon, Jun 20, 2016 at 1:44 PM, Pavel Medvedev notifications@github.com wrote:

Yes I have, see one of v8::class_::set() https://github.com/pmed/v8pp/blob/master/v8pp/class.hpp#L481-L490 overloads, it accepts any callable - static member function, free function, lambda. And usage example in test_class.cpp https://github.com/pmed/v8pp/blob/master/test/test_class.cpp#L63-L64

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pmed/v8pp/issues/24#issuecomment-227263627, or mute the thread https://github.com/notifications/unsubscribe/AAIycpJzSK6gSBwzPGoDOviPfClmhWYzks5qNvupgaJpZM4I5HLY .

pmed commented 8 years ago

As I remember a static member function and a free function have no differences from syntax point of view. Static one like a friend, but with name in its class scope.

xaxxon commented 8 years ago

Right, but in your example, you set both member functions and static functions with the same call:

    .set("rprop", v8pp::property(&X::get))
    .set("wprop", v8pp::property(&X::get, &X::set))
    .set("static_fun", &X::static_fun)
    .set("static_lambda", [](int x) { return x + 3; })

so .set detects if it the second parameter function wants a "this" or not and sets it as either a "member function" or "static function" based on that, right?

On Mon, Jun 20, 2016 at 2:15 PM, Pavel Medvedev notifications@github.com wrote:

As I remember a static member function and a free function have no differences from syntax point of view. Static one like a friend, but with name in its class scope.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pmed/v8pp/issues/24#issuecomment-227271778, or mute the thread https://github.com/notifications/unsubscribe/AAIyclA80Ibr_EtXQxqPa2KVSgtr3RfDks5qNwLsgaJpZM4I5HLY .

pmed commented 8 years ago

There are several overloads of class_::set() another one for member functions is above.

This is a SFINAE technique - to select a valid overloading of set() template function at compile time, depending on type of function its argument.

xaxxon commented 8 years ago

Have you done (or thought about doing) the ability to add a "class method" that's really just a lambda where the first parameter is a pointer to the wrapped c++ type?

like

wrap_class().add_method("some_method", [](MyClass * fake_this, ....whatever other parameters....){});

I'm considering it and it seems harmless...

Though I guess I am more descriptive with my names for adding things to the wrapped class. With just a "set" it wouldn't be possible to tell the difference between a "normal" function that wants any old MyClass * and a special "pretend like it's a method and the first parameter doesn't count as a normal parameter" version.

On Mon, Jun 20, 2016 at 3:15 PM, Pavel Medvedev notifications@github.com wrote:

There are several overloads of class_::set() another one for member functions https://github.com/pmed/v8pp/blob/master/v8pp/class.hpp#L470-L479 is above.

This is a SFINAE http://en.cppreference.com/w/cpp/language/sfinae technique - to select a valid overloading of set() template function at compile time, depending on type of function its argument.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pmed/v8pp/issues/24#issuecomment-227286435, or mute the thread https://github.com/notifications/unsubscribe/AAIyctQPN7JLmcE_H5EPrs8MmbCPBI4gks5qNxD1gaJpZM4I5HLY .

pmed commented 8 years ago

Yes, I thought about alternate API to describe bindings, like add_function, add_static_function, add_property, add_var etc.

xaxxon commented 8 years ago

Not sure how much you're still working on v8pp, but if you have any interest in collaborating on auto-generation of bindings via source code annotations, let me know.

I've got a reasonable start using libclang but could probably do better with someone to bounce some ideas off of. My prototype (mostly a hodge podge of stuff I've found online) is here: https://github.com/xaxxon/v8toolkit/blob/master/tools/class_parser.cpp

--Zac

Output of parsing some code looking for structs/classes with a particular annotation:

xaxxon$ ./run

Class/struct: Foo has an annotation

annotation value: v8toolkit_generate_bindings

Decl at line 8, file id: 1

Method: Foo::foo_method

static: 0 instance: 1 const: 0 volatile: 0 virtual: 0

Access specifier: private

Return type: void

Number input params: 2

Parameter 0: int *

Parameter 1: int

Method: Foo::foo_int_method

static: 0 instance: 1 const: 0 volatile: 0 virtual: 0

Access specifier: public

Return type: int

Number input params: 2

Parameter 0: char *

Parameter 1: char

Class/struct: FooStruct has an annotation

annotation value: v8toolkit_generate_bindings

Decl at line 14, file id: 1

Method: FooStruct::foostruct_method

static: 0 instance: 1 const: 0 volatile: 0 virtual: 0

Access specifier: public

Return type: void

Number input params: 2

Parameter 0: double

Parameter 1: float

Method: FooStruct::foostruct_char_method

static: 0 instance: 1 const: 0 volatile: 0 virtual: 0

Access specifier: private

Return type: char

Number input params: 1

Parameter 0: const std::string &

On Mon, Jun 20, 2016 at 11:49 PM, Pavel Medvedev notifications@github.com wrote:

Yes, I thought about alternate API to describe bindings, like add_function, add_static_function, add_property, add_var etc.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pmed/v8pp/issues/24#issuecomment-227354861, or mute the thread https://github.com/notifications/unsubscribe/AAIycldGXZ9R2gRARhWgQhNEVI4crTCPks5qN4mGgaJpZM4I5HLY .

pmed commented 8 years ago

Currently I prefer to control the code in both languages. But I'm not a big fan of automatic code generation, so I can be wrong.

I thought about auto-generation of bindings from C++ source code some time ago. The main challenge which I see: there is no multi-threading in JavaScript language in contrast to C++ language. It is possible in theory, to annotate that some C++ code should be performed asynchronously (maybe in some thread pool), and to call a JS callback on error/success (either to return a Promise in modern JS).

xaxxon commented 8 years ago

Well, there are opportunities for things other than code generation -- it could easily be made to do validation only -- you could do something that tests if every function in a class is either bound to a javascript call or explicitly marked as skipped. Sort of like the compiler warnings you get when you don't put all the elements of an enum in a switch statement in c++.

While that wouldn't be that big a deal for a more stable API, it would be quite helpful for for a code base under active development, which is what I'm struggling with right now and is my motivation for looking into this.

Also, at least with my API, you have to mark the parent types as being related to their derived types for inheritance to work correctly, which is error prone, but I couldn't figure out a way around that. This would allow for generating or checking that relationship automatically.

Anyhow, if it ever seems interesting to you, you can always look at that link later and hopefully it will be in better shape :)

--Zac

On Fri, Jun 24, 2016 at 11:13 AM, Pavel Medvedev notifications@github.com wrote:

Currently I prefer to control the code in both languages. But I'm not a big fan of automatic code generation, so I can be wrong.

I thought about auto-generation of bindings from C++ source code some time ago. The main challenge which I see: there is no multi-threading in JavaScript language in contrast to C++ language. It is possible in theory, to annotate that some C++ code should be performed asynchronously (maybe in some thread pool), and to call a JS callback on error/success (either to return a Promise in modern JS).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pmed/v8pp/issues/24#issuecomment-228419754, or mute the thread https://github.com/notifications/unsubscribe/AAIycrizwrRW1NdhL46UKX-XA9DI5Kqkks5qPB5jgaJpZM4I5HLY .

pmed commented 8 years ago

Libclang is also used in https://github.com/foonathan/standardese to parse C++ source code. Maybe that project will be useful how to use libclang.