add (very) basic main menu

This commit is contained in:
2025-08-11 19:47:55 +02:00
parent 24252896c7
commit b5ff44d793
14 changed files with 246 additions and 10 deletions

View File

@@ -1,7 +1,7 @@
#pragma once
#include <memory>
#include <cassert>
#include <memory>
namespace td {
@@ -15,6 +15,11 @@ class StateMachine {
virtual TReturn Update(TArgs... args) = 0;
template <typename T, typename... Args>
T* ChangeState(Args&&... args) {
return m_StateMachine.template ChangeState<T>(std::forward<Args>(args)...);
}
protected:
TDerived& m_StateMachine;
};

View File

@@ -0,0 +1,69 @@
#pragma once
#include <cassert>
#include <vector>
#include <memory>
namespace td {
template <typename TDerived, typename TReturn, typename... TArgs>
class StateStack {
public:
class State {
public:
State(TDerived& a_StateStack) : m_StateStack(a_StateStack) {}
virtual ~State() {}
virtual TReturn Update(TArgs... args) = 0;
protected:
/**
* \brief Called when enabled (can be used to connect signals)
*/
virtual void OnEnable() {}
/**
* \brief Called when disabled (can be used to disconnect signals)
*/
virtual void OnDisable() {}
protected:
TDerived& m_StateStack;
friend class StateStack;
};
StateStack() {}
StateStack(StateStack&&) = default;
virtual ~StateStack() {}
virtual TReturn Update(TArgs... args) {
assert(!m_States.empty() && "You must push at least one state before updating !");
return m_States.back()->Update(args...);
}
void PopState() {
assert(!m_States.empty() && "You must push at least one state before poping !");
m_States.back()->OnDisable();
m_States.pop_back();
if (m_States.empty())
return;
m_States.back()->OnEnable();
}
template <typename T, typename... Args>
T* PushState(Args&&... args) {
if (!m_States.empty())
m_States.back()->OnDisable();
auto newState = std::make_unique<T>(static_cast<TDerived&>(*this), std::forward<Args>(args)...);
newState->OnEnable();
m_States.push_back(std::move(newState));
return static_cast<T*>(newState.get());
}
private:
std::vector<std::unique_ptr<State>> m_States;
};
} // namespace td

View File

@@ -0,0 +1,15 @@
#pragma once
#include <td/display/state/MainMenuState.h>
namespace td {
class CreatePartyMenu : public MainMenuState::Menu {
public:
CreatePartyMenu(MainMenuState& a_MainMenu);
~CreatePartyMenu();
virtual void Update() override;
};
} // namespace td

View File

@@ -0,0 +1,15 @@
#pragma once
#include <td/display/state/MainMenuState.h>
namespace td {
class JoinPartyMenu : public MainMenuState::Menu {
public:
JoinPartyMenu(MainMenuState& a_MainMenu);
~JoinPartyMenu();
virtual void Update() override;
};
} // namespace td

View File

@@ -0,0 +1,15 @@
#pragma once
#include <td/display/state/MainMenuState.h>
namespace td {
class MainMenu : public MainMenuState::Menu {
public:
MainMenu(MainMenuState& a_MainMenu);
~MainMenu();
virtual void Update() override;
};
} // namespace td

View File

@@ -0,0 +1,15 @@
#pragma once
#include <td/display/state/MainMenuState.h>
namespace td {
class SettingsMenu : public MainMenuState::Menu {
public:
SettingsMenu(MainMenuState& a_MainMenu);
~SettingsMenu();
virtual void Update() override;
};
} // namespace td

View File

@@ -1,15 +1,27 @@
#pragma once
#include <td/common/StateStack.h>
#include <td/display/DisplayState.h>
namespace td {
class MainMenuState : public DisplayState {
class MainMenuState;
using MainMenuStateStack = StateStack<MainMenuState, void>;
class MainMenuState : public DisplayState, public MainMenuStateStack {
public:
using Menu = MainMenuStateStack::State;
MainMenuState(Display& a_Display);
~MainMenuState();
virtual void Update(float a_Delta) override;
void RenderBackButton();
protected:
virtual void OnKeyDown(SDL_Keycode a_Key) override;
};
} // namespace td