mirror of
https://github.com/zeldaret/ss
synced 2026-08-06 09:52:57 -04:00
Implement a solution that seemingly works
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user