Files

146 lines
2.7 KiB
Go

package shape
import (
"aego/asset"
"aego/core/errs"
"aego/core/log"
"aego/core/mathx"
"aego/engine"
"aego/render/debug"
"aego/render/view"
"aego/scene"
"aego/schema"
)
type Kind uint8
const (
None Kind = iota
Rect
Box
)
type Shape struct {
Kind Kind
Local mathx.Rect
Box mathx.AABB3
Order int64
}
type Func func(s *scene.Scene, res asset.Resolver, h scene.NodeHandle) (Shape, bool)
type OverlayCtx struct {
Scene *scene.Scene
World *engine.World
Debug *debug.Draw
View view.View
Mode3D bool
Game bool
Window mathx.Vec2
Px float32
Aspect float32
Color mathx.Color
}
type Overlay func(*OverlayCtx)
type entry struct {
owner string
t schema.TypeID
fn Func
}
type overlay struct {
owner string
fn Overlay
game bool
}
type Registry struct {
entries []entry
overlays []overlay
}
func NewRegistry() *Registry {
return &Registry{}
}
func (r *Registry) Register(owner string, t schema.TypeID, fn Func) error {
if fn == nil {
return errs.New(errs.EditorPanel, "bounds function is nil", log.F("module", owner))
}
for _, e := range r.entries {
if e.t == t {
return errs.New(errs.EditorPanel, "bounds are already registered for this component", log.F("module", owner))
}
}
r.entries = append(r.entries, entry{owner: owner, t: t, fn: fn})
return nil
}
func (r *Registry) AddOverlay(owner string, fn Overlay) {
r.AddOverlayIn(owner, fn, false)
}
func (r *Registry) AddOverlayIn(owner string, fn Overlay, game bool) {
if fn != nil {
r.overlays = append(r.overlays, overlay{owner: owner, fn: fn, game: game})
}
}
func (r *Registry) Remove(owner string) {
entries := r.entries[:0]
for _, e := range r.entries {
if e.owner != owner {
entries = append(entries, e)
}
}
r.entries = entries
overlays := r.overlays[:0]
for _, o := range r.overlays {
if o.owner != owner {
overlays = append(overlays, o)
}
}
r.overlays = overlays
}
type Set struct {
Reg *Registry
Res asset.Resolver
Hide func(*scene.Scene, scene.NodeHandle) bool
}
func (s Set) Hidden(sc *scene.Scene, h scene.NodeHandle) bool {
return s.Hide != nil && s.Hide(sc, h)
}
func (s Set) Of(sc *scene.Scene, h scene.NodeHandle) (Shape, bool) {
if s.Reg == nil || sc == nil || h.IsZero() || !sc.IsAlive(h) || s.Hidden(sc, h) {
return Shape{}, false
}
var best Shape
found := false
for _, e := range s.Reg.entries {
if _, ok := sc.GetByType(h, e.t); !ok {
continue
}
if sh, ok := e.fn(sc, s.Res, h); ok && (!found || sh.Order > best.Order) {
best, found = sh, true
}
}
return best, found
}
func (s Set) Overlays(c *OverlayCtx) {
if s.Reg == nil {
return
}
for _, o := range s.Reg.overlays {
if c.Game && !o.game {
continue
}
o.fn(c)
}
}