mirror of
https://gitee.com/energye/energy.git
synced 2024-12-12 12:25:23 +08:00
192 lines
5.1 KiB
Go
192 lines
5.1 KiB
Go
//----------------------------------------
|
|
//
|
|
// 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 (
|
|
"github.com/energye/energy/pkgs/json"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"reflect"
|
|
)
|
|
|
|
// callback IPC 监听回调函数
|
|
type callback struct {
|
|
context *contextCallback //上下文参数回调
|
|
argument *argumentCallback //参数回调
|
|
}
|
|
|
|
// contextCallback 带上下文的回调函数
|
|
type contextCallback struct {
|
|
callback EmitContextCallback
|
|
}
|
|
|
|
// argumentCallback 带参数的回调函数
|
|
type argumentCallback struct {
|
|
callback *reflect.Value //回调函数
|
|
}
|
|
|
|
// ContextCallback 返回上下文参数回调
|
|
func (m *callback) ContextCallback() *contextCallback {
|
|
if m.context == nil {
|
|
return nil
|
|
}
|
|
return m.context
|
|
}
|
|
|
|
// Invoke 调用函数
|
|
func (m *contextCallback) Invoke(context IContext) {
|
|
// call
|
|
m.callback(context)
|
|
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
|
|
context.Result(resultArgument.Bytes())
|
|
resultArgument.Free()
|
|
} else {
|
|
context.Result(nil)
|
|
}
|
|
}
|
|
|
|
// ArgumentCallback 参数回调
|
|
func (m *callback) ArgumentCallback() *argumentCallback {
|
|
if m.argument == nil {
|
|
return nil
|
|
}
|
|
return m.argument
|
|
}
|
|
|
|
// Invoke 调用函数
|
|
func (m *argumentCallback) Invoke(context IContext) {
|
|
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 {
|
|
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
|
|
if jsonBytes := argsValue.Bytes(); jsonBytes != nil {
|
|
v := reflect.New(inType)
|
|
if err := jsoniter.Unmarshal(jsonBytes, v.Interface()); err == nil {
|
|
inArgsValues[i] = v.Elem()
|
|
}
|
|
}
|
|
}
|
|
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()
|
|
}
|
|
}
|
|
} else {
|
|
inArgsValues[i] = reflect.ValueOf(argsValue.Data())
|
|
}
|
|
}
|
|
case reflect.Slice:
|
|
if argsValue.IsArray() {
|
|
// slice 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()
|
|
}
|
|
}
|
|
} else {
|
|
inArgsValues[i] = reflect.ValueOf(argsValue.Data())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if !inArgsValues[i].IsValid() {
|
|
inArgsValues[i] = reflect.New(inType).Elem()
|
|
}
|
|
}
|
|
// call
|
|
resultValues := m.callback.Call(inArgsValues)
|
|
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)
|
|
}
|
|
}
|
|
// result
|
|
context.Result(resultArgument.Bytes())
|
|
resultArgument.Free()
|
|
} else {
|
|
// result nil
|
|
context.Result(nil)
|
|
}
|
|
}
|