83 lines
1.5 KiB
Go
83 lines
1.5 KiB
Go
|
package socketio
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
)
|
||
|
|
||
|
type caller struct {
|
||
|
Func reflect.Value
|
||
|
Args []reflect.Type
|
||
|
NeedSocket bool
|
||
|
}
|
||
|
|
||
|
func newCaller(f interface{}) (*caller, error) {
|
||
|
fv := reflect.ValueOf(f)
|
||
|
if fv.Kind() != reflect.Func {
|
||
|
return nil, fmt.Errorf("f is not func")
|
||
|
}
|
||
|
ft := fv.Type()
|
||
|
if ft.NumIn() == 0 {
|
||
|
return &caller{
|
||
|
Func: fv,
|
||
|
}, nil
|
||
|
}
|
||
|
args := make([]reflect.Type, ft.NumIn())
|
||
|
for i, n := 0, ft.NumIn(); i < n; i++ {
|
||
|
args[i] = ft.In(i)
|
||
|
}
|
||
|
needSocket := false
|
||
|
if args[0].Name() == "Socket" {
|
||
|
args = args[1:]
|
||
|
needSocket = true
|
||
|
}
|
||
|
return &caller{
|
||
|
Func: fv,
|
||
|
Args: args,
|
||
|
NeedSocket: needSocket,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (c *caller) GetArgs() []interface{} {
|
||
|
ret := make([]interface{}, len(c.Args))
|
||
|
for i, argT := range c.Args {
|
||
|
if argT.Kind() == reflect.Ptr {
|
||
|
argT = argT.Elem()
|
||
|
}
|
||
|
v := reflect.New(argT)
|
||
|
ret[i] = v.Interface()
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func (c *caller) Call(so Socket, args []interface{}) []reflect.Value {
|
||
|
var a []reflect.Value
|
||
|
diff := 0
|
||
|
if c.NeedSocket {
|
||
|
diff = 1
|
||
|
a = make([]reflect.Value, len(args)+1)
|
||
|
a[0] = reflect.ValueOf(so)
|
||
|
} else {
|
||
|
a = make([]reflect.Value, len(args))
|
||
|
}
|
||
|
|
||
|
if len(args) != len(c.Args) {
|
||
|
return []reflect.Value{reflect.ValueOf([]interface{}{}), reflect.ValueOf(errors.New("Arguments do not match"))}
|
||
|
}
|
||
|
|
||
|
for i, arg := range args {
|
||
|
v := reflect.ValueOf(arg)
|
||
|
if c.Args[i].Kind() != reflect.Ptr {
|
||
|
if v.IsValid() {
|
||
|
v = v.Elem()
|
||
|
} else {
|
||
|
v = reflect.Zero(c.Args[i])
|
||
|
}
|
||
|
}
|
||
|
a[i+diff] = v
|
||
|
}
|
||
|
|
||
|
return c.Func.Call(a)
|
||
|
}
|