123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- package vnode
- import (
- "fmt"
- "log"
- "reflect"
- )
- type IVNode interface {
- Result() interface{}
- }
- const (
- OPT_VAR = iota
- OPT_FUNC
- OPT_FUNCI
- OPT_SFUNC
- )
- type Result interface{}
- type VNodeFunc func(*VNode) Result
- type SourceEntry struct {
- fnInputType reflect.Type
- srcInputInterface interface{}
- srcInputValue reflect.Value //
- srcInputFn func() interface{}
- //iface interface{}
- Value func() reflect.Value
- //fnHandler func() reflect.Value
- opType int
- }
- type VNode struct {
- sourceList []SourceEntry
- mainFuncValue reflect.Value
- specialFn func(...interface{}) interface{}
- }
- func New(fns ...interface{}) *VNode {
- var vn VNode
- fn := fns[0]
- nInputs := 0
- if len(fns) > 1 {
- nInputs = fns[1].(int)
- }
- rfn := reflect.ValueOf(fn)
- // Or Pointer
- // Check type func
- if rfn.Kind() != reflect.Func {
- log.Println("Argument should be a function")
- return nil
- }
- vn.mainFuncValue = rfn
- // could this reduce complexity??
- /*var Func func(...interface{}) interface{}
- if rfn.Type() != reflect.TypeOf(Func) {
- nInputs = rfn.Type().NumIn()
- madeFn := reflect.MakeFunc(reflect.TypeOf(Func), func(in []reflect.Value) []reflect.Value {
- nargs := []reflect.Value{}
- for i := 0; i < in[0].Len(); i++ {
- narg := in[0].Index(i).Elem()
- nargs = append(nargs, narg)
- }
- res := rfn.Call(nargs)
- v := res[0].Interface()
- return []reflect.Value{reflect.ValueOf(&v).Elem()}
- })
- reflect.ValueOf(&Func).Elem().Set(madeFn)
- fn = Func
- }*/
- switch fn.(type) {
- case func(...interface{}) interface{}:
- vn.specialFn = fn.(func(...interface{}) interface{})
- vn.sourceList = make([]SourceEntry, nInputs)
- for i := 0; i < nInputs; i++ {
- vn.sourceList[i].fnInputType = nil
- }
- default:
- nInputs = rfn.Type().NumIn()
- vn.sourceList = make([]SourceEntry, nInputs)
- for i := 0; i < nInputs; i++ {
- vn.sourceList[i].fnInputType = rfn.Type().In(i)
- }
- }
- return &vn
- }
- func (vn *VNode) SourceAt(i int, val interface{}) error {
- se := &vn.sourceList[i]
- // If fninputType is interface we can accept anything
- // Do some type checks here
- se.srcInputValue = reflect.ValueOf(val)
- if se.srcInputValue.Type() == reflect.TypeOf(vn) {
- se.srcInputValue = reflect.ValueOf(func() interface{} {
- return val.(*VNode).Exec()
- })
- }
- var t func() interface{}
- if se.srcInputValue.Type() == reflect.TypeOf(t) {
- se.Value = func() reflect.Value {
- return reflect.ValueOf(se.srcInputValue.Interface().(func() interface{})())
- }
- se.srcInputFn = se.srcInputValue.Interface().(func() interface{})
- se.opType = OPT_SFUNC
- return nil
- }
- // Especial case:
- if se.srcInputValue.Kind() == reflect.Func {
- if se.srcInputValue.Type().NumOut() != 1 { // we could ignore this
- return fmt.Errorf("Input: %d Invalid number of returns", i)
- }
- out := se.srcInputValue.Type().Out(0)
- // check output type if not interface or same type
- /*if out.Kind() != reflect.Interface && out != se.fnInputType {
- return fmt.Errorf("Input: %d Type mismatch", i)
- }*/
- if out.Kind() == reflect.Interface {
- se.Value = func() reflect.Value {
- return se.srcInputValue.Call([]reflect.Value{})[0].Elem()
- }
- se.opType = OPT_FUNCI
- } else {
- se.Value = func() reflect.Value {
- return se.srcInputValue.Call([]reflect.Value{})[0]
- }
- se.opType = OPT_FUNC
- }
- } else if se.srcInputValue.Type() == se.fnInputType || se.fnInputType == nil {
- se.Value = func() reflect.Value {
- return se.srcInputValue
- }
- se.srcInputInterface = se.srcInputValue.Interface()
- se.opType = OPT_VAR
- } else {
- return fmt.Errorf("Input: %d Didn't match", i)
- }
- //vn.sourceList[i] = se
- return nil
- }
- func (vn *VNode) Source(vnodes ...interface{}) error {
- for i, vnode := range vnodes {
- err := vn.SourceAt(i, vnode)
- if err != nil {
- return err
- }
- }
- return nil
- }
- // Change to execute
- func (vn *VNode) Exec() Result {
- //special case
- if vn.specialFn != nil {
- iargs := make([]interface{}, len(vn.sourceList))
- for i, se := range vn.sourceList {
- switch se.opType {
- case OPT_VAR: // Direct value input
- iargs[i] = se.srcInputInterface
- case OPT_SFUNC: // Function returning interface , optimizations
- iargs[i] = se.srcInputFn()
- default: // Function call
- iargs[i] = se.srcInputValue.Call([]reflect.Value{})[0].Interface()
- //iargs[i] = se.Value().Interface()
- }
- }
- return vn.specialFn(iargs...)
- }
- rargs := make([]reflect.Value, len(vn.sourceList))
- for i, se := range vn.sourceList {
- switch se.opType {
- case OPT_VAR: // Direct value input
- rargs[i] = se.srcInputValue
- case OPT_FUNC:
- rargs[i] = se.srcInputValue.Call([]reflect.Value{})[0]
- case OPT_FUNCI:
- rargs[i] = se.srcInputValue.Call([]reflect.Value{})[0].Elem()
- case OPT_SFUNC: // Function returning interface , optimizations
- rargs[i] = se.Value()
- default: // Function call
- rargs[i] = se.Value()
- //iargs[i] = se.srcInputValue.Call([]reflect.Value{})[0].Interface()
- //iargs[i] = se.Value().Interface()
- }
- }
- return vn.mainFuncValue.Call(rargs)[0].Interface()
- }
- // Exec input here
- /*func (vn *VNode) input(i int) interface{} {
- in := vn.sourceList[i]
- return in.fnHandler().Interface()
- }*/
|