WIP: Implements class in napi-go #10
71
function.go
71
function.go
@@ -6,19 +6,44 @@ import (
|
||||
"sirherobrine23.com.br/Sirherobrine23/napi-go/internal/napi"
|
||||
)
|
||||
|
||||
type Function struct{ value }
|
||||
type Function struct {
|
||||
value
|
||||
fn napi.Callback
|
||||
}
|
||||
|
||||
// Function to call on Javascript caller
|
||||
type Callback func(env EnvType, this ValueType, args []ValueType) (ValueType, error)
|
||||
type Callback func(*CallbackInfo) (ValueType, error)
|
||||
|
||||
// Values from [napi.CallbackInfo]
|
||||
type CallbackInfo struct {
|
||||
Env EnvType
|
||||
This ValueType
|
||||
Args []ValueType
|
||||
|
||||
info napi.CallbackInfo
|
||||
}
|
||||
|
||||
func (call *CallbackInfo) NewTarget() (ValueType, error) {
|
||||
v, status := napi.GetNewTarget(call.Env.NapiValue(), call.info)
|
||||
if err := status.ToError(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N_APIValue(call.Env, v), nil
|
||||
}
|
||||
|
||||
// Convert [ValueType] to [*Function]
|
||||
func ToFunction(o ValueType) *Function { return &Function{o} }
|
||||
func ToFunction(o ValueType) *Function { return &Function{o, nil} }
|
||||
|
||||
// CreateFunction creates a new JavaScript function in the given N-API environment with the specified name and callback.
|
||||
// The callback is invoked when the JavaScript function is called, receiving a CallbackInfo containing the environment,
|
||||
// 'this' value, arguments, and callback info. Any errors returned by the callback or panics are converted to JavaScript
|
||||
// exceptions. If the callback returns nil, the JavaScript 'undefined' value is returned. If the callback returns a value
|
||||
// of TypeError, it is thrown as a JavaScript exception.
|
||||
func CreateFunction(env EnvType, name string, callback Callback) (*Function, error) {
|
||||
return CreateFunctionNapi(env, name, func(napiEnv napi.Env, info napi.CallbackInfo) napi.Value {
|
||||
env := N_APIEnv(napiEnv)
|
||||
cbInfo, err := napi.GetCbInfo(napiEnv, info)
|
||||
if err := err.ToError(); err != nil {
|
||||
cbInfo, status := napi.GetCbInfo(napiEnv, info)
|
||||
if err := status.ToError(); err != nil {
|
||||
ThrowError(env, "", err.Error())
|
||||
return nil
|
||||
}
|
||||
@@ -40,23 +65,21 @@ func CreateFunction(env EnvType, name string, callback Callback) (*Function, err
|
||||
}
|
||||
}()
|
||||
|
||||
{
|
||||
res, err := callback(env, this, args)
|
||||
switch {
|
||||
case err != nil:
|
||||
ThrowError(env, "", err.Error())
|
||||
res, err := callback(&CallbackInfo{env, this, args, info})
|
||||
switch {
|
||||
case err != nil:
|
||||
ThrowError(env, "", err.Error())
|
||||
return nil
|
||||
case res == nil:
|
||||
und, _ := env.Undefined()
|
||||
return und.NapiValue()
|
||||
default:
|
||||
typeOf, _ := res.Type()
|
||||
if typeOf == TypeError {
|
||||
ToError(res).ThrowAsJavaScriptException()
|
||||
return nil
|
||||
case res == nil:
|
||||
und, _ := env.Undefined()
|
||||
return und.NapiValue()
|
||||
default:
|
||||
typeOf, _ := res.Type()
|
||||
if typeOf == TypeError {
|
||||
ToError(res).ThrowAsJavaScriptException()
|
||||
return nil
|
||||
}
|
||||
return res.NapiValue()
|
||||
}
|
||||
return res.NapiValue()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -67,7 +90,13 @@ func CreateFunctionNapi(env EnvType, name string, callback napi.Callback) (*Func
|
||||
if err := err.ToError(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ToFunction(N_APIValue(env, fnCall)), nil
|
||||
fn := ToFunction(N_APIValue(env, fnCall))
|
||||
fn.fn = callback
|
||||
return fn, nil
|
||||
}
|
||||
|
||||
func (fn *Function) NapiCallback() napi.Callback {
|
||||
return fn.fn
|
||||
}
|
||||
|
||||
func (fn *Function) internalCall(this napi.Value, argc int, argv []napi.Value) (ValueType, error) {
|
||||
|
@@ -14,7 +14,7 @@ var waitTime = time.Second * 3
|
||||
|
||||
//go:linkname Register sirherobrine23.com.br/Sirherobrine23/napi-go/module.Register
|
||||
func Register(env napi.EnvType, export *napi.Object) {
|
||||
fn, _ := napi.CreateFunction(env, "", func(env napi.EnvType, _ napi.ValueType, args []napi.ValueType) (napi.ValueType, error) {
|
||||
fn, _ := napi.CreateFunction(env, "", func(ci *napi.CallbackInfo) (napi.ValueType, error) {
|
||||
var Test *napi.String
|
||||
return napi.CreateAsyncWorker(env,
|
||||
func(env napi.EnvType) {
|
||||
|
@@ -12,12 +12,12 @@ import (
|
||||
|
||||
//go:linkname Register sirherobrine23.com.br/Sirherobrine23/napi-go/module.Register
|
||||
func Register(env napi.EnvType, export *napi.Object) {
|
||||
jsFunc := napi.Callback(func(env napi.EnvType, this napi.ValueType, args []napi.ValueType) (napi.ValueType, error) {
|
||||
jsFunc := napi.Callback(func(ci *napi.CallbackInfo) (napi.ValueType, error) {
|
||||
var waitTime = time.Second * 3
|
||||
|
||||
if len(args) == 1 {
|
||||
if typof, _ := args[0].Type(); typof == napi.TypeNumber {
|
||||
wait := napi.As[*napi.Number](args[0])
|
||||
if len(ci.Args) == 1 {
|
||||
if typof, _ := ci.Args[0].Type(); typof == napi.TypeNumber {
|
||||
wait := napi.As[*napi.Number](ci.Args[0])
|
||||
_waitTime, _ := wait.Int()
|
||||
waitTime = time.Duration(_waitTime)
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ func funcOf(env EnvType, ptr reflect.Value) (ValueType, error) {
|
||||
case internalNapi.Callback: // return internal/napi function value
|
||||
return CreateFunctionNapi(env, funcName, v)
|
||||
default: // Convert go function to javascript function
|
||||
return CreateFunction(env, funcName, func(env EnvType, this ValueType, args []ValueType) (ValueType, error) {
|
||||
return CreateFunction(env, funcName, func(ci *CallbackInfo) (ValueType, error) {
|
||||
var goFnReturn []reflect.Value
|
||||
in, out, veridict := ptr.Type().NumIn(), ptr.Type().NumOut(), ptr.Type().IsVariadic()
|
||||
|
||||
@@ -46,9 +46,9 @@ func funcOf(env EnvType, ptr reflect.Value) (ValueType, error) {
|
||||
case in == 0 && out == 0: // only call
|
||||
goFnReturn = ptr.Call([]reflect.Value{})
|
||||
case !veridict: // call same args
|
||||
goFnReturn = ptr.Call(goValuesInFunc(ptr, args, false))
|
||||
goFnReturn = ptr.Call(goValuesInFunc(ptr, ci.Args, false))
|
||||
default: // call with slice on end
|
||||
goFnReturn = ptr.CallSlice(goValuesInFunc(ptr, args, true))
|
||||
goFnReturn = ptr.CallSlice(goValuesInFunc(ptr, ci.Args, true))
|
||||
}
|
||||
|
||||
// Check for last element is error
|
||||
|
Reference in New Issue
Block a user