WIP: Implements class in napi-go #10
79
class.go
Normal file
79
class.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package napi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"sirherobrine23.com.br/Sirherobrine23/napi-go/internal/napi"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
PropertyDescriptor = napi.PropertyDescriptor
|
||||||
|
|
||||||
|
ClassType interface {
|
||||||
|
Contructor(env EnvType, this ValueType, args []ValueType) (*Object, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
Class[T ClassType] struct {
|
||||||
|
value
|
||||||
|
Class T
|
||||||
|
classReflect reflect.Type
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PropertyAttributesDefault = napi.Default
|
||||||
|
PropertyAttributesWritable = napi.Writable
|
||||||
|
PropertyAttributesEnumerable = napi.Enumerable
|
||||||
|
PropertyAttributesConfigurable = napi.Configurable
|
||||||
|
PropertyAttributesStatic = napi.Static
|
||||||
|
PropertyAttributesDefaultMethod = napi.DefaultMethod
|
||||||
|
PropertyAttributesDefaultJSProperty = napi.DefaultJSProperty
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateClass[T ClassType](env EnvType, propertys []PropertyDescriptor) (*Class[T], error) {
|
||||||
|
ptrType := reflect.TypeFor[T]()
|
||||||
|
switch ptrType.Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
case reflect.Pointer:
|
||||||
|
if ptrType = ptrType.Elem(); ptrType.Kind() != reflect.Struct {
|
||||||
|
return nil, fmt.Errorf("type %s is not a struct", ptrType.Name())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("type %s is not a struct", ptrType.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
startStruct := &Class[T]{classReflect: ptrType}
|
||||||
|
value, status := napi.DefineClass(env.NapiValue(), ptrType.Name(),
|
||||||
|
func(env napi.Env, info napi.CallbackInfo) napi.Value {
|
||||||
|
startStruct.Class = reflect.New(ptrType).Interface().(T)
|
||||||
|
cbInfo, status := napi.GetCbInfo(env, info)
|
||||||
|
if err := status.ToError(); err != nil {
|
||||||
|
ThrowError(N_APIEnv(env), "", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
gonapiEnv := N_APIEnv(env)
|
||||||
|
this := N_APIValue(gonapiEnv, cbInfo.This)
|
||||||
|
args := make([]ValueType, len(cbInfo.Args))
|
||||||
|
for i, cbArg := range cbInfo.Args {
|
||||||
|
args[i] = N_APIValue(gonapiEnv, cbArg)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := startStruct.Class.Contructor(gonapiEnv, this, args)
|
||||||
|
if err != nil {
|
||||||
|
ThrowError(gonapiEnv, "", err.Error())
|
||||||
|
} else if res == nil {
|
||||||
|
und, _ := gonapiEnv.Undefined()
|
||||||
|
return und.NapiValue()
|
||||||
|
}
|
||||||
|
napi.Wrap(env, res.NapiValue(), unsafe.Pointer(startStruct), nil, nil)
|
||||||
|
return res.NapiValue()
|
||||||
|
}, propertys)
|
||||||
|
if err := status.ToError(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
startStruct.value = N_APIValue(env, value)
|
||||||
|
return startStruct, nil
|
||||||
|
}
|
29
internal/examples/class/main.go
Normal file
29
internal/examples/class/main.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
_ "sirherobrine23.com.br/Sirherobrine23/napi-go/entry"
|
||||||
|
|
||||||
|
"sirherobrine23.com.br/Sirherobrine23/napi-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
|
||||||
|
//go:linkname Register sirherobrine23.com.br/Sirherobrine23/napi-go/entry.Register
|
||||||
|
func Register(env napi.EnvType, export *napi.Object) {
|
||||||
|
class, err := napi.CreateClass[*ClassTest](env, []napi.PropertyDescriptor{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
export.Set("class", class)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClassTest struct{}
|
||||||
|
|
||||||
|
func (class *ClassTest) Contructor(env napi.EnvType, this napi.ValueType, args []napi.ValueType) (*napi.Object, error) {
|
||||||
|
obj, _ := napi.CreateObject(env)
|
||||||
|
|
||||||
|
return obj, nil
|
||||||
|
}
|
27
internal/napi/class.go
Normal file
27
internal/napi/class.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package napi
|
||||||
|
|
||||||
|
// #include <node/node_api.h>
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func DefineClass(env Env, name string, constructor Callback, Property []PropertyDescriptor) (Value, Status) {
|
||||||
|
var pro *C.napi_property_descriptor
|
||||||
|
if len(Property) > 0 {
|
||||||
|
pro = (*C.napi_property_descriptor)(unsafe.Pointer(&Property[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
var result Value
|
||||||
|
call := &constructor
|
||||||
|
status := Status(C.napi_define_class(
|
||||||
|
C.napi_env(env),
|
||||||
|
C.CString(name),
|
||||||
|
C.size_t(len(name)),
|
||||||
|
C.napi_callback(unsafe.Pointer(call)),
|
||||||
|
nil,
|
||||||
|
C.size_t(len(Property)),
|
||||||
|
pro,
|
||||||
|
(*C.napi_value)(unsafe.Pointer(&result)),
|
||||||
|
))
|
||||||
|
return result, status
|
||||||
|
}
|
Reference in New Issue
Block a user