using Friflo.Engine.ECS; using Friflo.Engine.ECS.Systems; namespace MrGameEng.Core; /// /// A scene owns its ECS world () and two system roots: /// for game logic and for rendering. /// Override to create entities and register systems. /// public abstract class Scene { /// The ECS world of this scene. public EntityStore Store { get; } = new(); /// Systems executed every update tick, in registration order. public SystemRoot UpdateSystems { get; } /// Systems executed every draw tick, in registration order. public SystemRoot DrawSystems { get; } /// Engine context. Valid from until . public EngineContext Context => _context ?? throw new InvalidOperationException("Scene is not loaded."); /// True while the scene is the active, loaded scene. public bool IsLoaded => _context is not null; private EngineContext? _context; /// Initializes the scene's ECS world and system roots. protected Scene() { UpdateSystems = new SystemRoot(Store, "Update"); DrawSystems = new SystemRoot(Store, "Draw"); } /// Called once when the scene becomes active: create entities, add systems. protected abstract void OnLoad(); /// Called once when the scene is replaced or the game exits. Release scene resources here. protected virtual void OnUnload() { } /// Runs the update phase. Called by . public virtual void Update(GameClock clock) => UpdateSystems.Update(new UpdateTick(clock.DeltaTime, (float)clock.TotalTime)); /// Runs the draw phase. Called by . public virtual void Draw(GameClock clock) => DrawSystems.Update(new UpdateTick(clock.DeltaTime, (float)clock.TotalTime)); internal void Load(EngineContext context) { _context = context; OnLoad(); } internal void Unload() { OnUnload(); _context = null; } }