feat(napi): new JsFunction instance

This commit is contained in:
LongYinan 2020-10-27 14:19:40 +08:00
parent 77f4892cb9
commit 6ba674e4bc
No known key found for this signature in database
GPG key ID: A3FFE134A3E20881
4 changed files with 45 additions and 1 deletions

View file

@ -85,9 +85,10 @@ pub fn js_function(attr: TokenStream, input: TokenStream) -> TokenStream {
let new_fn_name = signature.ident.clone();
let execute_js_function = get_execute_js_code(new_fn_name, FunctionKind::JsFunction);
let expanded = quote! {
#[inline]
#[inline(always)]
#signature #(#fn_block)*
#[inline(always)]
#visibility extern "C" fn #fn_name(
raw_env: napi::sys::napi_env,
cb_info: napi::sys::napi_callback_info,

View file

@ -55,4 +55,28 @@ impl JsFunction {
JsUnknown::from_raw(self.0.env, return_value)
}
/// https://nodejs.org/api/n-api.html#n_api_napi_new_instance
/// This method is used to instantiate a new `JavaScript` value using a given `JsFunction` that represents the constructor for the object.
pub fn new<V>(&self, args: &[V]) -> Result<JsObject>
where
V: NapiValue,
{
let mut js_instance = ptr::null_mut();
let length = args.len() as u64;
let raw_args = args
.iter()
.map(|arg| arg.raw())
.collect::<Vec<sys::napi_value>>();
check_status(unsafe {
sys::napi_new_instance(
self.0.env,
self.0.value,
length,
raw_args.as_ptr(),
&mut js_instance,
)
})?;
Ok(JsObject::from_raw_unchecked(self.0.env, js_instance))
}
}

View file

@ -19,3 +19,8 @@ test('should be able to manipulate wrapped native value', (t) => {
const add = 101
t.is(testClass.addNativeCount(add), fixture + add + 100)
})
test('should be able to new class instance in native side', (t) => {
const instance = bindings.newTestClass()
t.is(instance.count, 42)
})

View file

@ -45,7 +45,21 @@ fn add_native_count(ctx: CallContext) -> Result<JsNumber> {
ctx.env.create_int32(native_class.value)
}
#[js_function(1)]
fn new_test_class(ctx: CallContext) -> Result<JsObject> {
let add_count_method = Property::new(&ctx.env, "addCount")?.with_method(add_count);
let add_native_count = Property::new(&ctx.env, "addNativeCount")?.with_method(add_native_count);
let properties = vec![add_count_method, add_native_count];
let test_class =
ctx
.env
.define_class("TestClass", test_class_constructor, properties.as_slice())?;
test_class.new(&vec![ctx.env.create_int32(42)?])
}
pub fn register_js(module: &mut Module) -> Result<()> {
module.create_named_method("createTestClass", create_test_class)?;
module.create_named_method("newTestClass", new_test_class)?;
Ok(())
}