space.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package app
  2. import (
  3. "errors"
  4. "v2ray.com/core/common"
  5. )
  6. var (
  7. ErrMissingApplication = errors.New("App: Failed to found one or more applications.")
  8. )
  9. type ID int
  10. // Context of a function call from proxy to app.
  11. type Context interface {
  12. CallerTag() string
  13. }
  14. type Caller interface {
  15. Tag() string
  16. }
  17. type Application interface {
  18. common.Releasable
  19. }
  20. type ApplicationInitializer func() error
  21. type ApplicationFactory interface {
  22. Create(space Space, config interface{}) (Application, error)
  23. AppId() ID
  24. }
  25. var (
  26. applicationFactoryCache map[string]ApplicationFactory
  27. )
  28. func RegisterApplicationFactory(name string, factory ApplicationFactory) error {
  29. applicationFactoryCache[name] = factory
  30. return nil
  31. }
  32. // A Space contains all apps that may be available in a V2Ray runtime.
  33. // Caller must check the availability of an app by calling HasXXX before getting its instance.
  34. type Space interface {
  35. Initialize() error
  36. InitializeApplication(ApplicationInitializer)
  37. HasApp(ID) bool
  38. GetApp(ID) Application
  39. BindApp(ID, Application)
  40. BindFromConfig(name string, config interface{}) error
  41. }
  42. type spaceImpl struct {
  43. cache map[ID]Application
  44. appInit []ApplicationInitializer
  45. }
  46. func NewSpace() Space {
  47. return &spaceImpl{
  48. cache: make(map[ID]Application),
  49. appInit: make([]ApplicationInitializer, 0, 32),
  50. }
  51. }
  52. func (this *spaceImpl) InitializeApplication(f ApplicationInitializer) {
  53. this.appInit = append(this.appInit, f)
  54. }
  55. func (this *spaceImpl) Initialize() error {
  56. for _, f := range this.appInit {
  57. err := f()
  58. if err != nil {
  59. return err
  60. }
  61. }
  62. return nil
  63. }
  64. func (this *spaceImpl) HasApp(id ID) bool {
  65. _, found := this.cache[id]
  66. return found
  67. }
  68. func (this *spaceImpl) GetApp(id ID) Application {
  69. obj, found := this.cache[id]
  70. if !found {
  71. return nil
  72. }
  73. return obj
  74. }
  75. func (this *spaceImpl) BindApp(id ID, application Application) {
  76. this.cache[id] = application
  77. }
  78. func (this *spaceImpl) BindFromConfig(name string, config interface{}) error {
  79. factory, found := applicationFactoryCache[name]
  80. if !found {
  81. return errors.New("Space: app not registered: " + name)
  82. }
  83. app, err := factory.Create(this, config)
  84. if err != nil {
  85. return err
  86. }
  87. this.BindApp(factory.AppId(), app)
  88. return nil
  89. }