Instead of using the MODS_GROUP_ASSIGN über-macro, add members for assigning, both to an individual field and for the entire group. Also add FromString and generic zero argument Call members. For the templated Assign, Call, and Toggle[1] members, use the macros to make getting pointers to data/function members easier.
1. Toggle just toggles a boolean. This would seem to have strange effects that are not consistent with the others. Calling Toggle with ModsLevel_Song and then following that by calling it with ModsLevel_Stage will cause Stage and Song groups to be opposite w.r.t. that bool. This is only used in two places. Perhaps Assign() with the value of the smallest ModsLevel used--that is the level passed to Toggle currently--toggled should be used instead.
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
#ifndef ModLevel_H
|
#ifndef ModLevel_H
|
||||||
#define ModLevel_H
|
#define ModLevel_H
|
||||||
|
|
||||||
|
#include "EnumHelper.h"
|
||||||
|
|
||||||
enum ModsLevel
|
enum ModsLevel
|
||||||
{
|
{
|
||||||
ModsLevel_Preferred, // user-chosen player options. Does not include any forced mods.
|
ModsLevel_Preferred, // user-chosen player options. Does not include any forced mods.
|
||||||
@@ -11,25 +13,22 @@ enum ModsLevel
|
|||||||
NUM_ModsLevel,
|
NUM_ModsLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MODS_GROUP_ASSIGN( modsGroup, modsLevel, assignment ) \
|
#define MODS_GROUP_ASSIGN( group, level, member, val ) \
|
||||||
{ \
|
(group).Assign( (level), &(group).GroupType::member, (val) )
|
||||||
for( int i=(ModsLevel)(modsLevel); i<NUM_ModsLevel; i++ ) \
|
#define MODS_GROUP_CALL( group, level, fun ) (group).Call( (level), &(group).GroupType::fun )
|
||||||
(modsGroup).m_[i] assignment; \
|
#define MODS_GROUP_TOGGLE( group, level, member ) (group).Call( (level), &(group).GroupType::member )
|
||||||
if( modsLevel != ModsLevel_Song ) \
|
|
||||||
(modsGroup).m_current assignment; \
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct ModsGroup
|
struct ModsGroup
|
||||||
{
|
{
|
||||||
|
typedef T GroupType;
|
||||||
T m_[NUM_ModsLevel];
|
T m_[NUM_ModsLevel];
|
||||||
RageTimer m_timer;
|
RageTimer m_timer;
|
||||||
T m_current; // approaches ModsLevel_Song
|
T m_current; // approaches ModsLevel_Song
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
MODS_GROUP_ASSIGN( *this, (ModsLevel)0, .Init() );
|
Call( ModsLevel_Preferred, &T::Init );
|
||||||
m_current.Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update( float fDelta )
|
void Update( float fDelta )
|
||||||
@@ -40,6 +39,48 @@ struct ModsGroup
|
|||||||
m_current.Approach( m_[ModsLevel_Song], fDelta );
|
m_current.Approach( m_[ModsLevel_Song], fDelta );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
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 &GetPreferred() const { return m_[ModsLevel_Preferred]; }
|
||||||
const T &GetStage() const { return m_[ModsLevel_Stage]; }
|
const T &GetStage() const { return m_[ModsLevel_Stage]; }
|
||||||
const T &GetSong() const { return m_[ModsLevel_Song]; }
|
const T &GetSong() const { return m_[ModsLevel_Song]; }
|
||||||
|
|||||||
Reference in New Issue
Block a user