diff --git a/cef/cef-application-callback.go b/cef/cef-application-callback.go index 80db3fd6..375761cf 100644 --- a/cef/cef-application-callback.go +++ b/cef/cef-application-callback.go @@ -158,7 +158,13 @@ func (m *mainRun) ipcEmitMessage(browser *ICefBrowser, frame *ICefFrame, sourceP ipcContext := ipc.NewContext(browser.Identifier(), frame.Identifier(), argsBytes, isCallback) argsBytes = nil fmt.Println("ipcEmitMessage", isCallback, ipcContext) - eventCallback(ipcContext) + if ctxCallback := eventCallback.ContextCallback(); ctxCallback != nil { + ctxCallback(ipcContext) + } else if argsCallback := eventCallback.ArgumentCallback(); argsCallback != nil { + //rv := argsCallback.Callback() + //rv.Call() + ipcContext.ArgumentList() + } return //if isCallback { // //处理回复消息 diff --git a/example/dev-test/ipc-event/ipc-event.go b/example/dev-test/ipc-event/ipc-event.go index 4fca7ac5..1fb907ba 100644 --- a/example/dev-test/ipc-event/ipc-event.go +++ b/example/dev-test/ipc-event/ipc-event.go @@ -35,6 +35,9 @@ func main() { server.Assets = &resources go server.StartHttpServer() }) + ipc.OnArgument("testArgsEmitName", func(s string, v int, b bool, sarr []string, smap map[string]string) (string, int, bool) { + return "", 0, false + }) ipc.On("testEmitName", func(context ipc.IContext) { argument := context.ArgumentList() fmt.Println("testEmitName", argument.Size(), context.BrowserId(), context.FrameId()) diff --git a/ipc/ipc.go b/ipc/ipc.go index 45bc179f..a498d133 100644 --- a/ipc/ipc.go +++ b/ipc/ipc.go @@ -12,6 +12,8 @@ package ipc import ( "github.com/energye/energy/common" + "github.com/energye/energy/consts" + "reflect" "sync" ) @@ -19,25 +21,95 @@ var ( browser *browserIPC ) +type EmitContextCallback func(context IContext) +type EmitArgumentCallback any + // browserIPC 主进程 IPC type browserIPC struct { - onEvent map[string]EmitCallback + onEvent map[string]*callback lock sync.Mutex } -type EmitCallback func(context IContext) +type callback struct { + context *contextCallback + argument *argumentCallback +} + +type contextCallback struct { + callback EmitContextCallback //带上下文的回调函数 +} + +type argumentCallback struct { + callback *reflect.Value //带参数的回调函数 + inArgumentType []consts.GO_VALUE_TYPE //入参类型 + outArgumentType []consts.GO_VALUE_TYPE //出参类型 +} + +func (m *callback) ContextCallback() EmitContextCallback { + if m.context == nil { + return nil + } + return m.context.callback +} + +func (m *callback) ArgumentCallback() *argumentCallback { + if m.argument == nil { + return nil + } + return m.argument +} + +func (m *argumentCallback) Callback() *reflect.Value { + return m.callback +} + +func (m *argumentCallback) InArgumentType() []consts.GO_VALUE_TYPE { + return m.inArgumentType +} + +func (m *argumentCallback) OutArgumentType() []consts.GO_VALUE_TYPE { + return m.outArgumentType +} func init() { if common.Args.IsMain() { - browser = &browserIPC{onEvent: make(map[string]EmitCallback)} + browser = &browserIPC{onEvent: make(map[string]*callback)} } } //On -// IPC GO 监听事件 -func On(name string, fn EmitCallback) { +// IPC GO 监听事件, 上下文参数 +func On(name string, fn EmitContextCallback) { if browser != nil { - browser.addOnEvent(name, fn) + browser.addOnEvent(name, &callback{context: &contextCallback{callback: fn}}) + } +} + +//OnArgument +// IPC GO 监听事件, 自定义参数,仅支持对应 JavaScript 中的常用类型 +// +// 支持类型: int, bool, float, string, slice, map, struct +func OnArgument(name string, fn EmitArgumentCallback) { + if browser != nil { + v := reflect.ValueOf(fn) + // f must be a function + if v.Kind() != reflect.Func { + return + } + vt := v.Type() + inArgumentType := make([]consts.GO_VALUE_TYPE, vt.NumIn()) + outArgumentType := make([]consts.GO_VALUE_TYPE, vt.NumOut()) + for i := 0; i < len(inArgumentType); i++ { + it := vt.In(i) + gv, _ := common.FieldReflectType(it) + inArgumentType[i] = gv + } + for i := 0; i < len(outArgumentType); i++ { + ot := vt.Out(i) + gv, _ := common.FieldReflectType(ot) + inArgumentType[i] = gv + } + browser.addOnEvent(name, &callback{argument: &argumentCallback{callback: &v, inArgumentType: inArgumentType, outArgumentType: outArgumentType}}) } } @@ -60,20 +132,20 @@ func Emit(name string) { //CheckOnEvent // IPC 检查 GO 中监听的事件是存在, 并返回回调函数 -func CheckOnEvent(name string) EmitCallback { +func CheckOnEvent(name string) *callback { if browser == nil || name == "" { return nil } browser.lock.Lock() defer browser.lock.Unlock() - if callback, ok := browser.onEvent[name]; ok { - return callback + if fn, ok := browser.onEvent[name]; ok { + return fn } return nil } // addOnEvent 添加监听事件 -func (m *browserIPC) addOnEvent(name string, fn EmitCallback) { +func (m *browserIPC) addOnEvent(name string, fn *callback) { if m == nil || name == "" || fn == nil { return }