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;
}
}