2023-05-31 17:41:14 +08:00
|
|
|
|
//----------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Copyright © yanghy. All Rights Reserved.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under Apache License Version 2.0, January 2004
|
|
|
|
|
//
|
|
|
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
//----------------------------------------
|
|
|
|
|
|
|
|
|
|
// energy 渲染进程 IPC
|
|
|
|
|
|
|
|
|
|
package cef
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
2023-05-31 18:00:34 +08:00
|
|
|
|
"github.com/energye/energy/v2/cef/internal/ipc"
|
|
|
|
|
ipcArgument "github.com/energye/energy/v2/cef/ipc/argument"
|
|
|
|
|
"github.com/energye/energy/v2/cef/ipc/context"
|
2024-01-05 23:52:52 +08:00
|
|
|
|
"github.com/energye/energy/v2/cef/ipc/target"
|
2023-05-31 18:00:34 +08:00
|
|
|
|
"github.com/energye/energy/v2/consts"
|
|
|
|
|
"github.com/energye/energy/v2/pkgs/json"
|
2024-04-25 20:49:44 +08:00
|
|
|
|
"time"
|
2023-05-31 17:41:14 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ipcRenderProcess 渲染进程
|
|
|
|
|
type ipcRenderProcess struct {
|
|
|
|
|
isInitRenderIPC bool
|
2024-06-23 15:34:51 +08:00
|
|
|
|
ipcObject *ICefV8Value // ipc object
|
|
|
|
|
emitHandler *ipcEmitHandler // ipc.emit handler
|
|
|
|
|
onHandler map[int64]*ipcOnHandler // ipc.on handler
|
2024-04-25 20:49:44 +08:00
|
|
|
|
waitChan *ipc.WaitChan
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-23 15:34:51 +08:00
|
|
|
|
func (m *ipcRenderProcess) clear(frameId int64) {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if m.ipcObject != nil {
|
|
|
|
|
m.ipcObject.Free()
|
|
|
|
|
m.ipcObject = nil
|
|
|
|
|
}
|
2023-08-23 19:27:42 +08:00
|
|
|
|
if m.onHandler != nil {
|
2024-06-23 15:34:51 +08:00
|
|
|
|
if on, ok := m.onHandler[frameId]; ok {
|
|
|
|
|
on.clear()
|
|
|
|
|
delete(m.onHandler, frameId)
|
|
|
|
|
}
|
2023-08-23 19:27:42 +08:00
|
|
|
|
}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-23 15:34:51 +08:00
|
|
|
|
// JS ipc.on 监听事件
|
|
|
|
|
func (m *ipcOnHandler) jsOnEvent(name string, object *ICefV8Value, arguments *TCefV8ValueArray, retVal *ResultV8Value, exception *ResultString) (result bool) {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if name != internalIPCOn {
|
|
|
|
|
return
|
|
|
|
|
} else if arguments.Size() != 2 { //必须是2个参数
|
|
|
|
|
exception.SetValue("ipc.on parameter should be 2 quantity")
|
|
|
|
|
arguments.Free()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var (
|
|
|
|
|
onName *ICefV8Value // 事件名
|
|
|
|
|
onNameValue string // 事件名
|
|
|
|
|
onCallback *ICefV8Value // 事件回调函数
|
|
|
|
|
)
|
|
|
|
|
onName = arguments.Get(0)
|
2023-08-23 19:27:42 +08:00
|
|
|
|
//事件名,第一个参数必须是字符串
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if !onName.IsString() {
|
|
|
|
|
exception.SetValue("ipc.on event name should be a string")
|
2023-08-23 19:27:42 +08:00
|
|
|
|
arguments.Free()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
onCallback = arguments.Get(1)
|
2023-08-23 19:27:42 +08:00
|
|
|
|
//回调函数,第二个参数必须是函数
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if !onCallback.IsFunction() {
|
|
|
|
|
exception.SetValue("ipc.on event callback should be a function")
|
2023-08-23 19:27:42 +08:00
|
|
|
|
arguments.Free()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
retVal.SetResult(V8ValueRef.NewBool(true))
|
|
|
|
|
onCallback.SetCanNotFree(true)
|
|
|
|
|
onNameValue = onName.GetStringValue()
|
|
|
|
|
//ipc on
|
2024-06-23 15:34:51 +08:00
|
|
|
|
m.addCallback(onNameValue, &ipcCallback{function: V8ValueRef.UnWrap(onCallback), name: V8ValueRef.UnWrap(onName)})
|
2023-05-31 17:41:14 +08:00
|
|
|
|
result = true
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-15 12:11:16 +08:00
|
|
|
|
// Go ipc.emit 执行JS事件
|
2023-05-31 17:41:14 +08:00
|
|
|
|
func (m *ipcRenderProcess) ipcGoExecuteJSEvent(browser *ICefBrowser, frame *ICefFrame, sourceProcess consts.CefProcessId, message *ICefProcessMessage) (result bool) {
|
2024-06-23 15:34:51 +08:00
|
|
|
|
on, ok := m.onHandler[frame.Identifier()]
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
result = true
|
|
|
|
|
argumentListBytes := message.ArgumentList().GetBinary(0)
|
|
|
|
|
//接收二进制数据失败
|
|
|
|
|
if argumentListBytes == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var messageDataBytes []byte
|
|
|
|
|
if argumentListBytes.IsValid() {
|
|
|
|
|
size := argumentListBytes.GetSize()
|
|
|
|
|
messageDataBytes = make([]byte, size)
|
|
|
|
|
c := argumentListBytes.GetData(messageDataBytes, 0)
|
|
|
|
|
argumentListBytes.Free()
|
|
|
|
|
message.Free()
|
|
|
|
|
if c == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var messageId int32
|
|
|
|
|
var emitName string
|
|
|
|
|
var argument ipcArgument.IList
|
|
|
|
|
var argumentList json.JSONArray
|
|
|
|
|
if messageDataBytes != nil {
|
|
|
|
|
argument = ipcArgument.UnList(messageDataBytes)
|
|
|
|
|
messageId = argument.MessageId()
|
|
|
|
|
emitName = argument.GetEventName()
|
|
|
|
|
if argument.JSON() != nil {
|
|
|
|
|
argumentList = argument.JSON().JSONArray()
|
|
|
|
|
}
|
|
|
|
|
messageDataBytes = nil
|
|
|
|
|
}
|
|
|
|
|
defer func() {
|
|
|
|
|
if argument != nil {
|
|
|
|
|
argument.Reset()
|
|
|
|
|
}
|
|
|
|
|
if argumentList != nil {
|
|
|
|
|
argumentList.Free()
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2024-06-23 15:34:51 +08:00
|
|
|
|
if callback := on.getCallback(emitName); callback != nil {
|
2023-12-30 23:12:20 +08:00
|
|
|
|
var callbackArgsBytes interface{}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
//enter v8context
|
2024-05-15 12:11:16 +08:00
|
|
|
|
ctx := frame.V8Context()
|
|
|
|
|
if ctx.Enter() {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
var ret *ICefV8Value
|
|
|
|
|
var argsArray *TCefV8ValueArray
|
|
|
|
|
var err error
|
|
|
|
|
if argumentList != nil {
|
|
|
|
|
//bytes to v8array value
|
|
|
|
|
argsArray, err = ValueConvert.BytesToV8ArrayValue(argumentList.Bytes())
|
|
|
|
|
}
|
|
|
|
|
if argsArray != nil && err == nil {
|
|
|
|
|
// parse v8array success
|
2024-05-15 12:11:16 +08:00
|
|
|
|
ret = callback.function.ExecuteFunctionWithContext(ctx, nil, argsArray)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
argsArray.Free()
|
|
|
|
|
} else {
|
|
|
|
|
// parse v8array fail
|
2024-05-15 12:11:16 +08:00
|
|
|
|
ret = callback.function.ExecuteFunctionWithContext(ctx, nil, nil)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
if ret != nil && ret.IsValid() && messageId != 0 { // messageId != 0 callback func args
|
|
|
|
|
// v8value to process message bytes
|
|
|
|
|
callbackArgsBytes = ValueConvert.V8ValueToProcessMessageArray(ret)
|
|
|
|
|
ret.Free()
|
|
|
|
|
} else if ret != nil {
|
|
|
|
|
ret.Free()
|
|
|
|
|
}
|
|
|
|
|
//exit v8context
|
2024-05-15 12:11:16 +08:00
|
|
|
|
ctx.Exit()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
2024-05-15 12:11:16 +08:00
|
|
|
|
ctx.Free()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if messageId != 0 { //messageId != 0 callback func
|
|
|
|
|
callbackMessage := &ipcArgument.List{
|
|
|
|
|
Id: messageId,
|
|
|
|
|
BId: ipc.RenderChan().BrowserId(),
|
|
|
|
|
Name: internalIPCGoExecuteJSEventReplay,
|
|
|
|
|
}
|
|
|
|
|
if callbackArgsBytes != nil {
|
|
|
|
|
callbackMessage.Data = callbackArgsBytes //json.NewJSONArray(callbackArgsBytes).Data()
|
|
|
|
|
}
|
|
|
|
|
// send ipc message
|
|
|
|
|
// send bytes data to browser ipc
|
|
|
|
|
ipc.RenderChan().IPC().Send(callbackMessage.Bytes())
|
|
|
|
|
callbackMessage.Reset()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 规则选项名定义
|
|
|
|
|
const (
|
|
|
|
|
ruleName = "name"
|
|
|
|
|
ruleArguments = "arguments"
|
|
|
|
|
ruleCallback = "callback"
|
|
|
|
|
ruleMode = "mode"
|
2024-04-25 20:49:44 +08:00
|
|
|
|
ruleWaitTime = "waitTime"
|
2023-05-31 17:41:14 +08:00
|
|
|
|
ruleTarget = "target"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 触发模式
|
|
|
|
|
type modelRule int8
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
modelAsync modelRule = iota // 异步
|
2024-04-25 20:49:44 +08:00
|
|
|
|
modelWait // 等待结果
|
2023-05-31 17:41:14 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 触发接收目标
|
|
|
|
|
type targetRule int8
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
targetMain targetRule = iota //主进程
|
|
|
|
|
targetCurrent //当前进程
|
|
|
|
|
targetOther //其它子进程
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 执行规则
|
|
|
|
|
type executeRule int8
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
exerOption executeRule = iota //选项
|
|
|
|
|
exerArgs //参数
|
|
|
|
|
)
|
|
|
|
|
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 触发模式是 modelWait 时的默认等待时间
|
|
|
|
|
const defaultEmitWaitTime = 5 * time.Second
|
|
|
|
|
|
2023-05-31 17:41:14 +08:00
|
|
|
|
// jsExecuteRule
|
2024-04-25 20:49:44 +08:00
|
|
|
|
//
|
2023-05-31 17:41:14 +08:00
|
|
|
|
// JS 执行规则
|
|
|
|
|
type jsExecuteRule struct {
|
2024-04-25 20:49:44 +08:00
|
|
|
|
rule executeRule //规则
|
|
|
|
|
model modelRule //模式 默认 modelAsync
|
|
|
|
|
waitTime time.Duration //等待时间,当触发模式为 modelWait 有效, 默认5000毫秒
|
|
|
|
|
target targetRule //目标 默认 targetMain
|
|
|
|
|
first *ICefV8Value //
|
|
|
|
|
emitName *ICefV8Value //事件名
|
|
|
|
|
emitNameValue string //事件名值
|
|
|
|
|
emitArgs *ICefV8Value //事件参数
|
|
|
|
|
emitCallback *ICefV8Value //事件回调函数
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// freeV8Value
|
|
|
|
|
func (*jsExecuteRule) freeV8Value(value *ICefV8Value) {
|
|
|
|
|
if value != nil {
|
|
|
|
|
value.Free()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// freeAll
|
|
|
|
|
func (m *jsExecuteRule) freeAll() {
|
|
|
|
|
m.freeV8Value(m.first)
|
|
|
|
|
m.freeV8Value(m.emitName)
|
|
|
|
|
m.freeV8Value(m.emitArgs)
|
|
|
|
|
m.freeV8Value(m.emitCallback)
|
|
|
|
|
m.emitNameValue = ""
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 执行规则
|
2023-05-31 17:41:14 +08:00
|
|
|
|
func (*ipcRenderProcess) jsExecuteGoRule(name string, arguments *TCefV8ValueArray) (*jsExecuteRule, error) {
|
|
|
|
|
if arguments.Size() >= 1 {
|
|
|
|
|
m := new(jsExecuteRule)
|
|
|
|
|
m.first = arguments.Get(0)
|
2024-04-25 20:49:44 +08:00
|
|
|
|
m.waitTime = defaultEmitWaitTime // default
|
|
|
|
|
if m.first.IsString() { // args
|
2023-05-31 17:41:14 +08:00
|
|
|
|
m.emitName = m.first
|
|
|
|
|
m.emitNameValue = m.emitName.GetStringValue()
|
2024-04-25 20:49:44 +08:00
|
|
|
|
if name == internalIPCEmitWait { // 等待超时返回结果
|
|
|
|
|
m.model = modelWait
|
|
|
|
|
} else {
|
|
|
|
|
m.model = modelAsync // default
|
|
|
|
|
}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if arguments.Size() == 2 {
|
|
|
|
|
args2 := arguments.Get(1)
|
|
|
|
|
if args2.IsArray() {
|
|
|
|
|
m.emitArgs = args2
|
2024-04-25 20:49:44 +08:00
|
|
|
|
} else if m.model == modelAsync && args2.IsFunction() {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
m.emitCallback = args2
|
2024-04-25 20:49:44 +08:00
|
|
|
|
} else if m.model == modelWait && args2.IsUInt() {
|
|
|
|
|
// 等待超时触发
|
|
|
|
|
waitTimeValue := args2.GetUIntValue()
|
|
|
|
|
args2.Free()
|
|
|
|
|
if waitTimeValue > 0 {
|
|
|
|
|
m.waitTime = time.Duration(waitTimeValue) * time.Millisecond
|
|
|
|
|
}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
} else {
|
|
|
|
|
m.freeAll()
|
2024-04-25 20:49:44 +08:00
|
|
|
|
if m.model == modelAsync {
|
|
|
|
|
return nil, errors.New("ipc.emit second argument can only be a input parameter. third parameter can only be a callback function")
|
|
|
|
|
} else {
|
|
|
|
|
return nil, errors.New("ipc.emitWait second argument can only be a input parameter. third parameter can only be a timeout time")
|
|
|
|
|
}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
} else if arguments.Size() == 3 {
|
|
|
|
|
m.emitArgs = arguments.Get(1)
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 第三个参数, 根据触发模式
|
|
|
|
|
args3 := arguments.Get(2)
|
|
|
|
|
// 异步触发
|
|
|
|
|
if m.model == modelAsync && args3.IsFunction() {
|
|
|
|
|
m.emitCallback = args3
|
|
|
|
|
} else if m.model == modelWait && args3.IsUInt() {
|
|
|
|
|
// 等待超时触发
|
|
|
|
|
waitTimeValue := args3.GetUIntValue()
|
|
|
|
|
args3.Free()
|
|
|
|
|
if waitTimeValue > 0 {
|
|
|
|
|
m.waitTime = time.Duration(waitTimeValue) * time.Millisecond
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
m.freeAll()
|
2024-04-25 20:49:44 +08:00
|
|
|
|
if m.model == modelAsync {
|
|
|
|
|
return nil, errors.New("ipc.emit second argument can only be a input parameter. third parameter can only be a callback function")
|
|
|
|
|
} else {
|
|
|
|
|
return nil, errors.New("ipc.emitWait second argument can only be a input parameter. third parameter can only be a timeout time")
|
|
|
|
|
}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-25 20:49:44 +08:00
|
|
|
|
|
2023-05-31 17:41:14 +08:00
|
|
|
|
m.rule = exerArgs
|
|
|
|
|
m.target = targetMain // default
|
|
|
|
|
return m, nil
|
|
|
|
|
} else if m.first.IsObject() { // options
|
|
|
|
|
keys := m.first.GetKeys()
|
|
|
|
|
keyMap := make(map[string]bool, keys.Count())
|
|
|
|
|
for i := 0; i < keys.Count(); i++ {
|
|
|
|
|
keyMap[keys.Get(i)] = true
|
|
|
|
|
}
|
|
|
|
|
keys.Free()
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 事件名称
|
|
|
|
|
if _, ok := keyMap[ruleName]; ok {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
m.emitName = m.first.getValueByKey(ruleName)
|
|
|
|
|
if !m.emitName.IsString() {
|
|
|
|
|
m.freeAll()
|
|
|
|
|
return nil, errors.New("ipc.emit event name is incorrect, Pass as an string")
|
|
|
|
|
}
|
|
|
|
|
m.emitNameValue = m.emitName.GetStringValue()
|
|
|
|
|
} else {
|
|
|
|
|
m.freeAll()
|
|
|
|
|
return nil, errors.New("ipc.emit event name is incorrect, Pass as an string")
|
|
|
|
|
}
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 参数列表
|
|
|
|
|
if _, ok := keyMap[ruleArguments]; ok {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
m.emitArgs = m.first.getValueByKey(ruleArguments) // array
|
|
|
|
|
if !m.emitArgs.IsArray() {
|
|
|
|
|
m.freeAll()
|
|
|
|
|
return nil, errors.New("ipc.emit event arguments is incorrect, Pass as an array")
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 回调函数
|
|
|
|
|
if _, ok := keyMap[ruleCallback]; ok {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
m.emitCallback = m.first.getValueByKey(ruleCallback) // function
|
|
|
|
|
if !m.emitCallback.IsFunction() {
|
|
|
|
|
m.freeAll()
|
|
|
|
|
return nil, errors.New("ipc.emit event callback function is incorrect, Pass as an function")
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 触发模式
|
|
|
|
|
if _, ok := keyMap[ruleMode]; ok {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
mode := m.first.getValueByKey(ruleMode) // int 0:async or 1:sync, default 0:async
|
|
|
|
|
if !mode.IsInt() {
|
|
|
|
|
m.freeAll()
|
|
|
|
|
return nil, errors.New("ipc.emit event mode is incorrect, Pass as an integer")
|
|
|
|
|
}
|
|
|
|
|
modeValue := modelRule(mode.GetIntValue())
|
|
|
|
|
mode.Free()
|
2024-04-25 20:49:44 +08:00
|
|
|
|
if modeValue == modelAsync || modeValue == modelWait {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
m.model = modeValue
|
|
|
|
|
} else {
|
|
|
|
|
m.model = modelAsync // default
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
m.model = modelAsync // default
|
|
|
|
|
}
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 触发等待时间,触发模式为 modelWait 有效
|
|
|
|
|
if _, ok := keyMap[ruleWaitTime]; ok && m.model == modelWait {
|
|
|
|
|
waitTime := m.first.getValueByKey(ruleWaitTime) // int 0:async or 1:sync, default 0:async
|
|
|
|
|
if !waitTime.IsUInt() {
|
|
|
|
|
m.freeAll()
|
|
|
|
|
return nil, errors.New("ipc.emitWait The timeout waiting time is incorrect, Pass as an uint, unit millisecond")
|
|
|
|
|
}
|
|
|
|
|
// 单位 毫秒
|
|
|
|
|
waitTimeValue := waitTime.GetUIntValue()
|
|
|
|
|
waitTime.Free()
|
|
|
|
|
if waitTimeValue > 0 {
|
|
|
|
|
m.waitTime = time.Duration(waitTimeValue) * time.Millisecond
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 触发目标
|
|
|
|
|
if _, ok := keyMap[ruleTarget]; ok {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
target := m.first.getValueByKey(ruleTarget) // int 0:main 1:current 2:other
|
|
|
|
|
if !target.IsInt() {
|
|
|
|
|
m.freeAll()
|
|
|
|
|
return nil, errors.New("ipc.emit event target is incorrect, Pass as an integer")
|
|
|
|
|
}
|
|
|
|
|
targetValue := targetRule(target.GetIntValue())
|
|
|
|
|
target.Free()
|
|
|
|
|
if targetValue == targetMain || targetValue == targetCurrent || targetValue == targetOther {
|
|
|
|
|
m.target = targetValue
|
|
|
|
|
} else {
|
|
|
|
|
m.target = targetMain // default
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
m.target = targetMain // default
|
|
|
|
|
}
|
|
|
|
|
m.rule = exerOption
|
|
|
|
|
return m, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil, errors.New("ipc.emit first argument must be the event name or option rule")
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-15 12:11:16 +08:00
|
|
|
|
// JS 执行 GO 监听事件
|
2023-05-31 17:41:14 +08:00
|
|
|
|
func (m *ipcRenderProcess) jsExecuteGoEvent(name string, object *ICefV8Value, arguments *TCefV8ValueArray, retVal *ResultV8Value, exception *ResultString) (result bool) {
|
|
|
|
|
result = true
|
2023-12-30 23:12:20 +08:00
|
|
|
|
var args interface{}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
defer func() {
|
|
|
|
|
if args != nil {
|
|
|
|
|
args = nil
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
rule, err := m.jsExecuteGoRule(name, arguments)
|
|
|
|
|
if err == nil {
|
|
|
|
|
defer rule.freeAll()
|
2024-05-15 12:11:16 +08:00
|
|
|
|
v8ctx := V8ContextRef.Current()
|
|
|
|
|
defer v8ctx.Free()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if rule.emitArgs != nil { //入参
|
|
|
|
|
//V8Value 转换
|
|
|
|
|
args = ValueConvert.V8ValueToProcessMessageArray(rule.emitArgs)
|
|
|
|
|
if args == nil {
|
|
|
|
|
exception.SetValue("ipc.emit convert parameter to value value error")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-25 20:49:44 +08:00
|
|
|
|
var isWait = rule.model == modelWait //等待超时返回结果
|
2023-05-31 17:41:14 +08:00
|
|
|
|
//单进程 不通过进程消息, 全是同步
|
|
|
|
|
if application.SingleProcess() {
|
|
|
|
|
callback := &ipcCallback{}
|
|
|
|
|
if rule.emitCallback != nil { //callback function
|
|
|
|
|
callback.resultType = rt_function
|
|
|
|
|
callback.function = rule.emitCallback
|
|
|
|
|
} else { //variable
|
|
|
|
|
callback.resultType = rt_variable
|
|
|
|
|
}
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.singleProcess(v8ctx, rule.emitNameValue, callback, args)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if callback.resultType == rt_variable {
|
|
|
|
|
if callback.variable != nil {
|
|
|
|
|
retVal.SetResult(callback.variable)
|
|
|
|
|
} else {
|
|
|
|
|
retVal.SetResult(V8ValueRef.NewBool(true))
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
retVal.SetResult(V8ValueRef.NewBool(true))
|
|
|
|
|
}
|
|
|
|
|
} else { //多进程
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 等待超时 或 当前子进程
|
|
|
|
|
if isWait || rule.target == targetCurrent {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
callback := &ipcCallback{isSync: true}
|
|
|
|
|
// 回调函数或变量方式接收返回值, 优先回调函数
|
|
|
|
|
if rule.emitCallback != nil { //callback function
|
|
|
|
|
callback.resultType = rt_function
|
|
|
|
|
callback.function = rule.emitCallback
|
|
|
|
|
} else { //variable
|
|
|
|
|
callback.resultType = rt_variable
|
|
|
|
|
}
|
|
|
|
|
//当前子进程
|
|
|
|
|
if rule.target == targetCurrent {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.multiProcessCurrentProcess(v8ctx, rule.emitNameValue, callback, args)
|
2024-04-25 20:49:44 +08:00
|
|
|
|
} else { //等待 - 主进程
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.multiProcessWait(v8ctx, rule.emitNameValue, callback, rule.waitTime, args)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
if callback.resultType == rt_variable {
|
|
|
|
|
if callback.variable != nil {
|
|
|
|
|
retVal.SetResult(callback.variable)
|
|
|
|
|
} else {
|
|
|
|
|
retVal.SetResult(V8ValueRef.NewBool(true))
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
retVal.SetResult(V8ValueRef.NewBool(true))
|
|
|
|
|
}
|
|
|
|
|
} else { // 异步 - 主进程
|
|
|
|
|
var messageId int32 = 0
|
|
|
|
|
if rule.emitCallback != nil {
|
|
|
|
|
rule.emitCallback.SetCanNotFree(true)
|
|
|
|
|
callback := &ipcCallback{resultType: rt_function, function: V8ValueRef.UnWrap(rule.emitCallback)}
|
|
|
|
|
messageId = m.emitHandler.addCallback(callback)
|
|
|
|
|
}
|
2024-05-15 12:11:16 +08:00
|
|
|
|
var message target.IProcessMessage
|
2024-01-05 23:52:52 +08:00
|
|
|
|
if application.IsSpecVer49() {
|
|
|
|
|
// CEF49
|
2024-05-15 12:11:16 +08:00
|
|
|
|
message = v8ctx.Browser()
|
2024-01-05 23:52:52 +08:00
|
|
|
|
} else {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
message = v8ctx.Frame()
|
2024-01-05 23:52:52 +08:00
|
|
|
|
}
|
|
|
|
|
// 在多进程时,发送多进程异步消息,如果当前CEF版本是CEF49使用Browser的发送消息函数
|
|
|
|
|
if success := m.multiProcessAsync(message, messageId, rule.emitNameValue, args); !success {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
//失败,释放回调函数
|
|
|
|
|
rule.emitCallback.SetCanNotFree(false)
|
|
|
|
|
}
|
|
|
|
|
retVal.SetResult(V8ValueRef.NewBool(true))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// emit rule error
|
|
|
|
|
println("js execute go event error:", err.Error())
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-15 12:11:16 +08:00
|
|
|
|
// 多进程消息 - 当前进程
|
|
|
|
|
func (m *ipcRenderProcess) multiProcessCurrentProcess(v8ctx *ICefV8Context, emitName string, callback *ipcCallback, data interface{}) {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
// 主进程
|
|
|
|
|
eventCallback := ipc.CheckOnEvent(emitName)
|
|
|
|
|
var ipcContext context.IContext
|
|
|
|
|
if eventCallback != nil {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
ipcContext = context.NewContext(v8ctx.Browser().Identifier(), v8ctx.Frame().Identifier(), true, json.NewJSONArray(data))
|
2023-05-31 17:41:14 +08:00
|
|
|
|
//调用监听函数
|
|
|
|
|
if ctxCallback := eventCallback.ContextCallback(); ctxCallback != nil {
|
|
|
|
|
ctxCallback.Invoke(ipcContext)
|
|
|
|
|
} else if argsCallback := eventCallback.ArgumentCallback(); argsCallback != nil {
|
|
|
|
|
argsCallback.Invoke(ipcContext)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ipcContext != nil && callback != nil {
|
|
|
|
|
//处理回复消息
|
|
|
|
|
replay := ipcContext.Replay()
|
|
|
|
|
if replay.Result() != nil && len(replay.Result()) > 0 {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.executeCallbackFunction(v8ctx, true, callback, json.NewJSONArray(replay.Result()))
|
2023-05-31 17:41:14 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.executeCallbackFunction(v8ctx, false, callback, nil)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-15 12:11:16 +08:00
|
|
|
|
// 单进程
|
|
|
|
|
func (m *ipcRenderProcess) singleProcess(v8ctx *ICefV8Context, emitName string, callback *ipcCallback, data interface{}) {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if ipcBrowser == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-27 22:34:30 +08:00
|
|
|
|
// 当前为主进程
|
2024-05-15 12:11:16 +08:00
|
|
|
|
ipcContext := ipcBrowser.jsExecuteGoMethod(v8ctx.Browser().Identifier(), v8ctx.Frame().Identifier(), emitName, json.NewJSONArray(data))
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if ipcContext != nil && callback != nil {
|
2024-04-27 22:34:30 +08:00
|
|
|
|
// 处理回复消息
|
2023-05-31 17:41:14 +08:00
|
|
|
|
replay := ipcContext.Replay()
|
|
|
|
|
if replay.Result() != nil && len(replay.Result()) > 0 {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.executeCallbackFunction(v8ctx, true, callback, json.NewJSONArray(replay.Result()))
|
2023-05-31 17:41:14 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.executeCallbackFunction(v8ctx, false, callback, nil)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-27 22:34:30 +08:00
|
|
|
|
// 多进程消息 - 会阻塞渲染进程,并等待 delay 时间后自动返回
|
2024-05-15 12:11:16 +08:00
|
|
|
|
func (m *ipcRenderProcess) multiProcessWait(v8ctx *ICefV8Context, emitName string, callback *ipcCallback, delay time.Duration, data interface{}) {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
//延迟等待接收结果,默认5秒
|
2024-04-25 20:49:44 +08:00
|
|
|
|
messageId := m.waitChan.NextMessageId()
|
|
|
|
|
resultChan := make(chan interface{})
|
|
|
|
|
m.waitChan.Pending.Store(messageId, func(result interface{}) {
|
|
|
|
|
select {
|
|
|
|
|
case resultChan <- result:
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-04-27 22:34:30 +08:00
|
|
|
|
// 组装消息
|
2023-05-31 17:41:14 +08:00
|
|
|
|
message := &ipcArgument.List{
|
|
|
|
|
Id: messageId,
|
|
|
|
|
BId: ipc.RenderChan().BrowserId(),
|
2024-04-27 22:34:30 +08:00
|
|
|
|
Name: internalIPCJSExecuteGoWaitEvent,
|
2023-05-31 17:41:14 +08:00
|
|
|
|
EventName: emitName,
|
|
|
|
|
Data: data,
|
|
|
|
|
}
|
|
|
|
|
//发送数据到主进程
|
|
|
|
|
ipc.RenderChan().IPC().Send(message.Bytes())
|
|
|
|
|
message.Reset()
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 开始计时, 直到 delay 时间结束,或正常返回结果
|
|
|
|
|
delayer := m.waitChan.NewDelayer(messageId, delay)
|
|
|
|
|
select {
|
|
|
|
|
case resultData := <-resultChan:
|
|
|
|
|
//接收成功,停止
|
|
|
|
|
delayer.Stop()
|
|
|
|
|
delayer = nil
|
|
|
|
|
var argumentList json.JSONArray
|
|
|
|
|
if resultData != nil {
|
|
|
|
|
argumentList = resultData.(json.JSONArray)
|
|
|
|
|
}
|
|
|
|
|
if argumentList != nil {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.executeCallbackFunction(v8ctx, true, callback, argumentList)
|
2024-04-25 20:49:44 +08:00
|
|
|
|
argumentList.Free()
|
|
|
|
|
} else {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.executeCallbackFunction(v8ctx, false, callback, nil)
|
2024-04-25 20:49:44 +08:00
|
|
|
|
}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
2024-04-25 20:49:44 +08:00
|
|
|
|
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 多进程消息 - 异步
|
2024-01-05 23:52:52 +08:00
|
|
|
|
func (m *ipcRenderProcess) multiProcessAsync(processMessage target.IProcessMessage, messageId int32, emitName string, data interface{}) bool {
|
|
|
|
|
if processMessage != nil {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
message := &ipcArgument.List{
|
|
|
|
|
Id: messageId,
|
|
|
|
|
EventName: emitName,
|
|
|
|
|
Data: data,
|
|
|
|
|
}
|
2024-01-05 23:52:52 +08:00
|
|
|
|
processMessage.SendProcessMessageForJSONBytes(internalIPCJSExecuteGoEvent, consts.PID_BROWSER, message.Bytes())
|
2023-05-31 17:41:14 +08:00
|
|
|
|
message.Reset()
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// JS执行Go监听,Go的消息回复
|
2023-05-31 17:41:14 +08:00
|
|
|
|
func (m *ipcRenderProcess) ipcJSExecuteGoEventMessageReply(browser *ICefBrowser, frame *ICefFrame, sourceProcess consts.CefProcessId, message *ICefProcessMessage) (result bool) {
|
|
|
|
|
result = true
|
|
|
|
|
argumentListBytes := message.ArgumentList().GetBinary(0)
|
|
|
|
|
if argumentListBytes == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var messageDataBytes []byte
|
|
|
|
|
if argumentListBytes.IsValid() {
|
|
|
|
|
size := argumentListBytes.GetSize()
|
|
|
|
|
messageDataBytes = make([]byte, size)
|
|
|
|
|
c := argumentListBytes.GetData(messageDataBytes, 0)
|
|
|
|
|
argumentListBytes.Free()
|
|
|
|
|
if c == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var (
|
|
|
|
|
messageId int32
|
|
|
|
|
isReturnArgs bool
|
|
|
|
|
argumentList ipcArgument.IList // json.JSONArray
|
|
|
|
|
)
|
|
|
|
|
if messageDataBytes != nil {
|
|
|
|
|
argumentList = ipcArgument.UnList(messageDataBytes)
|
|
|
|
|
messageId = argumentList.MessageId()
|
2023-06-13 12:12:21 +08:00
|
|
|
|
isReturnArgs = argumentList.JSON() != nil
|
2023-05-31 17:41:14 +08:00
|
|
|
|
messageDataBytes = nil
|
|
|
|
|
}
|
|
|
|
|
defer func() {
|
|
|
|
|
if argumentList != nil {
|
|
|
|
|
argumentList.Reset()
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
if callback := m.emitHandler.getCallback(messageId); callback != nil {
|
|
|
|
|
var returnArgs json.JSONArray
|
|
|
|
|
defer func() {
|
|
|
|
|
if returnArgs != nil {
|
|
|
|
|
returnArgs.Free()
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
if callback.function != nil {
|
|
|
|
|
//设置允许释放
|
|
|
|
|
callback.function.SetCanNotFree(false)
|
|
|
|
|
}
|
2023-06-13 12:12:21 +08:00
|
|
|
|
if isReturnArgs {
|
|
|
|
|
//[]byte
|
|
|
|
|
returnArgs = argumentList.JSON().JSONArray()
|
|
|
|
|
}
|
2024-05-15 12:11:16 +08:00
|
|
|
|
v8ctx := frame.V8Context()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if returnArgs != nil {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.executeCallbackFunction(v8ctx, isReturnArgs, callback, returnArgs)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
} else {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
m.executeCallbackFunction(v8ctx, isReturnArgs, callback, nil)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
2023-08-23 19:27:42 +08:00
|
|
|
|
callback.function.Free()
|
|
|
|
|
callback.name.Free()
|
2024-05-15 12:11:16 +08:00
|
|
|
|
v8ctx.Free()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// 执行 v8 function 回调函数
|
2024-05-15 12:11:16 +08:00
|
|
|
|
func (m *ipcRenderProcess) executeCallbackFunction(v8ctx *ICefV8Context, isReturnArgs bool, callback *ipcCallback, returnArgs json.JSONArray) {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if isReturnArgs { //有返回参数
|
|
|
|
|
//enter v8context
|
2024-05-15 12:11:16 +08:00
|
|
|
|
if v8ctx.Enter() {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
var argsArray *TCefV8ValueArray
|
|
|
|
|
var err error
|
|
|
|
|
if callback.resultType == rt_function {
|
|
|
|
|
if returnArgs != nil {
|
|
|
|
|
//bytes to v8array value
|
|
|
|
|
argsArray, err = ValueConvert.JSONArrayToV8ArrayValue(returnArgs)
|
|
|
|
|
}
|
|
|
|
|
if argsArray != nil && err == nil {
|
|
|
|
|
// parse v8array success
|
2024-05-15 12:11:16 +08:00
|
|
|
|
callback.function.ExecuteFunctionWithContext(v8ctx, nil, argsArray).Free()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
argsArray.Free()
|
|
|
|
|
} else {
|
|
|
|
|
// parse v8array fail
|
2024-05-15 12:11:16 +08:00
|
|
|
|
callback.function.ExecuteFunctionWithContext(v8ctx, nil, nil).Free()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
} else if callback.resultType == rt_variable {
|
|
|
|
|
if returnArgs != nil && returnArgs.Size() > 0 {
|
|
|
|
|
//bytes to v8array value
|
|
|
|
|
argsArray, err = ValueConvert.JSONArrayToV8ArrayValue(returnArgs)
|
|
|
|
|
if argsArray != nil && err == nil {
|
|
|
|
|
if argsArray.Size() == 1 {
|
|
|
|
|
callback.variable = argsArray.Get(0)
|
|
|
|
|
callback.variable.SetCanNotFree(true)
|
|
|
|
|
} else {
|
|
|
|
|
callback.variable = V8ValueRef.NewArray(int32(argsArray.Size()))
|
|
|
|
|
for i := 0; i < argsArray.Size(); i++ {
|
|
|
|
|
callback.variable.SetValueByIndex(int32(i), argsArray.Get(i))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
argsArray.Free()
|
|
|
|
|
} else {
|
|
|
|
|
callback.variable = V8ValueRef.NewBool(true)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
callback.variable = V8ValueRef.NewBool(true)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//exit v8context
|
2024-05-15 12:11:16 +08:00
|
|
|
|
v8ctx.Exit()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
} else { //无返回参数
|
|
|
|
|
if callback.resultType == rt_function {
|
2024-05-15 12:11:16 +08:00
|
|
|
|
if v8ctx.Enter() {
|
|
|
|
|
callback.function.ExecuteFunctionWithContext(v8ctx, nil, nil).Free()
|
|
|
|
|
v8ctx.Exit()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
} else if callback.resultType == rt_variable {
|
|
|
|
|
// null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// Go IPC 渲染进程监听
|
2024-04-27 22:34:30 +08:00
|
|
|
|
func (m *ipcRenderProcess) registerGoWaitReplayEvent() {
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if m.isInitRenderIPC {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
m.isInitRenderIPC = true
|
|
|
|
|
ipc.RenderChan().AddCallback(func(channelId int64, argument ipcArgument.IList) bool {
|
|
|
|
|
if argument != nil {
|
|
|
|
|
name := argument.GetName()
|
2024-04-27 22:34:30 +08:00
|
|
|
|
if name == internalIPCJSExecuteGoWaitEventReplay {
|
2024-04-25 20:49:44 +08:00
|
|
|
|
var (
|
|
|
|
|
messageId = argument.MessageId()
|
|
|
|
|
argumentList json.JSONArray
|
|
|
|
|
)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
if argument.JSON() != nil {
|
|
|
|
|
argumentList = argument.JSON().JSONArray()
|
|
|
|
|
}
|
2024-04-25 20:49:44 +08:00
|
|
|
|
m.ipcJSExecuteGoSyncEventMessageReply(messageId, argumentList)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// JS执行Go事件 - 同步回复接收
|
|
|
|
|
func (m *ipcRenderProcess) ipcJSExecuteGoSyncEventMessageReply(messageId int32, argumentList json.JSONArray) {
|
|
|
|
|
m.waitChan.Done(messageId, argumentList)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:49:44 +08:00
|
|
|
|
// ipc
|
2024-06-23 15:34:51 +08:00
|
|
|
|
func (m *ipcRenderProcess) makeIPC(frameId int64, context *ICefV8Context) {
|
2024-01-05 23:52:52 +08:00
|
|
|
|
if m.ipcObject != nil {
|
|
|
|
|
// 刷新时释放掉
|
2024-06-23 15:34:51 +08:00
|
|
|
|
m.clear(frameId)
|
2024-01-05 23:52:52 +08:00
|
|
|
|
}
|
2023-05-31 17:41:14 +08:00
|
|
|
|
// ipc emit
|
|
|
|
|
m.emitHandler.handler = V8HandlerRef.New()
|
|
|
|
|
m.emitHandler.handler.Execute(m.jsExecuteGoEvent)
|
|
|
|
|
|
|
|
|
|
// ipc emit sync
|
|
|
|
|
m.emitHandler.handlerSync = V8HandlerRef.New()
|
|
|
|
|
m.emitHandler.handlerSync.Execute(m.jsExecuteGoEvent)
|
|
|
|
|
|
|
|
|
|
// ipc on
|
2024-06-23 15:34:51 +08:00
|
|
|
|
var on *ipcOnHandler
|
|
|
|
|
if handler, ok := m.onHandler[frameId]; ok {
|
|
|
|
|
on = handler
|
|
|
|
|
} else {
|
|
|
|
|
on = &ipcOnHandler{handler: V8HandlerRef.New(), callbackList: make(map[string]*ipcCallback)}
|
|
|
|
|
on.handler.Execute(on.jsOnEvent)
|
|
|
|
|
m.onHandler[frameId] = on
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//m.onHandler.handler = V8HandlerRef.New()
|
|
|
|
|
//m.onHandler.handler.Execute(m.jsOnEvent)
|
|
|
|
|
//on.handler = V8HandlerRef.New()
|
2023-05-31 17:41:14 +08:00
|
|
|
|
|
|
|
|
|
// ipc object
|
|
|
|
|
m.ipcObject = V8ValueRef.NewObject(nil)
|
|
|
|
|
m.ipcObject.setValueByKey(internalIPCEmit, V8ValueRef.newFunction(internalIPCEmit, m.emitHandler.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
2024-04-25 20:49:44 +08:00
|
|
|
|
m.ipcObject.setValueByKey(internalIPCEmitWait, V8ValueRef.newFunction(internalIPCEmitWait, m.emitHandler.handlerSync), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
2024-06-23 15:34:51 +08:00
|
|
|
|
m.ipcObject.setValueByKey(internalIPCOn, V8ValueRef.newFunction(internalIPCOn, on.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
2023-05-31 17:41:14 +08:00
|
|
|
|
|
|
|
|
|
// ipc key to v8 global
|
|
|
|
|
context.Global().setValueByKey(internalIPC, m.ipcObject, consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
|
|
|
|
}
|