space.go 1.9 KB

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