energy/ipc/ipc-invoke.go

205 lines
5.5 KiB
Go
Raw Normal View History

2023-03-11 13:50:09 +08:00
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
// Licensed under Apache License Version 2.0, January 2004
//
// https://www.apache.org/licenses/LICENSE-2.0
//
//----------------------------------------
package ipc
import (
2023-03-11 19:18:17 +08:00
"github.com/energye/energy/pkgs/json"
2023-03-11 13:50:09 +08:00
jsoniter "github.com/json-iterator/go"
"reflect"
)
// callback IPC 监听回调函数
type callback struct {
context *contextCallback //上下文参数回调
argument *argumentCallback //参数回调
}
// contextCallback 带上下文的回调函数
type contextCallback struct {
2023-03-15 14:29:45 +08:00
callback EmitContextCallback
2023-03-11 13:50:09 +08:00
}
// argumentCallback 带参数的回调函数
type argumentCallback struct {
2023-03-11 14:24:22 +08:00
callback *reflect.Value //回调函数
2023-03-11 13:50:09 +08:00
}
// ContextCallback 返回上下文参数回调
2023-03-11 19:18:17 +08:00
func (m *callback) ContextCallback() *contextCallback {
2023-03-11 13:50:09 +08:00
if m.context == nil {
return nil
}
2023-03-11 19:18:17 +08:00
return m.context
}
2023-03-12 00:51:00 +08:00
// Invoke 调用函数
2023-03-11 19:18:17 +08:00
func (m *contextCallback) Invoke(context IContext) {
2023-03-12 00:51:00 +08:00
// call
2023-03-11 19:18:17 +08:00
m.callback(context)
2023-03-12 00:51:00 +08:00
resultValues := context.Replay().Result()
if len(resultValues) > 0 {
// call result
resultArgument := json.NewJSONArray(nil)
for _, result := range resultValues {
switch result.(type) {
case error:
resultArgument.Add(result.(error).Error())
default:
resultArgument.Add(result)
}
}
// result bytes
context.Result(resultArgument.Bytes())
2023-03-14 21:04:16 +08:00
resultArgument.Free()
2023-03-12 00:51:00 +08:00
return
}
context.Result(nil)
2023-03-11 13:50:09 +08:00
}
// ArgumentCallback 参数回调
func (m *callback) ArgumentCallback() *argumentCallback {
if m.argument == nil {
return nil
}
return m.argument
}
// Invoke 调用函数
func (m *argumentCallback) Invoke(context IContext) {
2023-03-15 14:29:45 +08:00
var (
argsList json.JSONArray
argsSize int
inArgsValues []reflect.Value
)
argsList = context.ArgumentList()
if argsList != nil {
argsSize = argsList.Size()
rt := m.callback.Type()
inArgsCount := rt.NumIn()
inArgsValues = make([]reflect.Value, inArgsCount)
for i := 0; i < inArgsCount; i++ {
inType := rt.In(i)
if i < argsSize {
argsValue := argsList.GetByIndex(i)
if argsValue == nil {
inArgsValues[i] = reflect.New(inType).Elem()
continue
2023-03-11 13:50:09 +08:00
}
2023-03-15 14:29:45 +08:00
switch inType.Kind() {
case reflect.String:
inArgsValues[i] = reflect.ValueOf(argsValue.String())
case reflect.Int:
inArgsValues[i] = reflect.ValueOf(argsValue.Int())
case reflect.Int8:
inArgsValues[i] = reflect.ValueOf(int8(argsValue.Int()))
case reflect.Int16:
inArgsValues[i] = reflect.ValueOf(int16(argsValue.Int()))
case reflect.Int32:
inArgsValues[i] = reflect.ValueOf(int32(argsValue.Int()))
case reflect.Int64:
inArgsValues[i] = reflect.ValueOf(int64(argsValue.Int()))
case reflect.Uint:
inArgsValues[i] = reflect.ValueOf(uint(argsValue.Int()))
case reflect.Uint8:
inArgsValues[i] = reflect.ValueOf(uint8(argsValue.Int()))
case reflect.Uint16:
inArgsValues[i] = reflect.ValueOf(uint16(argsValue.Int()))
case reflect.Uint32:
inArgsValues[i] = reflect.ValueOf(uint32(argsValue.Int()))
case reflect.Uint64:
inArgsValues[i] = reflect.ValueOf(uint64(argsValue.Int()))
case reflect.Uintptr:
inArgsValues[i] = reflect.ValueOf(uintptr(argsValue.Int()))
case reflect.Float32:
inArgsValues[i] = reflect.ValueOf(float32(argsValue.Float()))
case reflect.Float64:
inArgsValues[i] = reflect.ValueOf(argsValue.Float())
case reflect.Bool:
inArgsValues[i] = reflect.ValueOf(argsValue.Bool())
case reflect.Struct:
if argsValue.IsObject() {
// struct
2023-03-11 13:50:09 +08:00
if jsonBytes := argsValue.Bytes(); jsonBytes != nil {
2023-03-15 14:29:45 +08:00
v := reflect.New(inType)
if err := jsoniter.Unmarshal(jsonBytes, v.Interface()); err == nil {
inArgsValues[i] = v.Elem()
2023-03-11 13:50:09 +08:00
continue
}
}
}
2023-03-11 14:24:22 +08:00
inArgsValues[i] = reflect.New(inType).Elem()
2023-03-15 14:29:45 +08:00
case reflect.Map:
if argsValue.IsObject() {
// map key=string : value != interface
if inType.Elem().Kind() != reflect.Interface {
if jsonBytes := argsValue.Bytes(); jsonBytes != nil {
vv := reflect.New(inType)
if err := jsoniter.Unmarshal(jsonBytes, vv.Interface()); err == nil {
inArgsValues[i] = vv.Elem()
continue
}
2023-03-11 13:50:09 +08:00
}
2023-03-15 14:29:45 +08:00
inArgsValues[i] = reflect.New(inType).Elem()
} else {
inArgsValues[i] = reflect.ValueOf(argsValue.Data())
2023-03-11 13:50:09 +08:00
}
2023-03-15 14:29:45 +08:00
} else {
2023-03-11 14:24:22 +08:00
inArgsValues[i] = reflect.New(inType).Elem()
2023-03-15 14:29:45 +08:00
}
case reflect.Slice:
if argsValue.IsArray() {
// slick value != interface
if inType.Elem().Kind() != reflect.Interface {
if jsonBytes := argsValue.Bytes(); jsonBytes != nil {
vv := reflect.New(inType)
if err := jsoniter.Unmarshal(jsonBytes, vv.Interface()); err == nil {
inArgsValues[i] = vv.Elem()
continue
}
}
inArgsValues[i] = reflect.New(inType).Elem()
} else {
inArgsValues[i] = reflect.ValueOf(argsValue.Data())
}
2023-03-11 13:50:09 +08:00
} else {
2023-03-15 14:29:45 +08:00
inArgsValues[i] = reflect.New(inType).Elem()
2023-03-11 13:50:09 +08:00
}
2023-03-15 14:29:45 +08:00
default:
2023-03-11 14:24:22 +08:00
inArgsValues[i] = reflect.New(inType).Elem()
2023-03-11 13:50:09 +08:00
}
2023-03-15 14:29:45 +08:00
} else {
2023-03-11 14:24:22 +08:00
inArgsValues[i] = reflect.New(inType).Elem()
2023-03-11 13:50:09 +08:00
}
}
}
// call
2023-03-11 14:24:22 +08:00
resultValues := m.callback.Call(inArgsValues)
2023-03-12 00:51:00 +08:00
if len(resultValues) > 0 {
// call result
resultArgument := json.NewJSONArray(nil)
for _, result := range resultValues {
res := result.Interface()
switch res.(type) {
case error:
resultArgument.Add(res.(error).Error())
default:
resultArgument.Add(res)
2023-03-11 19:18:17 +08:00
}
}
2023-03-12 00:51:00 +08:00
// result bytes
context.Result(resultArgument.Bytes())
2023-03-14 21:04:16 +08:00
resultArgument.Free()
2023-03-12 00:51:00 +08:00
return
2023-03-11 19:18:17 +08:00
}
2023-03-12 00:51:00 +08:00
// result nil
context.Result(nil)
2023-03-11 13:50:09 +08:00
}