Files
mrgameeng/src/MrGameEng.Core/Scene.cs
T

63 lines
2.2 KiB
C#

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