| 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()
 
- }*/
 
 
  |