A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
StateManager.hh
1#pragma once
2
3#include "game/field/obj/ObjectBase.hh"
4
5#include <type_traits>
6
7namespace Field {
8
10 u16 id;
11 void (*onEnter)(void *);
12 void (*onCalc)(void *);
13};
14
15template <typename T, void (T::*Enter)(), void (T::*Calc)()>
16constexpr StateManagerEntry StateEntry(u16 id) {
17 auto enter = [](void *obj) { (reinterpret_cast<T *>(obj)->*Enter)(); };
18 auto calc = [](void *obj) { (reinterpret_cast<T *>(obj)->*Calc)(); };
19 return {id, enter, calc};
20}
21
30protected:
31 StateManager(void *obj, const std::span<const StateManagerEntry> &entries)
32 : m_currentStateId(0), m_nextStateId(-1), m_currentFrame(0), m_entries(entries),
33 m_obj(obj) {
34 m_entryIds = std::span(new u16[m_entries.size()], m_entries.size());
35
36 // The base game initializes all entries to 0xffff, possibly to avoid an uninitialized value
37 for (auto &id : m_entryIds) {
38 id = 0xffff;
39 }
40
41 for (size_t i = 0; i < m_entryIds.size(); ++i) {
42 m_entryIds[m_entries[i].id] = i;
43 }
44 }
45
46 virtual ~StateManager() {
47 delete[] m_entryIds.data();
48 }
49
50 void calc() {
51 if (m_nextStateId >= 0) {
52 m_currentStateId = m_nextStateId;
53 m_nextStateId = -1;
54 m_currentFrame = 0;
55
56 auto enterFunc = m_entries[m_entryIds[m_currentStateId]].onEnter;
57 enterFunc(m_obj);
58 } else {
59 ++m_currentFrame;
60 }
61
62 auto calcFunc = m_entries[m_entryIds[m_currentStateId]].onCalc;
63 calcFunc(m_obj);
64 }
65
66 u16 m_currentStateId;
67 s32 m_nextStateId;
68 u32 m_currentFrame;
69 std::span<u16> m_entryIds;
70 std::span<const StateManagerEntry> m_entries;
71 void *m_obj;
72};
73
74} // namespace Field
Base class that represents different "states" for an object.
Pertains to collision.