mirror of
				https://github.com/v2fly/v2ray-core.git
				synced 2025-10-31 01:39:16 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			110 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package app
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 
 | |
| 	"v2ray.com/core/common"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	ErrMissingApplication = errors.New("App: Failed to found one or more applications.")
 | |
| )
 | |
| 
 | |
| type ID int
 | |
| 
 | |
| // Context of a function call from proxy to app.
 | |
| type Context interface {
 | |
| 	CallerTag() string
 | |
| }
 | |
| 
 | |
| type Caller interface {
 | |
| 	Tag() string
 | |
| }
 | |
| 
 | |
| type Application interface {
 | |
| 	common.Releasable
 | |
| }
 | |
| 
 | |
| type ApplicationInitializer func() error
 | |
| type ApplicationFactory interface {
 | |
| 	Create(space Space, config interface{}) (Application, error)
 | |
| 	AppId() ID
 | |
| }
 | |
| 
 | |
| var (
 | |
| 	applicationFactoryCache = make(map[string]ApplicationFactory)
 | |
| )
 | |
| 
 | |
| func RegisterApplicationFactory(name string, factory ApplicationFactory) error {
 | |
| 	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 {
 | |
| 	Initialize() error
 | |
| 	InitializeApplication(ApplicationInitializer)
 | |
| 
 | |
| 	HasApp(ID) bool
 | |
| 	GetApp(ID) Application
 | |
| 	BindApp(ID, Application)
 | |
| 	BindFromConfig(name string, config interface{}) error
 | |
| }
 | |
| 
 | |
| type spaceImpl struct {
 | |
| 	cache   map[ID]Application
 | |
| 	appInit []ApplicationInitializer
 | |
| }
 | |
| 
 | |
| func NewSpace() Space {
 | |
| 	return &spaceImpl{
 | |
| 		cache:   make(map[ID]Application),
 | |
| 		appInit: make([]ApplicationInitializer, 0, 32),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (this *spaceImpl) InitializeApplication(f ApplicationInitializer) {
 | |
| 	this.appInit = append(this.appInit, f)
 | |
| }
 | |
| 
 | |
| func (this *spaceImpl) Initialize() error {
 | |
| 	for _, f := range this.appInit {
 | |
| 		err := f()
 | |
| 		if err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (this *spaceImpl) HasApp(id ID) bool {
 | |
| 	_, found := this.cache[id]
 | |
| 	return found
 | |
| }
 | |
| 
 | |
| func (this *spaceImpl) GetApp(id ID) Application {
 | |
| 	obj, found := this.cache[id]
 | |
| 	if !found {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return obj
 | |
| }
 | |
| 
 | |
| func (this *spaceImpl) BindApp(id ID, application Application) {
 | |
| 	this.cache[id] = application
 | |
| }
 | |
| 
 | |
| func (this *spaceImpl) BindFromConfig(name string, config interface{}) error {
 | |
| 	factory, found := applicationFactoryCache[name]
 | |
| 	if !found {
 | |
| 		return errors.New("Space: app not registered: " + name)
 | |
| 	}
 | |
| 	app, err := factory.Create(this, config)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	this.BindApp(factory.AppId(), app)
 | |
| 	return nil
 | |
| }
 | 
