Files
aego/engine/world.go
T

121 lines
2.1 KiB
Go

package engine
import (
"sync/atomic"
"aego/core/clock"
"aego/core/rng"
"aego/engine/recorder"
"aego/platform/input"
)
type WorldID uint64
var worldSeq atomic.Uint64
type World struct {
id WorldID
name string
services []serviceEntry
views map[string]bool
replaying bool
Input *input.State
Time *clock.Time
Random *rng.Source
Recorder *recorder.Recorder
Break func() bool
}
func (c *Context) Input() *input.State {
if c.World != nil && c.World.Input != nil {
return c.World.Input
}
return c.Engine.Input()
}
func NewWorld(name string) *World {
return &World{id: WorldID(worldSeq.Add(1)), name: name, Time: clock.NewTime(clock.Config{})}
}
func (w *World) ID() WorldID {
return w.id
}
func (w *World) Name() string {
return w.name
}
func (w *World) set(id string, v any) {
for i := range w.services {
if w.services[i].id == id {
w.services[i].value = v
return
}
}
w.services = append(w.services, serviceEntry{id: id, value: v})
}
func (w *World) SetService(id string, v any) {
delete(w.views, id)
w.set(id, v)
}
func (w *World) SetView(id string, v any) {
w.set(id, v)
if w.views == nil {
w.views = map[string]bool{}
}
w.views[id] = true
}
func (w *World) RemoveService(id string) {
delete(w.views, id)
for i := range w.services {
if w.services[i].id == id {
w.services = append(w.services[:i], w.services[i+1:]...)
return
}
}
}
func (w *World) EachOwner(fn func(id string, v any)) {
for i := range w.services {
if e := &w.services[i]; !w.views[e.id] {
fn(e.id, e.value)
}
}
}
func (w *World) Replaying() bool {
return w != nil && w.replaying
}
func (w *World) SetReplaying(on bool) {
w.replaying = on
}
func (w *World) ServiceAny(id string) (any, bool) {
for i := range w.services {
if w.services[i].id == id {
return w.services[i].value, true
}
}
return nil, false
}
func ServiceOf[T any](w *World, id string) (T, bool) {
var zero T
if w == nil {
return zero, false
}
v, ok := w.ServiceAny(id)
if !ok {
return zero, false
}
typed, ok := v.(T)
if !ok {
return zero, false
}
return typed, true
}