-
Notifications
You must be signed in to change notification settings - Fork 595
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
Wrapped Napi-extracted functions into C++ shared_ptr<>
-s for easier lifetime management.
#182
base: main
Are you sure you want to change the base?
Conversation
shared_ptr<>
-s.shared_ptr<>
-s for easier lifetime management.
@KevinEady, @gabrielschulhof would probably make sense for one or both of you to take a look at this one. |
@KevinEady, @gabrielschulhof ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a really neat PR! I think as-is, it is a good example and starting point for people to work with. @dkorolev Please see review comments and let me know if you plan on making any changes
Some nitpicking though... perhaps the naming of the entities could be something different, as it is a little misleading in their current names.
NodeJSContext
-> AsyncCallContext
NodeJSFunction
-> AsyncCall
NodeJSContext::ExtractJSFunction
-> AsyncCallContext::CreateCall
...? I dunno, just a thought.
} | ||
static void PopulateArg(Napi::Env env, int input, napi_value& output) { output = Napi::Number::New(env, input); } | ||
static void PopulateArg(Napi::Env env, const std::string& input, napi_value& output) { output = Napi::String::New(env, input); } | ||
// NOTE(dkorolev): Add more type wrappers or find the right way to do it within Napi. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"the right way" ... perhaps something that uses Value::From
:
template <typename ValueType>
static void PopulateArg(Napi::Env env, ValueType input, napi_value& output) { output = Napi::Value::From(env, input); }
std::vector<napi_value> params; | ||
using tuple_t = decltype(args_as_tuple_to_copy); | ||
params.resize(std::tuple_size<tuple_t>::value); | ||
ArgsPopulator<tuple_t, 0, std::tuple_size<tuple_t>::value>::DoIt(env, args_as_tuple_to_copy, params); | ||
jsf.Call(params); | ||
// TODO(dkorolev): Process the return value as needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very neat implementation of "automagically" casting the C++ types to respective Napi::Value
s.
You mention "process the return value". Currently the operator()
returns void
, so yes, the caller (eg. f_odd(1,"one")
in your example) has no way of processing the return value of the JavaScript side.
The problem is that this is done asynchronously, so we can't return the immediate value. What about using an std::promise<Napi::Value>
from the return value of jsf.Call()
...? Just throwing some ideas out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Kevin!
Thanks for chiming in! I've refactored the code since, you may find this and this more complete.
On a grander scheme of things, I'm looking into tighter C++ <=> V8 coupling these days, both in my day job and as a pet project, and would be glad to be of help if we could join our efforts. There's an open problem we have right now (can't create a JavaScript object with several wrapped C++ functions as the fields of this JSON object without these fuctions being garbage-collected), and I'm looking forward to finding the time to take a deeper look.
Thanks,
Dima
class NodeJSContext final { | ||
private: | ||
struct Impl final { | ||
Napi::Env env_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We really don't recommend storing the Napi::Env
. You can access it from promise_.Env()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, thanks, C5T/Current#904.
@KevinEady wondering what the next step on this is? |
Hi @gengjiawen,
Was hoping for some feedback -- after experimenting with
node-addon-api
for a few days looks like I've managed to wrap the extracted functions into C++ objects that do not require explicit lifetime management. Would be grateful for your time, and about as grateful if you could point me to someone else who would be better suited and/or would have more time.A one-liner to run the code:
Results in:
The relevant JavaScript piece:
And the respective C++ one (the real code has comments, just pasting the cleaned up version here):