Loading...
Searching...
No Matches
ml::SceneManager< StateEnum > Class Template Reference

State-driven scene router for Malena state machines. More...

#include <Malena/Engine/Scene/SceneManager.h>

Public Member Functions

 SceneManager ()=default
 SceneManager (const SceneManager &)=delete
 SceneManager (SceneManager &&)=delete
template<typename Owner>
void attach (Owner &owner)
 Wire SceneManager into the owner's state machine.
void back ()
 Navigate to the previously visited state.
void bind (StateEnum state, Core &scene)
 Bind an existing scene instance to a state (eager).
template<typename SceneType, typename... Args>
void bindLazy (StateEnum state, Args &&... args)
 Bind a lazily-constructed scene type to a state.
void clear ()
 Clear all bindings and history.
StateEnum current () const
 Return the currently active state.
bool has (StateEnum state) const
 Return true if a scene has been bound to state.
bool isActive (StateEnum state) const
 Return true if state is currently the active scene.
SceneManageroperator= (const SceneManager &)=delete
SceneManageroperator= (SceneManager &&)=delete
void start (StateEnum state)
 Activate the initial scene without recording a history entry.

Detailed Description

template<typename StateEnum>
class ml::SceneManager< StateEnum >

State-driven scene router for Malena state machines.

SceneManager<StateEnum> binds scenes (any Core-derived object or lazily-constructed type) to state enum values. When the owner calls setState(), SceneManager intercepts the transition via onStateEnter / onStateExit and performs the scene swap automatically — removing the outgoing scene from the owner and adding the incoming one.

Ownership

A SceneManager is a plain object you own — typically a member of the thing that drives it. That owner can be an Application or any Component, so the same router works at the top level of an app and for sub-routing inside a component. Each instance has its own bindings and history; the router lives and dies with its owner.

The owner (the type passed to attach) must expose:

  • onStateEnter(std::function<void(StateEnum)>)
  • onStateExit(std::function<void(StateEnum)>)
  • setState(StateEnum)
  • syncState(StateEnum)
  • addComponent(Core&)
  • removeComponent(Core&)

Application and Component both satisfy this contract.

Warning
The owner must outlive the SceneManager. attach() stores callbacks that reference the owner and this; destroying either while still attached is undefined behaviour. Holding the SceneManager as a member of the owner satisfies this naturally.

Design contract

  • setState() on the owner is the only navigation primitive. SceneManager reacts to it; it does not replace it.
  • back() is the one exception — it calls setState() with the previously visited state, keeping the state machine as the single source of truth.
  • Scenes bound by reference (bind) are always in memory. Scenes bound lazily (bindLazy) are constructed on first visit and destroyed on back() or when another scene replaces them.

Typical setup (Application)

// AppManifest.h
struct AppManifest : public ml::Manifest
{
enum class State { MainMenu, Game, Settings };
};
// MyApp.h
class MyApp : public ml::ApplicationWith<AppManifest>
{
using State = AppManifest::State;
using Scenes = ml::SceneManager<State>;
Scenes _scenes; // owned router
MainMenuScene _mainMenu; // eager — always in memory
SettingsScene _settings; // eager
// GameScene is lazy — only allocated when visited
public:
MyApp() : ml::ApplicationWith<AppManifest>(1280, 720, 32, "My Game") {}
void onInit() override
{
_scenes.bind (State::MainMenu, _mainMenu);
_scenes.bind (State::Settings, _settings);
_scenes.bindLazy<GameScene>(State::Game);
_scenes.attach(*this); // wire into the app's state machine
_scenes.start (State::MainMenu); // first scene, no history entry
}
void onReady() override
{
// Navigation is just setState — SceneManager handles the rest
_mainMenu.playButton().onClick([this]{ setState(State::Game); });
_mainMenu.settingsButton().onClick([this]{ setState(State::Settings); });
_settings.backButton().onClick([this]{ _scenes.back(); });
}
};
Entry point for Malena applications with a manifest.
virtual void onInit()
Called once after construction, before the first frame.
Definition Lifecycle.h:82
virtual void onReady()
Called once after onInit(), when all components are registered.
Definition Lifecycle.h:90
Base class for all Malena manifests.
Definition Manifest.h:51
State-driven scene router for Malena state machines.
Definition Component.h:22

Sub-routing inside a Component

class Workspace : public ml::Component<WorkspaceManifest>
{
using State = WorkspaceManifest::State; // { Chat, Quiz, Monitor }
using Scenes = ml::SceneManager<State>;
Scenes _scenes; // this component's own sub-router
ChatPanel _chat;
QuizPanel _quiz;
public:
Workspace()
{
_scenes.bind(State::Chat, _chat);
_scenes.bind(State::Quiz, _quiz);
_scenes.attach(*this); // attaches to THIS component
_scenes.start (State::Chat);
}
};
Primary base class for all user-facing Malena components.
Definition Component.h:292
void bind(StateEnum state, Core &scene)
Bind an existing scene instance to a state (eager).

Lazy scenes

Lazy scenes are heap-allocated on first visit and freed when they are navigated away from. This is useful for heavy scenes (lots of textures, many components) that should not occupy memory while inactive.

_scenes.bindLazy<GameScene>(State::Game); // no args
_scenes.bindLazy<GameScene>(State::Game, level); // constructor args forwarded

History and back()

Every setState() call pushes the departing state onto a history stack. back() pops it and calls setState() with that value. The initial scene set via start() is NOT pushed — it acts as the history root.

Template Parameters
StateEnumThe enum class declared in the owner's manifest's State typedef. Must match the enum used by the owner's own state machine.
See also
ApplicationWith, Component, StateManager, CoreManager, Core

Definition at line 152 of file SceneManager.h.

Constructor & Destructor Documentation

◆ SceneManager() [1/3]

template<typename StateEnum>
ml::SceneManager< StateEnum >::SceneManager ( )
default

◆ SceneManager() [2/3]

template<typename StateEnum>
ml::SceneManager< StateEnum >::SceneManager ( const SceneManager< StateEnum > & )
delete

◆ SceneManager() [3/3]

template<typename StateEnum>
ml::SceneManager< StateEnum >::SceneManager ( SceneManager< StateEnum > && )
delete

Member Function Documentation

◆ attach()

template<typename StateEnum>
template<typename Owner>
void ml::SceneManager< StateEnum >::attach ( Owner & owner)
inline

Wire SceneManager into the owner's state machine.

Registers onStateEnter and onStateExit callbacks on owner so that every future setState() call automatically triggers a scene swap. Also stores a reference to setState() so that back() can navigate without the caller holding an owner reference.

Call this once after construction (e.g. in onInit() for an app, or the constructor for a component), before start().

Template Parameters
OwnerAny class that exposes:
  • onStateEnter(std::function<void(StateEnum)>)
  • onStateExit(std::function<void(StateEnum)>)
  • setState(StateEnum)
  • syncState(StateEnum)
  • addComponent(Core&)
  • removeComponent(Core&)
Parameters
ownerThe Application or Component instance to attach to.
Warning
owner and *this must both outlive the attachment.

Definition at line 286 of file SceneManager.h.

◆ back()

template<typename StateEnum>
void ml::SceneManager< StateEnum >::back ( )
inline

Navigate to the previously visited state.

Pops the history stack and calls setState() with the recovered state. Does nothing if history is empty (i.e., already at the root).

Note
This calls setState() on the owner, which fires onStateExit and onStateEnter as normal. The scene swap happens automatically through those callbacks.

Definition at line 339 of file SceneManager.h.

◆ bind()

template<typename StateEnum>
void ml::SceneManager< StateEnum >::bind ( StateEnum state,
Core & scene )
inline

Bind an existing scene instance to a state (eager).

The scene is always in memory. SceneManager does not own it — lifetime management is the caller's responsibility (typically a member of the owning Application/Component).

Parameters
stateThe state that activates this scene.
sceneReference to a Core-derived scene object.

Definition at line 216 of file SceneManager.h.

◆ bindLazy()

template<typename StateEnum>
template<typename SceneType, typename... Args>
void ml::SceneManager< StateEnum >::bindLazy ( StateEnum state,
Args &&... args )
inline

Bind a lazily-constructed scene type to a state.

The scene is heap-allocated on first visit and destroyed when navigated away from. Constructor arguments are forwarded at construction time.

Template Parameters
SceneTypeA Core-derived type to construct on demand.
ArgsConstructor argument types (deduced).
Parameters
stateThe state that activates this scene.
argsArguments forwarded to SceneType's constructor.
_scenes.bindLazy<GameScene>(State::Game);
_scenes.bindLazy<LevelScene>(State::Level, levelIndex);

Definition at line 240 of file SceneManager.h.

◆ clear()

template<typename StateEnum>
void ml::SceneManager< StateEnum >::clear ( )
inline

Clear all bindings and history.

Call before rebuilding the scene set. Does NOT deactivate the current scene — call deactivate(current()) first if needed.

Definition at line 380 of file SceneManager.h.

◆ current()

template<typename StateEnum>
StateEnum ml::SceneManager< StateEnum >::current ( ) const
inline

Return the currently active state.

Returns
The state whose scene is currently shown.

Definition at line 360 of file SceneManager.h.

◆ has()

template<typename StateEnum>
bool ml::SceneManager< StateEnum >::has ( StateEnum state) const
inline

Return true if a scene has been bound to state.

Parameters
stateState to check.

Definition at line 372 of file SceneManager.h.

◆ isActive()

template<typename StateEnum>
bool ml::SceneManager< StateEnum >::isActive ( StateEnum state) const
inline

Return true if state is currently the active scene.

Parameters
stateState to check.

Definition at line 366 of file SceneManager.h.

◆ operator=() [1/2]

template<typename StateEnum>
SceneManager & ml::SceneManager< StateEnum >::operator= ( const SceneManager< StateEnum > & )
delete

◆ operator=() [2/2]

template<typename StateEnum>
SceneManager & ml::SceneManager< StateEnum >::operator= ( SceneManager< StateEnum > && )
delete

◆ start()

template<typename StateEnum>
void ml::SceneManager< StateEnum >::start ( StateEnum state)
inline

Activate the initial scene without recording a history entry.

Call after attach() and all bind() / bindLazy() calls. The initial scene is treated as the history root — back() cannot navigate past it.

Parameters
stateThe state whose scene should be shown first.

Definition at line 319 of file SceneManager.h.


The documentation for this class was generated from the following file: