registry.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package inbound
  2. import (
  3. "context"
  4. "sync"
  5. "github.com/sagernet/sing-box/adapter"
  6. "github.com/sagernet/sing-box/log"
  7. "github.com/sagernet/sing/common"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. )
  10. type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Inbound, error)
  11. func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
  12. registry.register(outboundType, func() any {
  13. return new(Options)
  14. }, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Inbound, error) {
  15. return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options.(*Options)))
  16. })
  17. }
  18. var _ adapter.InboundRegistry = (*Registry)(nil)
  19. type (
  20. optionsConstructorFunc func() any
  21. constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Inbound, error)
  22. )
  23. type Registry struct {
  24. access sync.Mutex
  25. optionsType map[string]optionsConstructorFunc
  26. constructors map[string]constructorFunc
  27. }
  28. func NewRegistry() *Registry {
  29. return &Registry{
  30. optionsType: make(map[string]optionsConstructorFunc),
  31. constructors: make(map[string]constructorFunc),
  32. }
  33. }
  34. func (r *Registry) CreateOptions(outboundType string) (any, bool) {
  35. r.access.Lock()
  36. defer r.access.Unlock()
  37. optionsConstructor, loaded := r.optionsType[outboundType]
  38. if !loaded {
  39. return nil, false
  40. }
  41. return optionsConstructor(), true
  42. }
  43. func (r *Registry) CreateInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Inbound, error) {
  44. r.access.Lock()
  45. defer r.access.Unlock()
  46. constructor, loaded := r.constructors[outboundType]
  47. if !loaded {
  48. return nil, E.New("outbound type not found: " + outboundType)
  49. }
  50. return constructor(ctx, router, logger, tag, options)
  51. }
  52. func (r *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
  53. r.access.Lock()
  54. defer r.access.Unlock()
  55. r.optionsType[outboundType] = optionsConstructor
  56. r.constructors[outboundType] = constructor
  57. }