go-hep.org/x/hep@v0.38.1/fwk/registry.go (about) 1 // Copyright ©2017 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package fwk 6 7 import ( 8 "fmt" 9 "reflect" 10 "sort" 11 ) 12 13 // FactoryFunc creates a Component of type t and name n, managed by the fwk.App mgr. 14 type FactoryFunc func(t, n string, mgr App) (Component, error) 15 16 // factoryDb associates a fully-qualified type-name (pkg-path + type-name) with 17 // a component factory-function. 18 type factoryDb map[string]FactoryFunc 19 20 var gFactory = make(factoryDb) 21 22 // Register registers a type t with the FactoryFunc fct. 23 // 24 // fwk.ComponentMgr will then be able to create new values of that type t 25 // using the associated FactoryFunc fct. 26 // If a type t was already registered, the previous FactoryFunc value will be 27 // silently overridden with the new FactoryFunc value. 28 func Register(t reflect.Type, fct FactoryFunc) { 29 comp := t.PkgPath() + "." + t.Name() 30 gFactory[comp] = fct 31 //fmt.Printf("### factories ###\n%v\n", gFactory) 32 } 33 34 // Registry returns the list of all registered and known components. 35 func Registry() []string { 36 comps := make([]string, 0, len(gFactory)) 37 for k := range gFactory { 38 comps = append(comps, k) 39 } 40 sort.Strings(comps) 41 return comps 42 } 43 44 // New creates a new Component value with type t and name n. 45 func (app *appmgr) New(t, n string) (Component, error) { 46 var err error 47 fct, ok := gFactory[t] 48 if !ok { 49 return nil, fmt.Errorf("no component with type [%s] registered", t) 50 } 51 52 if _, dup := app.props[n]; dup { 53 return nil, fmt.Errorf("component with name [%s] already created", n) 54 } 55 app.props[n] = make(map[string]any) 56 57 c, err := fct(t, n, app) 58 if err != nil { 59 return nil, fmt.Errorf("error creating [%s:%s]: %w", t, n, err) 60 } 61 if c.Name() == "" { 62 return nil, fmt.Errorf("factory for [%s] does NOT set the name of the component", t) 63 } 64 65 err = app.addComponent(c) 66 if err != nil { 67 return nil, err 68 } 69 70 switch c := c.(type) { 71 case Svc: 72 err = app.AddSvc(c) 73 if err != nil { 74 return nil, err 75 } 76 case Task: 77 err = app.AddTask(c) 78 if err != nil { 79 return nil, err 80 } 81 } 82 83 return c, err 84 }