Skip to content

Commit 0e3701b

Browse files
authored
feat: add Ref (#29)
1 parent c2ac6b0 commit 0e3701b

12 files changed

Lines changed: 167 additions & 24 deletions

File tree

examples/basic/index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,13 @@ export declare function basic_function(left: number, right: number): number;
190190
*/
191191
export declare function create_function(): CallbackFunction;
192192

193+
/**
194+
* Creates a native reference to the callback, reads it back, and calls it with (1, 2)
195+
* @param cb - A callback function that takes two numbers and returns a number
196+
* @returns The result of calling cb(1, 2)
197+
*/
198+
export declare function call_function_with_reference(cb: CallbackFunction): number;
199+
193200
// ============== Thread Safe Function ==============
194201

195202
/**

examples/basic/src/hello.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const buffer = @import("buffer.zig");
1414
const arraybuffer = @import("arraybuffer.zig");
1515
const typedarray = @import("typedarray.zig");
1616
const dataview = @import("dataview.zig");
17+
const reference = @import("reference.zig");
1718

1819
pub const test_i32 = number.test_i32;
1920
pub const test_f32 = number.test_f32;
@@ -40,6 +41,7 @@ pub const return_nullable = object.return_nullable;
4041
pub const call_function = function.call_function;
4142
pub const basic_function = function.basic_function;
4243
pub const create_function = function.create_function;
44+
pub const call_function_with_reference = reference.call_function_with_reference;
4345

4446
pub const call_thread_safe_function = thread_safe_function.call_thread_safe_function;
4547

examples/basic/src/reference.zig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const napi = @import("napi");
2+
3+
const Args = struct { i32, i32 };
4+
5+
pub fn call_function_with_reference(env: napi.Env, cb: napi.Function(Args, i32)) !i32 {
6+
var reference = try cb.CreateRef();
7+
defer reference.Unref(env) catch @panic("Failed to unref reference");
8+
9+
const function = try reference.GetValue(env);
10+
return try function.Call(.{ 1, 2 });
11+
}

harmony_example/entry/src/main/cpp/types/libhello/Index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,13 @@ export declare function basic_function(left: number, right: number): number;
192192
*/
193193
export declare function create_function(): CallbackFunction;
194194

195+
/**
196+
* Creates a native reference to the callback, reads it back, and calls it with (1, 2)
197+
* @param cb - A callback function that takes two numbers and returns a number
198+
* @returns The result of calling cb(1, 2)
199+
*/
200+
export declare function call_function_with_reference(cb: CallbackFunction): number;
201+
195202
// ============== Thread Safe Function ==============
196203

197204
/**

src/napi.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const buffer = @import("./napi/wrapper/buffer.zig");
1111
const arraybuffer = @import("./napi/wrapper/arraybuffer.zig");
1212
const typedarray = @import("./napi/wrapper/typedarray.zig");
1313
const dataview = @import("./napi/wrapper/dataview.zig");
14+
const reference = @import("./napi/wrapper/reference.zig");
1415

1516
pub const napi_sys = @import("napi-sys");
1617
pub const Env = env.Env;
@@ -50,6 +51,12 @@ pub const Float64Array = typedarray.Float64Array;
5051
pub const BigInt64Array = typedarray.BigInt64Array;
5152
pub const BigUint64Array = typedarray.BigUint64Array;
5253
pub const DataView = dataview.DataView;
54+
pub const Reference = reference.Reference;
55+
pub const Ref = reference.Reference;
56+
pub fn FunctionRef(comptime Args: type, comptime Return: type) type {
57+
return reference.Reference(function.Function(Args, Return));
58+
}
59+
pub const ObjectRef = reference.Reference(value.Object);
5360

5461
pub const NODE_API_MODULE = module.NODE_API_MODULE;
5562
pub const NODE_API_MODULE_WITH_INIT = module.NODE_API_MODULE_WITH_INIT;

src/napi/util/helper.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ pub fn isDataView(comptime T: type) bool {
9292
return @hasDecl(T, "is_napi_dataview");
9393
}
9494

95+
pub fn isReference(comptime T: type) bool {
96+
return @hasDecl(T, "is_napi_reference");
97+
}
98+
9599
pub fn isArrayList(comptime T: type) bool {
96100
const info = @typeInfo(T);
97101
if (info != .@"struct") {

src/napi/util/napi.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ pub const Napi = struct {
9898
if (comptime helper.isDataView(T)) {
9999
return T.from_raw(env, raw);
100100
}
101+
if (comptime helper.isReference(T)) {
102+
return T.from_napi_value(env, raw);
103+
}
101104

102105
if (comptime helper.isTuple(T)) {
103106
return NapiValue.Array.from_napi_value(env, raw, T);
@@ -210,6 +213,9 @@ pub const Napi = struct {
210213
if (comptime helper.isDataView(value_type)) {
211214
return value.raw;
212215
}
216+
if (comptime helper.isReference(value_type)) {
217+
return try value.to_napi_value(env);
218+
}
213219
if (comptime helper.isTuple(value_type)) {
214220
const array = try NapiValue.Array.New(Env.from_raw(env), value);
215221
return array.raw;

src/napi/value/function.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const Napi = @import("../util/napi.zig").Napi;
66
const NapiError = @import("../wrapper/error.zig");
77
const Undefined = @import("./undefined.zig").Undefined;
88
const GlobalAllocator = @import("../util/allocator.zig");
9+
const Reference = @import("../wrapper/reference.zig").Reference;
910

1011
pub fn Function(comptime Args: type, comptime Return: type) type {
1112
const ArgsInfos = @typeInfo(Args);
@@ -135,5 +136,9 @@ pub fn Function(comptime Args: type, comptime Return: type) type {
135136

136137
return Napi.from_napi_value(self.env, result, Return);
137138
}
139+
140+
pub fn CreateRef(self: Self) !Reference(Self) {
141+
return Reference(Self).New(Env.from_raw(self.env), self);
142+
}
138143
};
139144
}

src/napi/value/object.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const String = @import("./string.zig").String;
1111
const helper = @import("../util/helper.zig");
1212
const Napi = @import("../util/napi.zig").Napi;
1313
const NapiError = @import("../wrapper/error.zig");
14+
const Reference = @import("../wrapper/reference.zig").Reference;
1415

1516
pub const Object = struct {
1617
env: napi.napi_env,
@@ -158,4 +159,8 @@ pub const Object = struct {
158159
}
159160
return result;
160161
}
162+
163+
pub fn CreateRef(self: Object) !Reference(Object) {
164+
return Reference(Object).New(Env.from_raw(self.env), self);
165+
}
161166
};

src/napi/wrapper/dataview.zig

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ pub const DataView = struct {
6161
return DataView.from_raw(env.raw, raw);
6262
}
6363

64-
pub fn from_arraybuffer(env: Env, arraybuffer: ArrayBuffer, byte_offset: usize, byte_length: usize) !DataView {
65-
return DataView.fromArrayBuffer(env, arraybuffer, byte_offset, byte_length);
66-
}
67-
6864
pub fn New(env: Env, byte_length: usize) !DataView {
6965
const arraybuffer = try ArrayBuffer.New(env, byte_length);
7066
return DataView.fromArrayBuffer(env, arraybuffer, 0, byte_length);
@@ -75,19 +71,11 @@ pub const DataView = struct {
7571
return DataView.fromArrayBuffer(env, arraybuffer, 0, data.len);
7672
}
7773

78-
pub fn copy_from(env: Env, data: []const u8) !DataView {
79-
return DataView.copy(env, data);
80-
}
81-
8274
pub fn from(env: Env, data: []u8) !DataView {
8375
const arraybuffer = try ArrayBuffer.from(env, data);
8476
return DataView.fromArrayBuffer(env, arraybuffer, 0, data.len);
8577
}
8678

87-
pub fn from_data(env: Env, data: []u8) !DataView {
88-
return DataView.from(env, data);
89-
}
90-
9179
pub fn asSlice(self: DataView) []u8 {
9280
return self.data[0..self.byte_length];
9381
}

0 commit comments

Comments
 (0)