diff --git a/stepmania/src/ModsGroup.h b/stepmania/src/ModsGroup.h index bd2826186f..f9162b5044 100644 --- a/stepmania/src/ModsGroup.h +++ b/stepmania/src/ModsGroup.h @@ -3,6 +3,8 @@ #ifndef ModLevel_H #define ModLevel_H +#include "EnumHelper.h" + enum ModsLevel { ModsLevel_Preferred, // user-chosen player options. Does not include any forced mods. @@ -11,25 +13,22 @@ enum ModsLevel NUM_ModsLevel, }; -#define MODS_GROUP_ASSIGN( modsGroup, modsLevel, assignment ) \ - { \ - for( int i=(ModsLevel)(modsLevel); i struct ModsGroup { + typedef T GroupType; T m_[NUM_ModsLevel]; RageTimer m_timer; T m_current; // approaches ModsLevel_Song void Init() { - MODS_GROUP_ASSIGN( *this, (ModsLevel)0, .Init() ); - m_current.Init(); + Call( ModsLevel_Preferred, &T::Init ); } void Update( float fDelta ) @@ -39,6 +38,48 @@ struct ModsGroup fDelta = m_timer.GetDeltaTime(); m_current.Approach( m_[ModsLevel_Song], fDelta ); } + + template + void Assign( ModsLevel level, U T::*member, const U &val ) + { + if( level != ModsLevel_Song ) + m_current.*member = val; + for( ; level < NUM_ModsLevel; enum_add(level, 1) ) + m_[level].*member = val; + } + + void Assign( ModsLevel level, const T &val ) + { + if( level != ModsLevel_Song ) + m_current = val; + for( ; level < NUM_ModsLevel; enum_add(level, 1) ) + m_[level] = val; + } + + void Call( ModsLevel level, void (T::*fun)() ) + { + if( level != ModsLevel_Song ) + (m_current.*fun)(); + for( ; level < NUM_ModsLevel; enum_add(level, 1) ) + (m_[level].*fun)(); + } + + void FromString( ModsLevel level, const RString &str ) + { + if( level != ModsLevel_Song ) + m_current.FromString( str ); + for( ; level < NUM_ModsLevel; enum_add(level, 1) ) + m_[level].FromString( str ); + } + + // This seems like a very strange thing to do. + void Toggle( ModsLevel level, bool T::*member ) + { + if( level != ModsLevel_Song ) + m_current.*member ^= 1; + for( ; level < NUM_ModsLevel; enum_add(level, 1) ) + m_[level].*member ^= 1; + } const T &GetPreferred() const { return m_[ModsLevel_Preferred]; } const T &GetStage() const { return m_[ModsLevel_Stage]; }