| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 | 
							- package app
 
- import (
 
- 	"github.com/golang/protobuf/proto"
 
- 	"v2ray.com/core/common/errors"
 
- 	"v2ray.com/core/common/log"
 
- 	"v2ray.com/core/common/serial"
 
- )
 
- type Application interface {
 
- }
 
- type InitializationCallback func() error
 
- type ApplicationFactory interface {
 
- 	Create(space Space, config interface{}) (Application, error)
 
- }
 
- type AppGetter interface {
 
- 	GetApp(name string) Application
 
- }
 
- var (
 
- 	applicationFactoryCache = make(map[string]ApplicationFactory)
 
- )
 
- func RegisterApplicationFactory(defaultConfig proto.Message, factory ApplicationFactory) error {
 
- 	if defaultConfig == nil {
 
- 		return errors.New("Space: config is nil.")
 
- 	}
 
- 	name := serial.GetMessageType(defaultConfig)
 
- 	if len(name) == 0 {
 
- 		return errors.New("Space: cannot get config type.")
 
- 	}
 
- 	applicationFactoryCache[name] = factory
 
- 	return nil
 
- }
 
- // A Space contains all apps that may be available in a V2Ray runtime.
 
- // Caller must check the availability of an app by calling HasXXX before getting its instance.
 
- type Space interface {
 
- 	AddApp(config proto.Message) error
 
- 	AddAppLegacy(name string, app Application)
 
- 	Initialize() error
 
- 	OnInitialize(InitializationCallback)
 
- }
 
- type spaceImpl struct {
 
- 	initialized bool
 
- 	cache       map[string]Application
 
- 	appInit     []InitializationCallback
 
- }
 
- func NewSpace() Space {
 
- 	return &spaceImpl{
 
- 		cache:   make(map[string]Application),
 
- 		appInit: make([]InitializationCallback, 0, 32),
 
- 	}
 
- }
 
- func (v *spaceImpl) OnInitialize(f InitializationCallback) {
 
- 	if v.initialized {
 
- 		if err := f(); err != nil {
 
- 			log.Error("Space: error after space initialization: ", err)
 
- 		}
 
- 	} else {
 
- 		v.appInit = append(v.appInit, f)
 
- 	}
 
- }
 
- func (v *spaceImpl) Initialize() error {
 
- 	for _, f := range v.appInit {
 
- 		if err := f(); err != nil {
 
- 			return err
 
- 		}
 
- 	}
 
- 	v.appInit = nil
 
- 	v.initialized = true
 
- 	return nil
 
- }
 
- func (v *spaceImpl) GetApp(configType string) Application {
 
- 	obj, found := v.cache[configType]
 
- 	if !found {
 
- 		return nil
 
- 	}
 
- 	return obj
 
- }
 
- func (v *spaceImpl) AddApp(config proto.Message) error {
 
- 	configName := serial.GetMessageType(config)
 
- 	factory, found := applicationFactoryCache[configName]
 
- 	if !found {
 
- 		return errors.New("Space: app not registered: ", configName)
 
- 	}
 
- 	app, err := factory.Create(v, config)
 
- 	if err != nil {
 
- 		return err
 
- 	}
 
- 	v.cache[configName] = app
 
- 	return nil
 
- }
 
- func (v *spaceImpl) AddAppLegacy(name string, application Application) {
 
- 	v.cache[name] = application
 
- }
 
 
  |