2023-03-03 17:08:06 +08:00
|
|
|
//----------------------------------------
|
|
|
|
//
|
|
|
|
// Copyright © yanghy. All Rights Reserved.
|
|
|
|
//
|
|
|
|
// Licensed under Apache License Version 2.0, January 2004
|
|
|
|
//
|
|
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
//----------------------------------------
|
|
|
|
|
2023-03-13 11:29:51 +08:00
|
|
|
// energy ipc 事件驱动监听
|
|
|
|
//
|
|
|
|
// 事件监听、事件触发
|
2023-03-03 17:08:06 +08:00
|
|
|
package ipc
|
|
|
|
|
2023-03-03 21:53:18 +08:00
|
|
|
import (
|
|
|
|
"github.com/energye/energy/common"
|
2023-03-14 17:07:15 +08:00
|
|
|
"github.com/energye/energy/consts"
|
2023-03-10 18:12:24 +08:00
|
|
|
"reflect"
|
2023-03-03 21:53:18 +08:00
|
|
|
"sync"
|
|
|
|
)
|
2023-03-03 17:08:06 +08:00
|
|
|
|
2023-03-03 21:53:18 +08:00
|
|
|
var (
|
|
|
|
browser *browserIPC
|
|
|
|
)
|
2023-03-03 17:08:06 +08:00
|
|
|
|
2023-03-15 14:29:45 +08:00
|
|
|
// EmitContextCallback IPC 上下文件回调函数
|
|
|
|
type EmitContextCallback func(context IContext)
|
2023-03-10 18:12:24 +08:00
|
|
|
|
2023-03-03 21:53:18 +08:00
|
|
|
// browserIPC 主进程 IPC
|
|
|
|
type browserIPC struct {
|
2023-03-14 17:07:15 +08:00
|
|
|
onEvent map[string]*callback
|
2023-03-15 14:29:45 +08:00
|
|
|
emitCallback map[int32]*callback
|
2023-03-14 17:07:15 +08:00
|
|
|
emitCallbackMessageId int32
|
|
|
|
onLock sync.Mutex
|
|
|
|
emitLock sync.Mutex
|
|
|
|
processMessage IProcessMessage
|
2023-03-03 17:08:06 +08:00
|
|
|
}
|
|
|
|
|
2023-03-03 21:53:18 +08:00
|
|
|
func init() {
|
|
|
|
if common.Args.IsMain() {
|
2023-03-15 14:29:45 +08:00
|
|
|
browser = &browserIPC{onEvent: make(map[string]*callback), emitCallback: make(map[int32]*callback)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func createCallback(fn any) *callback {
|
|
|
|
switch fn.(type) {
|
|
|
|
case func(context IContext):
|
|
|
|
return &callback{context: &contextCallback{callback: fn.(func(context IContext))}}
|
|
|
|
default:
|
|
|
|
v := reflect.ValueOf(fn)
|
|
|
|
// f must be a function
|
|
|
|
if v.Kind() != reflect.Func {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return &callback{argument: &argumentCallback{callback: &v}}
|
2023-03-14 17:07:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-15 14:50:08 +08:00
|
|
|
// SetProcessMessage 设置进程消息对象, 不需要手动调用
|
2023-03-14 17:07:15 +08:00
|
|
|
func SetProcessMessage(pm IProcessMessage) {
|
|
|
|
if browser == nil || pm == nil {
|
|
|
|
return
|
2023-03-03 21:53:18 +08:00
|
|
|
}
|
2023-03-14 17:07:15 +08:00
|
|
|
browser.processMessage = pm
|
2023-03-03 21:53:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//On
|
2023-03-15 14:29:45 +08:00
|
|
|
//
|
2023-03-15 14:45:01 +08:00
|
|
|
// 参数 回调函数fn: EmitContextCallback 或 func(...) {}
|
2023-03-15 14:29:45 +08:00
|
|
|
//
|
2023-03-11 00:02:03 +08:00
|
|
|
// IPC GO 监听事件, 自定义参数,仅支持对应 JavaScript 对应 Go 的常用类型
|
2023-03-10 18:12:24 +08:00
|
|
|
//
|
2023-03-11 00:02:03 +08:00
|
|
|
// 入参 不限制个数
|
|
|
|
// 基本类型: int(int8 ~ uint64), bool, float(float32、float64), string
|
|
|
|
//
|
|
|
|
// 复杂类型: slice, map, struct
|
|
|
|
//
|
|
|
|
// 复杂类型限制示例: slice: []interface{}, map: map[string]interface{}
|
|
|
|
//
|
|
|
|
// slice: 只能是 any 或 interface{}
|
2023-03-11 14:24:22 +08:00
|
|
|
// map: key 只能 string 类型, value 基本类型+复杂类型
|
2023-03-11 00:02:03 +08:00
|
|
|
// struct: 首字母大写, 字段类型匹配
|
|
|
|
// type ArgsStructDemo struct {
|
2023-03-11 14:24:22 +08:00
|
|
|
// Key1 string
|
|
|
|
// Key2 string
|
2023-03-11 00:02:03 +08:00
|
|
|
// Key3 string
|
|
|
|
// Key4 int
|
|
|
|
// Key5 float64
|
|
|
|
// Key6 bool
|
2023-03-11 14:24:22 +08:00
|
|
|
// Sub1 SubStructXXX
|
|
|
|
// Sub2 *SubStructXXX
|
2023-03-11 00:02:03 +08:00
|
|
|
// }
|
|
|
|
//
|
|
|
|
// 出参
|
|
|
|
//
|
2023-03-15 14:29:45 +08:00
|
|
|
// 与入参相同
|
|
|
|
func On(name string, fn any) {
|
|
|
|
if callbackFN := createCallback(fn); callbackFN != nil {
|
|
|
|
browser.addOnEvent(name, callbackFN)
|
2023-03-03 21:53:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//RemoveOn
|
|
|
|
// IPC GO 移除监听事件
|
|
|
|
func RemoveOn(name string) {
|
|
|
|
if browser == nil || name == "" {
|
|
|
|
return
|
|
|
|
}
|
2023-03-14 17:07:15 +08:00
|
|
|
browser.onLock.Lock()
|
|
|
|
defer browser.onLock.Unlock()
|
2023-03-03 21:53:18 +08:00
|
|
|
delete(browser.onEvent, name)
|
|
|
|
}
|
|
|
|
|
|
|
|
//Emit
|
|
|
|
// IPC GO 中触发 JS 监听的事件
|
2023-03-15 14:29:45 +08:00
|
|
|
//
|
|
|
|
// 参数
|
|
|
|
// name: JS 监听的事件名
|
|
|
|
// []argument: 入参 基本类型: int(int8 ~ uint64), bool, float(float32、float64), string
|
|
|
|
// 复杂类型: slice, map, struct
|
|
|
|
// 复杂类型限制示例: slice: []interface{}, map: map[string]interface{}
|
2023-03-14 12:13:30 +08:00
|
|
|
func Emit(name string, argument ...any) {
|
2023-03-14 17:07:15 +08:00
|
|
|
if browser == nil || name == "" || browser.processMessage == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
browser.processMessage.SendProcessMessageForIPC(0, name, consts.PID_RENDER, nil, argument...)
|
|
|
|
}
|
2023-03-03 17:08:06 +08:00
|
|
|
|
2023-03-14 17:07:15 +08:00
|
|
|
//EmitAndCallback
|
|
|
|
// IPC GO 中触发 JS 监听的事件
|
2023-03-15 14:29:45 +08:00
|
|
|
//
|
|
|
|
// 参数
|
|
|
|
// name: JS 监听的事件名
|
|
|
|
// []argument: 入参 基本类型: int(int8 ~ uint64), bool, float(float32、float64), string
|
|
|
|
// 复杂类型: slice, map, struct
|
|
|
|
// 复杂类型限制示例: slice: []interface{}, map: map[string]interface{}
|
|
|
|
// callback: 无返回值的回调函数, 接收返回值. 函数类型 EmitContextCallback 或 func(...) {}
|
2023-03-15 14:45:01 +08:00
|
|
|
func EmitAndCallback(name string, argument []any, fn any) {
|
2023-03-14 17:07:15 +08:00
|
|
|
if browser == nil || name == "" || browser.processMessage == nil {
|
|
|
|
return
|
|
|
|
}
|
2023-03-15 14:45:01 +08:00
|
|
|
messageId := browser.addEmitCallback(fn)
|
2023-03-14 17:07:15 +08:00
|
|
|
browser.processMessage.SendProcessMessageForIPC(messageId, name, consts.PID_RENDER, nil, argument...)
|
2023-03-03 17:08:06 +08:00
|
|
|
}
|
|
|
|
|
2023-03-14 17:07:15 +08:00
|
|
|
//EmitTarget
|
|
|
|
// IPC GO 中触发指定目标 JS 监听的事件
|
2023-03-15 14:29:45 +08:00
|
|
|
//
|
|
|
|
// 参数
|
|
|
|
// name: JS 监听的事件名
|
|
|
|
// target: 接收事件的目标
|
|
|
|
// []argument: 入参 基本类型: int(int8 ~ uint64), bool, float(float32、float64), string
|
|
|
|
// 复杂类型: slice, map, struct
|
|
|
|
// 复杂类型限制示例: slice: []interface{}, map: map[string]interface{}
|
2023-03-14 17:07:15 +08:00
|
|
|
func EmitTarget(name string, target ITarget, argument ...any) {
|
|
|
|
if browser == nil || name == "" || browser.processMessage == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
browser.processMessage.SendProcessMessageForIPC(0, name, consts.PID_RENDER, target, argument...)
|
|
|
|
}
|
|
|
|
|
|
|
|
//EmitTargetAndCallback
|
|
|
|
// IPC GO 中触发指定目标 JS 监听的事件
|
2023-03-15 14:29:45 +08:00
|
|
|
//
|
|
|
|
// 参数
|
|
|
|
// name: JS 监听的事件名
|
|
|
|
// target: 接收事件的目标
|
|
|
|
// []argument: 入参 基本类型: int(int8 ~ uint64), bool, float(float32、float64), string
|
|
|
|
// 复杂类型: slice, map, struct
|
|
|
|
// 复杂类型限制示例: slice: []interface{}, map: map[string]interface{}
|
|
|
|
// callback: 无返回值的回调函数, 接收返回值. 函数类型 EmitContextCallback 或 func(...) {}
|
2023-03-15 14:45:01 +08:00
|
|
|
func EmitTargetAndCallback(name string, target ITarget, argument []any, fn any) {
|
2023-03-14 17:07:15 +08:00
|
|
|
if browser == nil || name == "" || browser.processMessage == nil {
|
|
|
|
return
|
|
|
|
}
|
2023-03-15 14:45:01 +08:00
|
|
|
messageId := browser.addEmitCallback(fn)
|
2023-03-14 17:07:15 +08:00
|
|
|
browser.processMessage.SendProcessMessageForIPC(messageId, name, consts.PID_RENDER, target, argument...)
|
|
|
|
}
|
2023-03-14 12:13:30 +08:00
|
|
|
|
2023-03-03 21:53:18 +08:00
|
|
|
//CheckOnEvent
|
2023-03-15 14:50:08 +08:00
|
|
|
// IPC 检查 GO 中监听的事件是否存在,同时返回函数并移除
|
2023-03-10 18:12:24 +08:00
|
|
|
func CheckOnEvent(name string) *callback {
|
2023-03-03 21:53:18 +08:00
|
|
|
if browser == nil || name == "" {
|
|
|
|
return nil
|
|
|
|
}
|
2023-03-14 17:07:15 +08:00
|
|
|
browser.onLock.Lock()
|
|
|
|
defer browser.onLock.Unlock()
|
2023-03-10 18:12:24 +08:00
|
|
|
if fn, ok := browser.onEvent[name]; ok {
|
|
|
|
return fn
|
2023-03-03 21:53:18 +08:00
|
|
|
}
|
|
|
|
return nil
|
2023-03-03 17:08:06 +08:00
|
|
|
}
|
|
|
|
|
2023-03-14 17:07:15 +08:00
|
|
|
//CheckEmitCallback
|
2023-03-15 14:50:08 +08:00
|
|
|
// IPC 检查 GO Emit 回调函数是否存在,同时返回函数并移除
|
2023-03-15 14:29:45 +08:00
|
|
|
func CheckEmitCallback(id int32) *callback {
|
2023-03-14 17:07:15 +08:00
|
|
|
if browser == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
browser.emitLock.Lock()
|
|
|
|
defer browser.emitLock.Unlock()
|
|
|
|
if fn, ok := browser.emitCallback[id]; ok {
|
2023-03-15 14:29:45 +08:00
|
|
|
delete(browser.emitCallback, id)
|
|
|
|
return fn
|
2023-03-14 17:07:15 +08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-03-03 21:53:18 +08:00
|
|
|
// addOnEvent 添加监听事件
|
2023-03-10 18:12:24 +08:00
|
|
|
func (m *browserIPC) addOnEvent(name string, fn *callback) {
|
2023-03-03 21:53:18 +08:00
|
|
|
if m == nil || name == "" || fn == nil {
|
|
|
|
return
|
|
|
|
}
|
2023-03-14 17:07:15 +08:00
|
|
|
m.onLock.Lock()
|
|
|
|
defer m.onLock.Unlock()
|
2023-03-03 21:53:18 +08:00
|
|
|
m.onEvent[name] = fn
|
2023-03-03 17:08:06 +08:00
|
|
|
}
|
|
|
|
|
2023-03-03 21:53:18 +08:00
|
|
|
// emitOnEvent 触发监听事件
|
|
|
|
func (m *browserIPC) emitOnEvent(name string, argumentList IArrayValue) {
|
|
|
|
if m == nil || name == "" || argumentList == nil {
|
|
|
|
return
|
|
|
|
}
|
2023-03-14 17:07:15 +08:00
|
|
|
m.onLock.Lock()
|
|
|
|
defer m.onLock.Unlock()
|
|
|
|
}
|
2023-03-03 21:53:18 +08:00
|
|
|
|
2023-03-14 17:07:15 +08:00
|
|
|
// addOnEvent 添加emit回调函数
|
|
|
|
func (m *browserIPC) addEmitCallback(fn any) int32 {
|
|
|
|
if m == nil || fn == nil {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
m.emitLock.Lock()
|
|
|
|
defer m.emitLock.Unlock()
|
2023-03-15 14:29:45 +08:00
|
|
|
if callbackFN := createCallback(fn); callbackFN != nil {
|
|
|
|
if m.emitCallbackMessageId == -1 {
|
|
|
|
m.emitCallbackMessageId = 1
|
|
|
|
} else {
|
|
|
|
m.emitCallbackMessageId++
|
|
|
|
}
|
|
|
|
m.emitCallback[m.emitCallbackMessageId] = callbackFN
|
|
|
|
return m.emitCallbackMessageId
|
2023-03-14 17:07:15 +08:00
|
|
|
}
|
2023-03-15 14:29:45 +08:00
|
|
|
return 0
|
2023-03-03 17:08:06 +08:00
|
|
|
}
|