Implement a solution that seemingly works

This commit is contained in:
robojumper
2024-11-12 19:37:21 +01:00
parent 3a45e6536a
commit 31ddec9bd4
9 changed files with 128 additions and 92 deletions
+2 -56
View File
@@ -2,61 +2,7 @@
#define D_A_NPC_H
#include "d/a/obj/d_a_obj_base.h"
#include "s/s_FStateID.hpp"
#include "s/s_FStateMgr.hpp"
#include "s/s_StateID.hpp"
#include "s/s_StateMethodUsr_FI.hpp"
// Virtual states!
template <typename T>
class sVFStateID_c : public sFStateID_c<T> {
public:
typedef void (T::*stateFunc)();
sVFStateID_c(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 getRootState()->numberBase();
}
const sVFStateID_c<T> *getRootState() const {
if (!mpSuperState->isNull()) {
return static_cast<const sVFStateID_c<T> *>(mpSuperState)->getRootState();
}
return this;
}
unsigned int numberBase() const {
return sStateID_c::number();
}
private:
sStateID_c *mpSuperState;
};
#define STATE_VIRTUAL_FUNC_DECLARE(class, name) \
virtual void initializeState_##name(); \
virtual void executeState_##name(); \
virtual void finalizeState_##name(); \
static sVFStateID_c<class> StateID_##name
#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 sVFStateID_c<class> StateID_##name; \
#define STATE_VIRTUAL_DEFINE(class, name) \
sStateID_c *getDefaultSuperState_##class##name() { \
return &sStateID::null; \
} \
sVFStateID_c<class> class ::StateID_##name( \
getDefaultSuperState_##class##name(), #class "::StateID_" #name, &class ::initializeState_##name, \
&class ::executeState_##name, &class ::finalizeState_##name \
)
#define STATE_VIRTUAL_MGR_DECLARE(class_name) sFStateMgr_c<class_name, sStateMethodUsr_FI_c> mStateMgr;
#include "s/s_State.hpp"
// This is the NPC base. Most npcs actually use dAcOrdinaryNpc, but this just is a simpler one?
@@ -70,7 +16,7 @@ public:
STATE_VIRTUAL_FUNC_DECLARE(dAcNpc_c, Wait);
STATE_VIRTUAL_FUNC_DECLARE(dAcNpc_c, Demo);
STATE_VIRTUAL_MGR_DECLARE(dAcNpc_c);
STATE_MGR_DECLARE(dAcNpc_c);
};
#endif
+9
View File
@@ -2,10 +2,19 @@
#define D_A_ORDINARY_NPC_H
#include "d/a/npc/d_a_npc.h"
#include "s/s_State.hpp"
class dAcOrdinaryNpc_c : public dAcNpc_c {
public:
STATE_VIRTUAL_OVERRIDE_FUNC_DECLARE(dAcOrdinaryNpc_c, dAcNpc_c, Wait);
STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Pain);
STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Surprised);
STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Withstand);
STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Walk);
STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, LookAwaySt);
STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, LookAway);
STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Turn);
STATE_FUNC_DECLARE(dAcOrdinaryNpc_c, PreWalkTurn);
};
#endif
+4
View File
@@ -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.
+35
View File
@@ -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
+34
View File
@@ -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
+1 -1
View File
@@ -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