2022-10-04 13:21:05 +08:00
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
2023-02-19 23:21:47 +08:00
// 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"
2022-11-02 12:47:47 +08:00
"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 :
2022-11-02 12:47:47 +08:00
return common . StringToBytes ( iValue . ( string ) )
2022-10-04 13:21:05 +08:00
case V8_VALUE_INT :
2022-11-02 12:47:47 +08:00
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 :
2022-11-02 12:47:47 +08:00
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 :
2022-11-02 12:47:47 +08:00
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 :
2022-11-02 12:47:47 +08:00
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 :
2022-11-02 12:47:47 +08:00
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 :
2022-11-02 12:47:47 +08:00
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 {
2022-11-02 12:47:47 +08:00
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 ( ) {
2022-11-02 12:47:47 +08:00
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 ( ) {
2022-11-02 12:47:47 +08:00
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 ( ) {
2022-11-02 12:47:47 +08:00
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 ( ) {
2022-11-02 12:47:47 +08:00
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
}