space.go 2.0 KB

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