space.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package app
  2. type ID int
  3. const (
  4. PACKET_DISPATCHER = ID(1)
  5. DNS_CACHE = ID(2)
  6. PUBSUB = ID(3)
  7. INBOUND_HANDLER_MANAGER = ID(4)
  8. )
  9. // Context of a function call from proxy to app.
  10. type Context interface {
  11. CallerTag() string
  12. }
  13. // A Space contains all apps that may be available in a V2Ray runtime.
  14. // Caller must check the availability of an app by calling HasXXX before getting its instance.
  15. type Space interface {
  16. HasApp(ID) bool
  17. GetApp(ID) interface{}
  18. }
  19. type ForContextCreator func(Context, interface{}) interface{}
  20. var (
  21. metadataCache = make(map[ID]ForContextCreator)
  22. )
  23. func RegisterApp(id ID, creator ForContextCreator) {
  24. // TODO: check id
  25. metadataCache[id] = creator
  26. }
  27. type contextImpl struct {
  28. callerTag string
  29. }
  30. func (this *contextImpl) CallerTag() string {
  31. return this.callerTag
  32. }
  33. type spaceImpl struct {
  34. cache map[ID]interface{}
  35. tag string
  36. }
  37. func newSpaceImpl(tag string, cache map[ID]interface{}) *spaceImpl {
  38. space := &spaceImpl{
  39. tag: tag,
  40. cache: make(map[ID]interface{}),
  41. }
  42. context := &contextImpl{
  43. callerTag: tag,
  44. }
  45. for id, object := range cache {
  46. creator, found := metadataCache[id]
  47. if found {
  48. space.cache[id] = creator(context, object)
  49. }
  50. }
  51. return space
  52. }
  53. func (this *spaceImpl) HasApp(id ID) bool {
  54. _, found := this.cache[id]
  55. return found
  56. }
  57. func (this *spaceImpl) GetApp(id ID) interface{} {
  58. obj, found := this.cache[id]
  59. if !found {
  60. return nil
  61. }
  62. return obj
  63. }
  64. // A SpaceController is supposed to be used by a shell to create Spaces. It should not be used
  65. // directly by proxies.
  66. type SpaceController struct {
  67. objectCache map[ID]interface{}
  68. }
  69. func NewController() *SpaceController {
  70. return &SpaceController{
  71. objectCache: make(map[ID]interface{}),
  72. }
  73. }
  74. func (this *SpaceController) Bind(id ID, object interface{}) {
  75. this.objectCache[id] = object
  76. }
  77. func (this *SpaceController) ForContext(tag string) Space {
  78. return newSpaceImpl(tag, this.objectCache)
  79. }