summaryrefslogtreecommitdiff
path: root/include/s
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2024-11-12 19:37:21 +0100
committerrobojumper <robojumper@gmail.com>2024-11-13 19:08:38 +0100
commit31ddec9bd4d3b399412fd87bd53c41feb43e1c80 (patch)
tree669a756be1b1eb0d1a98cfa90c7037a37bf2d21a /include/s
parent3a45e6536a1deec0cd5a4c108dfeb4c374ca34d9 (diff)
Implement a solution that seemingly works
Diffstat (limited to 'include/s')
-rw-r--r--include/s/README.txt4
-rw-r--r--include/s/s_FStateVirtualID.hpp35
-rw-r--r--include/s/s_State.hpp34
-rw-r--r--include/s/s_StateID.hpp2
4 files changed, 74 insertions, 1 deletions
diff --git a/include/s/README.txt b/include/s/README.txt
index 53c6cb63..22881597 100644
--- a/include/s/README.txt
+++ b/include/s/README.txt
@@ -22,3 +22,7 @@ the other abstract interface classes and provides this dtor.
We're observing a lot of word-to-bool casts in code after these
operators are invoked, and while there are ways to force the conversion,
this seems the most reasonable.
+
+## s_FStateVirtualID
+
+Implemented by SS based on NSMBW symbols. Probably missing some parts, sync with NSMBW if they get around to it.
diff --git a/include/s/s_FStateVirtualID.hpp b/include/s/s_FStateVirtualID.hpp
new file mode 100644
index 00000000..e48600a2
--- /dev/null
+++ b/include/s/s_FStateVirtualID.hpp
@@ -0,0 +1,35 @@
+#ifndef S_FSTATE_VIRTUAL_ID_H
+#define S_FSTATE_VIRTUAL_ID_H
+
+#include "s/s_FStateID.hpp"
+#include "s/s_StateID.hpp"
+
+template <typename T>
+class sFStateVirtualID_c : public sFStateID_c<T> {
+public:
+ typedef void (T::*stateFunc)();
+ sFStateVirtualID_c(
+ const sStateID_c *superState, const char *name, stateFunc initialize, stateFunc execute, stateFunc finalize
+ )
+ : sFStateID_c<T>(name, initialize, execute, finalize), mpSuperState(superState) {}
+
+ virtual unsigned int number() const {
+ return superID()->numberBase();
+ }
+
+ const sFStateVirtualID_c<T> *superID() const {
+ if (!mpSuperState->isNull()) {
+ return static_cast<const sFStateVirtualID_c<T> *>(mpSuperState)->superID();
+ }
+ return this;
+ }
+
+ unsigned int numberBase() const {
+ return sStateID_c::number();
+ }
+
+private:
+ const sStateID_c *mpSuperState;
+};
+
+#endif
diff --git a/include/s/s_State.hpp b/include/s/s_State.hpp
index 76339e3a..3a8c4ec5 100644
--- a/include/s/s_State.hpp
+++ b/include/s/s_State.hpp
@@ -3,6 +3,7 @@
#include "s/s_FStateMgr.hpp"
#include "s/s_StateMethodUsr_FI.hpp"
+#include "s/s_FStateVirtualID.hpp"
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
@@ -29,4 +30,37 @@
#define STATE_MGR(class_name) sFStateMgr_c<class_name, sStateMethodUsr_FI_c>
+// TODO this is probably not the whole solution.
+// The problems with this approach are:
+// * You can't define the same state name for multiple files in the same TU due to baseID_ symbol clash.
+// * The use of the templated baseID_ function isn't quite justified (could just use normal functions).
+
+#define STATE_VIRTUAL_FUNC_DECLARE(class, name) \
+ virtual void initializeState_##name(); \
+ virtual void executeState_##name(); \
+ virtual void finalizeState_##name(); \
+ static const sFStateVirtualID_c<class> StateID_##name; \
+ typedef sStateID_c StateID_##name##_BaseIDClass
+
+#define STATE_VIRTUAL_OVERRIDE_FUNC_DECLARE(class, super_class, name) \
+ virtual void initializeState_##name() override; \
+ virtual void executeState_##name() override; \
+ virtual void finalizeState_##name() override; \
+ static const sFStateVirtualID_c<class> StateID_##name; \
+ typedef super_class StateID_##name##_BaseIDClass
+
+#define STATE_VIRTUAL_DEFINE(class, name) \
+ template <typename T> \
+ static const sStateID_c &baseID_##name() { \
+ return T::StateID_##name; \
+ } \
+ template <> \
+ const sStateID_c &baseID_##name<sStateID_c>() { \
+ return sStateID::null; \
+ } \
+ const sFStateVirtualID_c<class> class ::StateID_##name( \
+ &baseID_##name<class ::StateID_##name##_BaseIDClass>(), #class "::StateID_" #name, \
+ &class ::initializeState_##name, &class ::executeState_##name, &class ::finalizeState_##name \
+ )
+
#endif
diff --git a/include/s/s_StateID.hpp b/include/s/s_StateID.hpp
index cff3ed9f..d385f354 100644
--- a/include/s/s_StateID.hpp
+++ b/include/s/s_StateID.hpp
@@ -44,7 +44,7 @@ protected:
namespace sStateID {
/// @ingroup state
-extern sStateID_c null; ///< A null state instance.
+extern const sStateID_c null; ///< A null state instance.
} // namespace sStateID
#endif