Created
July 27, 2022 01:11
-
-
Save jackalcooper/76249a52eb576afa15928c7ede5fa415 to your computer and use it in GitHub Desktop.
Zig managed NIF resource
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub fn ResourceKind(comptime ElementType: type, module_name: anytype) type { | |
return struct { | |
pub const T = ElementType; | |
pub const module_name = module_name; | |
pub const resource = struct { | |
pub var t: resource_type = undefined; | |
pub const name = @typeName(ElementType); | |
pub fn make(environment: env, value: T) !term { | |
return make_resource(environment, value, t); | |
} | |
pub fn fetch(environment: env, arg: term) !T { | |
return fetch_resource(T, environment, t, arg); | |
} | |
pub fn fetch_ptr(environment: env, arg: term) !*T { | |
return fetch_resource_ptr(T, environment, t, arg); | |
} | |
}; | |
const PtrType = [*c]ElementType; | |
pub const Ptr = struct { | |
pub const T = PtrType; | |
pub const resource = struct { | |
pub var t: resource_type = undefined; | |
pub const name = @typeName(PtrType); | |
pub fn make(environment: env, value: PtrType) !term { | |
return make_resource(environment, value, t); | |
} | |
pub fn fetch(environment: env, arg: term) !PtrType { | |
return fetch_resource(PtrType, environment, t, arg); | |
} | |
}; | |
}; | |
const ArrayType = [*c]const ElementType; | |
pub const Array = struct { | |
pub const T = ArrayType; | |
pub const resource = struct { | |
pub var t: resource_type = undefined; | |
pub const name = @typeName(ArrayType); | |
pub fn make(environment: env, value: ArrayType) !term { | |
return make_resource(environment, value, t); | |
} | |
pub fn fetch(environment: env, arg: term) !ArrayType { | |
return fetch_resource(ArrayType, environment, t, arg); | |
} | |
}; | |
}; | |
fn ptr(environment: env, _: c_int, args: [*c]const term) callconv(.C) term { | |
return get_resource_ptr_from_term(T, environment, @This().resource.t, Ptr.resource.t, args[0]) catch return make_error_binary(environment, "fail to create ptr " ++ @typeName(T)); | |
} | |
pub fn opaque_ptr(environment: env, _: c_int, args: [*c]const term) callconv(.C) term { | |
const ptr_to_resource_memory: Ptr.T = fetch_resource_ptr(T, environment, @This().resource.t, args[0]) catch return make_error_binary(environment, "fail to create ptr " ++ @typeName(T)); | |
return InternalOpaquePtr.resource.make(environment, ptr_to_resource_memory) catch return make_error_binary(environment, "fail to make resource for: " ++ @typeName(InternalOpaquePtr.T)); | |
} | |
fn array(environment: env, _: c_int, args: [*c]const term) callconv(.C) term { | |
return get_resource_array_from_list(T, environment, @This().resource.t, Array.resource.t, args[0]) catch return make_error_binary(environment, "fail to create array " ++ @typeName(T)); | |
} | |
fn mut_array(environment: env, _: c_int, args: [*c]const term) callconv(.C) term { | |
return get_resource_array_from_list(T, environment, @This().resource.t, Ptr.resource.t, args[0]) catch return make_error_binary(environment, "fail to create mut array " ++ @typeName(T)); | |
} | |
fn primitive(environment: env, _: c_int, args: [*c]const term) callconv(.C) term { | |
const v = resource.fetch(environment, args[0]) catch return make_error_binary(environment, "fail to extract pritimive from " ++ @typeName(T)); | |
return make(T, environment, v) catch return make_error_binary(environment, "fail to create primitive " ++ @typeName(T)); | |
} | |
fn make_(environment: env, _: c_int, args: [*c]const term) callconv(.C) term { | |
const v = get(T, environment, args[0]) catch return make_error_binary(environment, "fail to fetch " ++ @typeName(T)); | |
return resource.make(environment, v) catch return make_error_binary(environment, "fail to create " ++ @typeName(T)); | |
} | |
pub const nifs = .{ | |
e.ErlNifFunc{ .name = module_name ++ ".ptr", .arity = 1, .fptr = ptr, .flags = 0 }, | |
e.ErlNifFunc{ .name = module_name ++ ".opaque_ptr", .arity = 1, .fptr = opaque_ptr, .flags = 0 }, | |
e.ErlNifFunc{ .name = module_name ++ ".array", .arity = 1, .fptr = array, .flags = 0 }, | |
e.ErlNifFunc{ .name = module_name ++ ".mut_array", .arity = 1, .fptr = mut_array, .flags = 0 }, | |
e.ErlNifFunc{ .name = module_name ++ ".primitive", .arity = 1, .fptr = primitive, .flags = 0 }, | |
e.ErlNifFunc{ .name = module_name ++ ".make", .arity = 1, .fptr = make_, .flags = 0 }, | |
}; | |
pub fn open(environment: env) void { | |
@This().resource.t = e.enif_open_resource_type(environment, null, @This().resource.name, destroy_do_nothing, e.ERL_NIF_RT_CREATE | e.ERL_NIF_RT_TAKEOVER, null); | |
} | |
pub fn open_ptr(environment: env) void { | |
@This().Ptr.resource.t = e.enif_open_resource_type(environment, null, @This().Ptr.resource.name, destroy_do_nothing, e.ERL_NIF_RT_CREATE | e.ERL_NIF_RT_TAKEOVER, null); | |
} | |
pub fn open_array(environment: env) void { | |
@This().Array.resource.t = e.enif_open_resource_type(environment, null, @This().Array.resource.name, destroy_do_nothing, e.ERL_NIF_RT_CREATE | e.ERL_NIF_RT_TAKEOVER, null); | |
} | |
pub fn open_all(environment: env) void { | |
open(environment); | |
open_ptr(environment); | |
open_array(environment); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment