energy/cef/vars.go

319 lines
9.2 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
// energy 变量相关
2022-10-04 13:21:05 +08:00
package cef
import (
"errors"
2023-02-21 23:16:35 +08:00
"fmt"
"github.com/energye/energy/common"
2022-10-04 22:34:57 +08:00
. "github.com/energye/energy/consts"
2022-10-04 13:21:05 +08:00
"reflect"
"sync"
"unsafe"
)
var (
2023-02-22 12:31:35 +08:00
nullptr unsafe.Pointer = nil //
commonRootName = "gocobj" //V8Value 通用类型变量属性的所属默认对象名称
objectRootName = "goobj" //V8Value 对象类型变量属性的所属默认对象名称
DownloadsDir string //下载目录
enableGPU = false //启用GPU true启用 false不启用
processName common.PRCESS_TYPE //进程名称
isMainProcess, isRenderProcess bool //
2022-10-04 13:21:05 +08:00
)
type initBindVariableCallback func(browser *ICefBrowser, frame *ICefFrame, bind IProvisionalBindStorage)
// 变量绑定
2023-02-21 23:16:35 +08:00
var VariableBind = &variableBind{valuesBind: make(map[string]JSValue)}
2022-10-04 13:21:05 +08:00
type IProvisionalBindStorage interface {
NewString(name, value string) *JSString
NewInteger(name string, value int32) *JSInteger
NewDouble(name string, value float64) *JSDouble
NewBoolean(name string, value bool) *JSBoolean
NewNull(name string) *JSNull
NewUndefined(name string) *JSUndefined
NewFunction(name string, fn interface{}) error
NewObjects(objects ...interface{})
2023-02-21 23:16:35 +08:00
Bind(name string, bind interface{}) error
2022-10-04 13:21:05 +08:00
}
type variableBind struct {
initBindVariableCallback initBindVariableCallback //
2023-02-21 23:16:35 +08:00
valuesBind map[string]JSValue //所有绑定变量属性或函数集合
2022-10-04 13:21:05 +08:00
}
2023-02-22 12:31:35 +08:00
func init() {
isMainProcess = common.Args.IsMain()
isRenderProcess = common.Args.IsRender()
}
2022-10-04 13:21:05 +08:00
func (m *variableBind) putValueBind(fullName string, value JSValue) {
if _, ok := m.valuesBind[fullName]; !ok {
m.valuesBind[fullName] = value
}
}
func (m *variableBind) ValueBindCount() int {
return len(m.valuesBind)
}
2022-10-04 22:34:57 +08:00
func (m *variableBind) GetValueBind(fullName string) (JSValue, bool) {
2022-10-04 13:21:05 +08:00
value, ok := m.valuesBind[fullName]
return value, ok
}
func clearValueBind() {
//valuesBind = make(map[uintptr]JSValue)
}
2023-02-21 23:16:35 +08:00
// VariableCreateCallback
//
// # Go 和 javaScript 的函数或变量绑定声明初始函数
2022-10-04 13:21:05 +08:00
//
2023-02-21 23:16:35 +08:00
// 在 javaScript 中调用Go中的函数,变量)需要在此回调函数中绑定
2022-10-04 13:21:05 +08:00
//
2023-02-21 23:16:35 +08:00
// 主进程和子进程
2022-10-04 13:21:05 +08:00
func (m *variableBind) VariableCreateCallback(callback func(browser *ICefBrowser, frame *ICefFrame, bind IProvisionalBindStorage)) {
m.initBindVariableCallback = callback
}
// 调用变量绑定回调函数
//
// 在主进程和渲染进程创建时调用
func (m *variableBind) callVariableBind(browser *ICefBrowser, frame *ICefFrame) {
if m.initBindVariableCallback != nil {
2023-02-21 23:16:35 +08:00
m.initBindVariableCallback(browser, frame, m)
2022-10-04 13:21:05 +08:00
}
}
2023-02-21 23:16:35 +08:00
// NewString V8Value
func (m *variableBind) NewString(name, value string) *JSString {
2022-10-04 13:21:05 +08:00
jsValueBind := new(JSString)
2023-02-22 12:31:35 +08:00
jsValueBind.valueType = new(VT)
2022-10-04 13:21:05 +08:00
jsValueBind.rwLock = new(sync.Mutex)
jsValueBind.name = name
jsValueBind.value = value
2023-02-22 12:31:35 +08:00
jsValueBind.valueType.Jsv = V8_VALUE_STRING
jsValueBind.valueType.Gov = GO_VALUE_STRING
2023-02-21 23:16:35 +08:00
m.valueHandle(jsValueBind)
2022-10-04 13:21:05 +08:00
return jsValueBind
}
2023-02-21 23:16:35 +08:00
// NewInteger V8Value
func (m *variableBind) NewInteger(name string, value int32) *JSInteger {
2022-10-04 13:21:05 +08:00
jsValueBind := new(JSInteger)
2023-02-22 12:31:35 +08:00
jsValueBind.valueType = new(VT)
2022-10-04 13:21:05 +08:00
jsValueBind.rwLock = new(sync.Mutex)
jsValueBind.name = name
jsValueBind.value = value
2023-02-22 12:31:35 +08:00
jsValueBind.valueType.Jsv = V8_VALUE_INT
jsValueBind.valueType.Gov = GO_VALUE_INT32
2023-02-21 23:16:35 +08:00
m.valueHandle(jsValueBind)
2022-10-04 13:21:05 +08:00
return jsValueBind
}
2023-02-21 23:16:35 +08:00
// NewDouble V8Value
func (m *variableBind) NewDouble(name string, value float64) *JSDouble {
2022-10-04 13:21:05 +08:00
jsValueBind := new(JSDouble)
2023-02-22 12:31:35 +08:00
jsValueBind.valueType = new(VT)
2022-10-04 13:21:05 +08:00
jsValueBind.rwLock = new(sync.Mutex)
jsValueBind.name = name
jsValueBind.value = value
2023-02-22 12:31:35 +08:00
jsValueBind.valueType.Jsv = V8_VALUE_DOUBLE
jsValueBind.valueType.Gov = GO_VALUE_FLOAT64
2023-02-21 23:16:35 +08:00
m.valueHandle(jsValueBind)
2022-10-04 13:21:05 +08:00
return jsValueBind
}
2023-02-21 23:16:35 +08:00
// NewBool V8Value
func (m *variableBind) NewBoolean(name string, value bool) *JSBoolean {
2022-10-04 13:21:05 +08:00
jsValueBind := new(JSBoolean)
2023-02-22 12:31:35 +08:00
jsValueBind.valueType = new(VT)
2022-10-04 13:21:05 +08:00
jsValueBind.rwLock = new(sync.Mutex)
jsValueBind.name = name
jsValueBind.value = value
2023-02-22 12:31:35 +08:00
jsValueBind.valueType.Jsv = V8_VALUE_BOOLEAN
jsValueBind.valueType.Gov = GO_VALUE_BOOL
2023-02-21 23:16:35 +08:00
m.valueHandle(jsValueBind)
2022-10-04 13:21:05 +08:00
return jsValueBind
}
2023-02-21 23:16:35 +08:00
// NewNull V8Value
func (m *variableBind) NewNull(name string) *JSNull {
2022-10-04 13:21:05 +08:00
jsValueBind := new(JSNull)
2023-02-22 12:31:35 +08:00
jsValueBind.valueType = new(VT)
2022-10-04 13:21:05 +08:00
jsValueBind.rwLock = new(sync.Mutex)
jsValueBind.name = name
jsValueBind.value = "null"
2023-02-22 12:31:35 +08:00
jsValueBind.valueType.Jsv = V8_VALUE_NULL
jsValueBind.valueType.Gov = GO_VALUE_NIL
2023-02-21 23:16:35 +08:00
m.valueHandle(jsValueBind)
2022-10-04 13:21:05 +08:00
return jsValueBind
}
2023-02-21 23:16:35 +08:00
// NewUndefined V8Value
func (m *variableBind) NewUndefined(name string) *JSUndefined {
2022-10-04 13:21:05 +08:00
jsValueBind := new(JSUndefined)
2023-02-22 12:31:35 +08:00
jsValueBind.valueType = new(VT)
2022-10-04 13:21:05 +08:00
jsValueBind.rwLock = new(sync.Mutex)
jsValueBind.name = name
jsValueBind.value = "undefined"
2023-02-22 12:31:35 +08:00
jsValueBind.valueType.Jsv = V8_VALUE_UNDEFINED
jsValueBind.valueType.Gov = GO_VALUE_STRING
2023-02-21 23:16:35 +08:00
m.valueHandle(jsValueBind)
2022-10-04 13:21:05 +08:00
return jsValueBind
}
2023-02-21 23:16:35 +08:00
// NewFunction V8Value
2022-10-04 13:21:05 +08:00
//
// 绑定 定义的普通函数 prefix default struct name
2023-02-21 23:16:35 +08:00
func (m *variableBind) NewFunction(name string, fn interface{}) error {
2023-02-22 19:10:24 +08:00
if gov, _ := common.FieldReflectType(fn); gov == GO_VALUE_FUNC {
2022-10-04 13:21:05 +08:00
if info, err := checkFunc(reflect.TypeOf(fn), FN_TYPE_COMMON); err == nil {
jsValueBind := new(JSFunction)
2023-02-22 12:31:35 +08:00
jsValueBind.valueType = new(VT)
2022-10-04 13:21:05 +08:00
jsValueBind.rwLock = new(sync.Mutex)
jsValueBind.name = name
jsValueBind.value = fn
2023-02-22 12:31:35 +08:00
jsValueBind.valueType.Jsv = V8_VALUE_FUNCTION
jsValueBind.valueType.Gov = GO_VALUE_FUNC
2022-10-04 13:21:05 +08:00
jsValueBind.funcInfo = info
2023-02-21 23:16:35 +08:00
m.valueHandle(jsValueBind)
2022-10-04 13:21:05 +08:00
return nil
} else {
return err
}
}
return errors.New("创建的函数不是函数类型")
}
2023-02-22 12:31:35 +08:00
// V8Value valueHandle
func (m *variableBind) valueHandle(jsValue JSValue) {
jsValue.setPtr(unsafe.Pointer(&jsValue))
jsValue.setInstance(uintptr(jsValue.Ptr()))
jsValue.setEventId(uintptr(__bind_id()))
jsValue.setThat(jsValue)
m.putValueBind(jsValue.Name(), jsValue)
}
2023-02-21 23:16:35 +08:00
// NewObjects V8Value
2022-10-04 13:21:05 +08:00
//
// 对象类型变量和对象函数绑定
2023-02-21 23:16:35 +08:00
func (m *variableBind) NewObjects(objects ...interface{}) {
2022-10-04 13:21:05 +08:00
bindObject(objects...)
}
2023-02-21 23:16:35 +08:00
// Bind V8Value
//
2023-02-22 08:47:48 +08:00
// 变量和函数绑定, 在Go中定义字段绑定到JS字段中, 在Go中定义的函数导出到JS
2023-02-21 23:16:35 +08:00
//
2023-02-22 12:31:35 +08:00
// 支持类型 String = string , Integer = int32 , Double = float64, Boolean = bool, Function = func, ObjectInfos = struct | map, Array = Slice
2023-02-21 23:16:35 +08:00
//
// 主进程和子进程
//
// 返回nil表示绑定成功
func (m *variableBind) Bind(name string, bind interface{}) error {
2023-02-22 12:31:35 +08:00
if isMainProcess || isRenderProcess {
typ := reflect.TypeOf(bind)
kind := typ.Kind()
//直接绑定变量地址
if kind != reflect.Ptr && kind != reflect.Func {
return errors.New(fmt.Sprintf("绑定字段 %s: 应传递绑定变量指针", name))
2023-02-21 23:16:35 +08:00
}
2023-02-22 19:10:24 +08:00
var gov GO_VALUE_TYPE
var jsv V8_JS_VALUE_TYPE
2023-02-22 12:31:35 +08:00
if kind == reflect.Func {
2023-02-22 19:10:24 +08:00
gov = GO_VALUE_FUNC
jsv = V8_VALUE_FUNCTION
2023-02-21 23:16:35 +08:00
} else {
2023-02-22 19:10:24 +08:00
gov, jsv = common.FieldReflectType(typ.Elem())
2023-02-21 23:16:35 +08:00
}
2023-02-22 19:10:24 +08:00
if jsv == V8_VALUE_EXCEPTION {
2023-02-22 12:31:35 +08:00
return errors.New("类型错误, 支持类型: string, int32, float64, bool, func, struct, map, slice")
}
value := &V8Value{
2023-02-22 19:10:24 +08:00
name: name,
rwLock: new(sync.Mutex),
valueType: &VT{
Jsv: jsv,
Gov: gov,
},
isCommonObject: IS_OBJECT,
eventId: uintptr(__bind_id()),
2023-02-21 23:16:35 +08:00
}
2023-02-22 19:10:24 +08:00
if jsv == V8_VALUE_FUNCTION {
if info, err := checkFunc(reflect.TypeOf(bind), FN_TYPE_OBJECT); err == nil {
2023-02-22 12:31:35 +08:00
value.funcInfo = info
value.ptr = unsafe.Pointer(&bind)
} else {
return err
}
2023-02-22 19:10:24 +08:00
} else if jsv == V8_VALUE_OBJECT {
if gov == GO_VALUE_STRUCT {
2023-02-22 12:31:35 +08:00
2023-02-22 19:10:24 +08:00
} else if gov == GO_VALUE_MAP {
2023-02-21 23:16:35 +08:00
}
2023-02-22 19:10:24 +08:00
} else if jsv == V8_VALUE_ARRAY {
2023-02-22 12:31:35 +08:00
} else {
2023-02-22 19:10:24 +08:00
switch jsv {
2023-02-22 12:31:35 +08:00
case V8_VALUE_STRING:
value.ptr = unsafe.Pointer(bind.(*string))
case V8_VALUE_INT:
2023-02-22 19:10:24 +08:00
switch gov {
2023-02-22 12:31:35 +08:00
case GO_VALUE_INT:
value.ptr = unsafe.Pointer(bind.(*int))
case GO_VALUE_INT8:
value.ptr = unsafe.Pointer(bind.(*int8))
case GO_VALUE_INT16:
value.ptr = unsafe.Pointer(bind.(*int16))
case GO_VALUE_INT32:
value.ptr = unsafe.Pointer(bind.(*int32))
case GO_VALUE_INT64:
value.ptr = unsafe.Pointer(bind.(*int64))
case GO_VALUE_UINT:
value.ptr = unsafe.Pointer(bind.(*uint))
case GO_VALUE_UINT8:
value.ptr = unsafe.Pointer(bind.(*uint8))
case GO_VALUE_UINT16:
value.ptr = unsafe.Pointer(bind.(*uint16))
case GO_VALUE_UINT32:
value.ptr = unsafe.Pointer(bind.(*uint32))
case GO_VALUE_UINT64:
value.ptr = unsafe.Pointer(bind.(*uint64))
case GO_VALUE_UINTPTR:
value.ptr = unsafe.Pointer(bind.(*uintptr))
}
case V8_VALUE_DOUBLE:
2023-02-22 19:10:24 +08:00
if gov == GO_VALUE_FLOAT32 {
2023-02-22 12:31:35 +08:00
value.ptr = unsafe.Pointer(bind.(*float32))
} else {
value.ptr = unsafe.Pointer(bind.(*float64))
}
case V8_VALUE_BOOLEAN:
value.ptr = unsafe.Pointer(bind.(*bool))
default:
return errors.New("字段 " + name + ": 不支持的绑定类型")
2023-02-21 23:16:35 +08:00
}
}
value.instance = uintptr(value.ptr)
2023-02-22 12:31:35 +08:00
value.value = bind
value.that = value
m.putValueBind(name, value)
objectTI.bind(value)
2023-02-21 23:16:35 +08:00
}
return nil
}