| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | package appimport (	"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() errortype 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.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}
 |