package flow import "reflect" // Global var ( globalRegistry = NewRegistry() Register = globalRegistry.Register ) // Registry function registry type Registry struct { data map[string]interface{} } // NewRegistry creates a new registry func NewRegistry() *Registry { return &Registry{map[string]interface{}{}} } //Register should be a func only register func (r *Registry) Register(name string, v interface{}) error { fntyp := reflect.TypeOf(v) if fntyp.Kind() != reflect.Func { return ErrNotAFunc } if fntyp.NumOut() == 0 { return ErrOutput } r.data[name] = v return nil } // Get an entry func (r *Registry) Get(name string, params ...interface{}) (interface{}, error) { v, ok := r.data[name] if !ok { return nil, ErrNotFound } // We already know this is a function // and that returns 1 or more values vtyp := reflect.TypeOf(v) if vtyp.Out(0).Kind() == reflect.Func { fparam := make([]reflect.Value, len(params)) for i := range params { fparam[i] = reflect.ValueOf(params[i]) } // Call the func and return the thing v = reflect.ValueOf(v).Call(fparam)[0].Interface() } return v, nil } // opFunc creator /*type opFactory func() *opFunc // Registry of operator factory functions type Registry struct { opFactory map[string]opFactory } // NewRegistry Creates a new registry func NewRegistry() *Registry { r := &Registry{ map[string]opFactory{}, } return r } // Register a new operator func (r *Registry) Register(name string, fn interface{}) error { fntyp := reflect.TypeOf(fn) if fntyp.Kind() != reflect.Func { return ErrNotFunc } if fntyp.NumOut() == 0 { return ErrOutput } // Directly add this factory? if f, ok := fn.(opFactory); ok { r.opFactory[name] = f } // Constructor for func // opFunc creator? cfn := func() *opFunc { op := &opFunc{ executor: fn, } return op } // Create function factory for function? //Create factory from func r.opFactory[name] = cfn //return nil return nil } //Get a New Operation func (r *Registry) Get(name string) (*opFunc, error) { createOP, ok := r.opFactory[name] if !ok { return nil, errors.New("Does not exists") } return createOP(), nil }*/