energy/cef/cef-v8-value.go

413 lines
9.8 KiB
Go
Raw Normal View History

2022-10-04 13:21:05 +08:00
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
// Licensed under Apache License Version 2.0, January 2004
//
// https://www.apache.org/licenses/LICENSE-2.0
2022-10-04 13:21:05 +08:00
//
//----------------------------------------
2023-02-20 14:42:17 +08:00
// V8 JSValue js绑定实现
2022-10-04 13:21:05 +08:00
package cef
import (
"errors"
"fmt"
"github.com/energye/energy/common"
2022-10-04 22:34:57 +08:00
. "github.com/energye/energy/consts"
"github.com/energye/energy/logger"
2022-10-04 13:21:05 +08:00
"github.com/energye/golcl/lcl/api"
"reflect"
"sync"
"unsafe"
)
type valueBindInfo struct {
Name uintptr //string 字段名称
EventId uintptr //
BindType uintptr //int32 变量类型 0:string 1:int 2:double 3:bool 4:null 5:undefined 6:object 7:array 8:function
FnInNum uintptr //int32 入参个数
FnInParamType uintptr //string 入参变量类型 0,1,2,3,1
FnOutNum uintptr //int32 出参个数
FnOutParamType uintptr //string 出参变量类型
}
2023-02-21 23:16:35 +08:00
// V8Value 绑定到JS的字段
type V8Value struct {
2023-02-22 12:31:35 +08:00
eventId uintptr //事件ID
2023-03-05 12:31:33 +08:00
instance unsafe.Pointer //
2023-02-22 12:31:35 +08:00
name string //用于字段或函数名
value interface{} //值
valueType *VT //字段类型go 和 js
funcInfo *funcInfo //普通函数信息
sfi *functionInfo //对象函数信息
isCommonObject IS_CO //通用类型或对象类型 默认通用类型
that JSValue //
2023-03-05 12:31:33 +08:00
rwLock sync.Mutex //字段|函数独有锁
2022-10-04 13:21:05 +08:00
}
2023-02-20 14:42:17 +08:00
// CEFv8BindRoot 导出给JavaScript window的根对象名
2022-10-04 13:21:05 +08:00
type CEFv8BindRoot struct {
2023-02-21 23:16:35 +08:00
commonRootName string //V8Value 通用类型变量属性的所属默认对象名称
objectRootName string //V8Value 对象类型变量属性的所属默认对象名称
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
// checkFunc 检查函数是否导出, 返回:函数描述信息
2022-10-04 13:21:05 +08:00
func checkFunc(fnOf reflect.Type, fnType FN_TYPE) (*funcInfo, error) {
2023-03-05 12:31:33 +08:00
numIn := fnOf.NumIn() - int(fnType) // 结构函数的参数-1后才是入参
2022-10-04 13:21:05 +08:00
numOut := fnOf.NumOut()
2023-03-05 12:31:33 +08:00
//if numOut > BIND_FUNC_OUT_MAX_SUM {
// //出参个数超出
// return nil, errors.New(fmt.Sprintf("WindowBind function parameter error: the maximum number of function parameters is %d, but the actual number is %d", BIND_FUNC_OUT_MAX_SUM, numOut))
//}
//if numIn > BIND_FUNC_IN_MAX_SUM {
// //入参个数超出
// return nil, errors.New(fmt.Sprintf("WindowBind function parameter error: up to %d function input parameters, actually %d", BIND_FUNC_IN_MAX_SUM, numIn))
//}
2023-02-22 19:10:24 +08:00
if numIn < 0 {
numIn = 0
}
2022-10-04 13:21:05 +08:00
r := new(funcInfo)
r.InNum = int32(numIn)
r.OutNum = int32(numOut)
2023-02-22 12:31:35 +08:00
r.InParam = make([]*VT, numIn, numIn)
2022-10-04 13:21:05 +08:00
r.FnType = fnType
var idx = 0
for i := 0; i < numIn; i++ {
idx = i + int(fnType)
2023-02-22 19:10:24 +08:00
inTyp := fnOf.In(idx).Kind()
2023-03-05 12:31:33 +08:00
if gov, jsv := common.FieldReflectType(inTyp); jsv == -1 || gov == -1 {
//入参参数类型不支持
return nil, errors.New("input parameter type mismatch")
2022-10-04 13:21:05 +08:00
} else {
2023-02-22 12:31:35 +08:00
r.InParam[i] = &VT{Jsv: jsv, Gov: gov}
2022-10-04 13:21:05 +08:00
}
}
2023-03-05 12:31:33 +08:00
r.OutParam = make([]*VT, numOut, numOut)
for i := 0; i < numOut; i++ {
outTyp := fnOf.Out(i)
if gov, jsv := common.FieldReflectType(outTyp.Kind()); jsv == -1 || gov == -1 {
//出参参数类型不支持
return nil, errors.New("out parameter type mismatch")
} else {
r.OutParam[i] = &VT{Jsv: jsv, Gov: gov}
r.OutParamIdx = int32(i)
2022-10-04 13:21:05 +08:00
}
}
return r, nil
}
2023-02-20 14:42:17 +08:00
// Lock 每一个变量的独有锁 - 加锁
2023-02-21 23:16:35 +08:00
func (m *V8Value) Lock() {
2022-10-04 13:21:05 +08:00
m.rwLock.Lock()
}
2023-02-20 14:42:17 +08:00
// UnLock 每一个变量的独有锁 - 解锁
2023-02-21 23:16:35 +08:00
func (m *V8Value) UnLock() {
2022-10-04 13:21:05 +08:00
m.rwLock.Unlock()
}
2023-02-21 23:16:35 +08:00
// V8Value isCommon
func (m *V8Value) isCommon() bool {
2022-10-04 13:21:05 +08:00
return m.isCommonObject == IS_COMMON
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) setThat(that JSValue) {
2022-10-04 13:21:05 +08:00
m.that = that
}
2023-02-20 14:42:17 +08:00
// Bytes 值转换为字节
2023-02-21 23:16:35 +08:00
func (m *V8Value) Bytes() []byte {
2022-10-04 13:21:05 +08:00
var iValue interface{}
if m.isCommon() {
iValue = m.value
} else { //object
if refValue, ok := m.value.(*reflect.Value); ok {
iValue = refValue.Interface()
} else {
return nil
}
}
2023-02-22 12:31:35 +08:00
switch m.valueType.Jsv {
2022-10-04 13:21:05 +08:00
case V8_VALUE_STRING:
return common.StringToBytes(iValue.(string))
2022-10-04 13:21:05 +08:00
case V8_VALUE_INT:
if v, err := common.ValueToInt32(iValue); err == nil {
return common.Int32ToBytes(v)
2022-10-04 13:21:05 +08:00
} else {
return nil
}
case V8_VALUE_DOUBLE:
if v, err := common.ValueToFloat64(iValue); err == nil {
return common.Float64ToBytes(v)
2022-10-04 13:21:05 +08:00
} else {
return nil
}
case V8_VALUE_BOOLEAN:
if v, err := common.ValueToBool(iValue); err == nil {
return []byte{common.BoolToByte(v)}
2022-10-04 13:21:05 +08:00
} else {
return nil
}
default:
return nil
}
}
2023-02-20 14:42:17 +08:00
// ValueToPtr 转换为指针
2023-02-21 23:16:35 +08:00
func (m *V8Value) ValueToPtr() (unsafe.Pointer, error) {
2022-10-04 13:21:05 +08:00
var iValue interface{}
if m.isCommon() {
iValue = m.value
} else { //object
if refValue, ok := m.value.(*reflect.Value); ok {
iValue = refValue.Interface()
} else {
return nil, errors.New("object转换reflect.Value失败")
}
}
2023-02-22 12:31:35 +08:00
switch m.valueType.Jsv {
2022-10-04 13:21:05 +08:00
case V8_VALUE_STRING:
2022-12-03 21:56:51 +08:00
return unsafe.Pointer(api.PascalStr(iValue.(string))), nil
2022-10-04 13:21:05 +08:00
//return GoStrToDStrPointer(iValue.(string)), nil
case V8_VALUE_INT:
if v, err := common.ValueToInt32(iValue); err == nil {
2022-10-04 13:21:05 +08:00
return unsafe.Pointer(uintptr(v)), nil
} else {
return nil, err
}
case V8_VALUE_DOUBLE:
if v, err := common.ValueToFloat64(iValue); err == nil {
2022-10-04 13:21:05 +08:00
return unsafe.Pointer(&v), nil
} else {
return nil, err
}
case V8_VALUE_BOOLEAN:
if v, err := common.ValueToBool(iValue); err == nil {
2022-12-03 21:56:51 +08:00
return unsafe.Pointer(api.PascalBool(v)), nil
2022-10-04 13:21:05 +08:00
} else {
return nil, err
}
default:
return nil, errors.New("unsupported type")
}
}
2023-02-20 14:42:17 +08:00
// SetAnyValue 设置多类型值
2023-03-14 23:07:51 +08:00
func (m *V8Value) SetAnyValue(value any) error {
switch common.JSValueAssertType(value) {
2022-10-04 13:21:05 +08:00
case V8_VALUE_STRING:
2023-02-22 12:31:35 +08:00
m.valueType.Jsv = V8_VALUE_STRING
m.valueType.Gov = GO_VALUE_STRING
2022-10-04 13:21:05 +08:00
case V8_VALUE_INT:
2023-02-22 12:31:35 +08:00
m.valueType.Jsv = V8_VALUE_INT
m.valueType.Gov = GO_VALUE_INT32
2022-10-04 13:21:05 +08:00
case V8_VALUE_DOUBLE:
2023-02-22 12:31:35 +08:00
m.valueType.Jsv = V8_VALUE_DOUBLE
m.valueType.Gov = GO_VALUE_FLOAT64
2022-10-04 13:21:05 +08:00
case V8_VALUE_BOOLEAN:
2023-02-22 12:31:35 +08:00
m.valueType.Jsv = V8_VALUE_BOOLEAN
m.valueType.Gov = GO_VALUE_BOOL
2022-10-04 13:21:05 +08:00
default:
2023-03-14 23:07:51 +08:00
return errors.New("invalid type")
2022-10-04 13:21:05 +08:00
}
m.setValue(value)
return nil
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) getFuncInfo() *funcInfo {
2022-10-04 13:21:05 +08:00
return m.funcInfo
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) Instance() uintptr {
2023-03-05 12:31:33 +08:00
return uintptr(m.instance)
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) Name() string {
2022-10-04 13:21:05 +08:00
return m.name
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) setName(name string) {
2022-10-04 13:21:05 +08:00
m.name = name
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) getValue() interface{} {
2022-10-04 13:21:05 +08:00
return m.value
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) setValue(value interface{}) {
2022-10-04 13:21:05 +08:00
m.value = value
}
2023-02-22 12:31:35 +08:00
func (m *V8Value) ValueType() *VT {
2022-10-04 13:21:05 +08:00
return m.valueType
}
2023-03-05 12:31:33 +08:00
func (m *V8Value) setInstance(instance unsafe.Pointer) {
2022-10-04 13:21:05 +08:00
m.instance = instance
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) StringValue() (string, error) {
2022-10-04 13:21:05 +08:00
if m.IsString() {
return common.ValueToString(m.value)
2022-10-04 13:21:05 +08:00
}
return "", errors.New("failed to get a string value")
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IntegerValue() (int32, error) {
2022-10-04 13:21:05 +08:00
if m.IsInteger() {
return common.ValueToInt32(m.value)
2022-10-04 13:21:05 +08:00
}
return 0, errors.New("failed to get a integer value")
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) DoubleValue() (float64, error) {
2022-10-04 13:21:05 +08:00
if m.IsDouble() {
return common.ValueToFloat64(m.value)
2022-10-04 13:21:05 +08:00
}
return 0, errors.New("failed to get a double value")
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) BooleanValue() (bool, error) {
2022-10-04 13:21:05 +08:00
if m.IsBool() {
return common.ValueToBool(m.value)
2022-10-04 13:21:05 +08:00
}
return false, errors.New("failed to get a boolean value")
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsString() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_STRING
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsInteger() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_INT
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsDouble() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_DOUBLE
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsBool() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_BOOLEAN
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsArray() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_ARRAY
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsObject() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_OBJECT
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsFunction() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_FUNCTION
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsNull() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_NULL
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) IsUndefined() bool {
2023-02-22 12:31:35 +08:00
return m.valueType.Jsv == V8_VALUE_UNDEFINED
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) AsString() *JSString {
2022-10-04 13:21:05 +08:00
if m.that != nil {
if v, ok := m.that.(*JSString); ok {
2023-02-21 23:16:35 +08:00
return v
2022-10-04 13:21:05 +08:00
}
}
2023-02-21 23:16:35 +08:00
return nil
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) AsInteger() *JSInteger {
2022-10-04 13:21:05 +08:00
if m.that != nil {
if v, ok := m.that.(*JSInteger); ok {
2023-02-21 23:16:35 +08:00
return v
2022-10-04 13:21:05 +08:00
}
}
2023-02-21 23:16:35 +08:00
return nil
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) AsDouble() *JSDouble {
2022-10-04 13:21:05 +08:00
if m.that != nil {
if v, ok := m.that.(*JSDouble); ok {
2023-02-21 23:16:35 +08:00
return v
2022-10-04 13:21:05 +08:00
}
}
2023-02-21 23:16:35 +08:00
return nil
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) AsBoolean() *JSBoolean {
2022-10-04 13:21:05 +08:00
if m.that != nil {
if v, ok := m.that.(*JSBoolean); ok {
2023-02-21 23:16:35 +08:00
return v
2022-10-04 13:21:05 +08:00
}
}
2023-02-21 23:16:35 +08:00
return nil
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) AsV8Value() *V8Value {
return m
}
func (m *V8Value) AsArray() *JSArray {
2022-10-04 13:21:05 +08:00
if m.that != nil {
if v, ok := m.that.(*JSArray); ok {
2023-02-21 23:16:35 +08:00
return v
2022-10-04 13:21:05 +08:00
}
}
2023-02-21 23:16:35 +08:00
return nil
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) AsFunction() *JSFunction {
2022-10-04 13:21:05 +08:00
if m.that != nil {
if v, ok := m.that.(*JSFunction); ok {
2023-02-21 23:16:35 +08:00
return v
2022-10-04 13:21:05 +08:00
}
}
2023-02-21 23:16:35 +08:00
return nil
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) invoke(inParams []reflect.Value) (outParams []reflect.Value, success bool) {
2022-10-04 13:21:05 +08:00
defer func() {
if err := recover(); err != nil {
2023-02-22 19:10:24 +08:00
logger.Error("invoke recover:", err)
2022-10-04 13:21:05 +08:00
outParams = []reflect.Value{reflect.ValueOf(err.(error).Error())}
success = false
}
}()
if m.isCommon() {
outParams = reflect.ValueOf(m.value).Call(inParams)
} else {
outParams = m.sfi.Method.Call(inParams)
}
return outParams, true
}
2023-02-22 19:10:24 +08:00
func newV8Value(eventId uintptr, fullParentName, name string, value interface{}, sfi *functionInfo, valueType *VT, isCommonObject IS_CO) JSValue {
2023-02-21 23:16:35 +08:00
jsValueBind := new(V8Value)
2023-02-22 12:31:35 +08:00
jsValueBind.valueType = new(VT)
2023-03-05 12:31:33 +08:00
jsValueBind.instance = unsafe.Pointer(&jsValueBind)
2022-10-04 13:21:05 +08:00
jsValueBind.eventId = eventId
jsValueBind.name = name
jsValueBind.value = value
if sfi != nil {
jsValueBind.funcInfo = sfi.funcInfo
}
jsValueBind.sfi = sfi
2023-02-22 19:10:24 +08:00
jsValueBind.valueType = valueType
2022-10-04 13:21:05 +08:00
jsValueBind.isCommonObject = isCommonObject
2023-03-02 15:11:04 +08:00
VariableBind.addBind(fmt.Sprintf("%s.%s", fullParentName, name), jsValueBind)
2022-10-04 13:21:05 +08:00
return jsValueBind
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) setEventId(eventId uintptr) {
2022-10-04 13:21:05 +08:00
m.eventId = eventId
}
2023-02-21 23:16:35 +08:00
func (m *V8Value) getEventId() uintptr {
2022-10-04 13:21:05 +08:00
return m.eventId
}