space.go 2.1 KB

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