1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
package errorx
import "sync"
// TypeSubscriber is an interface to receive callbacks on the registered error namespaces and types.
// This may be used to create a user-defined registry, for example, to check if all type names are unique.
// ISSUE: if .ApplyModifiers is called for a type/namespace, callback still receives a value without those modifiers.
type TypeSubscriber interface {
// OnNamespaceCreated is called exactly once for each namespace
OnNamespaceCreated(namespace Namespace)
// OnTypeCreated is called exactly once for each type
OnTypeCreated(t *Type)
}
// RegisterTypeSubscriber adds a new TypeSubscriber.
// A subscriber is guaranteed to receive callbacks for all namespaces and types.
// If a type is already registered at the moment of subscription, a callback for this type is called immediately.
func RegisterTypeSubscriber(s TypeSubscriber) {
globalRegistry.registerTypeSubscriber(s)
}
type registry struct {
mu sync.Mutex
subscribers []TypeSubscriber
knownNamespaces []Namespace
knownTypes []*Type
}
var globalRegistry = ®istry{}
func (r *registry) registerNamespace(namespace Namespace) {
r.mu.Lock()
defer r.mu.Unlock()
r.knownNamespaces = append(r.knownNamespaces, namespace)
for _, s := range r.subscribers {
s.OnNamespaceCreated(namespace)
}
}
func (r *registry) registerType(t *Type) {
r.mu.Lock()
defer r.mu.Unlock()
r.knownTypes = append(r.knownTypes, t)
for _, s := range r.subscribers {
s.OnTypeCreated(t)
}
}
func (r *registry) registerTypeSubscriber(s TypeSubscriber) {
for _, ns := range r.knownNamespaces {
s.OnNamespaceCreated(ns)
}
for _, t := range r.knownTypes {
s.OnTypeCreated(t)
}
r.subscribers = append(r.subscribers, s)
}
|