2023-05-08 13:21:31 +00:00
|
|
|
package sdk
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-05-13 15:46:09 +00:00
|
|
|
"strings"
|
2023-05-08 13:21:31 +00:00
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
2023-05-13 15:46:09 +00:00
|
|
|
type Reference struct {
|
|
|
|
Category Category
|
|
|
|
Type string
|
|
|
|
}
|
|
|
|
|
2023-05-08 13:21:31 +00:00
|
|
|
type Registration interface {
|
|
|
|
RegisterAt(registry *TypeRegistry)
|
|
|
|
}
|
|
|
|
|
|
|
|
type RegistrationFunc func(registry *TypeRegistry)
|
|
|
|
|
|
|
|
func (f RegistrationFunc) RegisterAt(registry *TypeRegistry) {
|
|
|
|
f(registry)
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTypeRegistry() *TypeRegistry {
|
|
|
|
return &TypeRegistry{
|
|
|
|
registrations: make(map[string]Factory),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type TypeRegistry struct {
|
|
|
|
lock sync.Mutex
|
|
|
|
registrations map[string]Factory
|
|
|
|
}
|
|
|
|
|
2023-05-13 15:46:09 +00:00
|
|
|
func (r *TypeRegistry) List() (refs []Reference) {
|
|
|
|
refs = make([]Reference, 0, len(r.registrations))
|
|
|
|
|
|
|
|
for k := range r.registrations {
|
|
|
|
split := strings.SplitN(k, "/", 2)
|
|
|
|
if len(split) < 2 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
refs = append(refs, Reference{
|
|
|
|
Category: Category(split[0]),
|
|
|
|
Type: split[1],
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return refs
|
|
|
|
}
|
|
|
|
|
2023-05-08 13:21:31 +00:00
|
|
|
func (r *TypeRegistry) Add(cat Category, moduleName string, factory Factory) {
|
|
|
|
r.lock.Lock()
|
|
|
|
defer r.lock.Unlock()
|
|
|
|
|
|
|
|
r.registrations[specOf(cat, moduleName)] = factory
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *TypeRegistry) Get(cat Category, moduleName string) Module {
|
|
|
|
f, ok := r.registrations[specOf(cat, moduleName)]
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return f.Create()
|
|
|
|
}
|
|
|
|
|
|
|
|
func specOf(cat Category, moduleName string) string {
|
|
|
|
return fmt.Sprintf("%s/%s", cat.String(), moduleName)
|
|
|
|
}
|