66 lines
2.2 KiB
Go
66 lines
2.2 KiB
Go
package component
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
|
)
|
|
|
|
type ComponentPool struct {
|
|
pool lazy.Pool[Component, Core]
|
|
poolInit sync.Once
|
|
}
|
|
|
|
func (pool *ComponentPool) init() {
|
|
pool.poolInit.Do(func() {
|
|
pool.pool.Init = func(component Component, core Core) Component {
|
|
component.getBase().Core = core
|
|
return component
|
|
}
|
|
})
|
|
}
|
|
|
|
type ComponentPoolContext = *lazy.PoolContext[Component]
|
|
type ComponentAllFunc = func(context ComponentPoolContext) []Component
|
|
|
|
func (pool *ComponentPool) All(core Core, init func(context ComponentPoolContext) []Component) []Component {
|
|
pool.init()
|
|
return pool.pool.All(core, init)
|
|
}
|
|
|
|
// MakeComponent creates or returns a cached component of the given Context.
|
|
//
|
|
// Components are initialized by first calling the init function.
|
|
// Then all component-like fields of fields are filled with their appropriate components.
|
|
//
|
|
// A component-like field has one of the following types:
|
|
//
|
|
// - A pointer to a struct type that implements component
|
|
// - A slice type of an interface type that implements component
|
|
//
|
|
// These fields are initialized in an undefined order during initialization.
|
|
// The init function may not rely on these existing.
|
|
// Furthermore, the init function may not cause other components to be initialized.
|
|
//
|
|
// The init function may be nil, indicating that no additional initialization is required.
|
|
func MakeComponent[C Component](context ComponentPoolContext, core Core, init func(component C)) C {
|
|
return lazy.Make(context, init)
|
|
}
|
|
|
|
// ExportComponents exports all components that are a C from the pool.
|
|
//
|
|
// All should be the function of the core that initializes all components.
|
|
// All should only make calls to [InitComponent].
|
|
func ExportComponents[C Component](pool *ComponentPool, core Core, All ComponentAllFunc) []C {
|
|
pool.init()
|
|
return lazy.ExportComponents[Component, Core, C](&pool.pool, core, All)
|
|
}
|
|
|
|
// ExportComponent exports the first component that is a C from the pool.
|
|
//
|
|
// All should be the function of the core that initializes all components.
|
|
// All should only make calls to [InitComponent].
|
|
func ExportComponent[C Component](pool *ComponentPool, core Core, All ComponentAllFunc) C {
|
|
pool.init()
|
|
return lazy.ExportComponent[Component, Core, C](&pool.pool, core, All)
|
|
}
|