diff --git a/stepmania/src/Foreach.h b/stepmania/src/Foreach.h index 40970e7fdc..fd6bdcc89e 100644 --- a/stepmania/src/Foreach.h +++ b/stepmania/src/Foreach.h @@ -11,4 +11,7 @@ for( deque::iterator var = (vect).begin(); var != (vect).end(); ++var #define FOREACHD_CONST( elemType, vect, var ) \ for( deque::const_iterator var = (vect).begin(); var != (vect).end(); ++var ) +#define FOREACHMM( keyType, valType, vect, var ) \ +for( multimap::iterator var = (vect).begin(); var != (vect).end(); ++var ) + #endif diff --git a/stepmania/src/HighScore.cpp b/stepmania/src/HighScore.cpp index 8e6272873c..fbfd9612af 100644 --- a/stepmania/src/HighScore.cpp +++ b/stepmania/src/HighScore.cpp @@ -4,6 +4,7 @@ #include "GameConstantsAndTypes.h" #include "ThemeManager.h" #include "XmlFile.h" +#include "Foreach.h" #define EMPTY_NAME THEME->GetMetric ("HighScore","EmptyName") @@ -163,23 +164,21 @@ XNode* HighScoreList::CreateNode() const return pNode; } -void HighScoreList::LoadFromNode( const XNode* pNode ) +void HighScoreList::LoadFromNode( const XNode* pHighScoreList ) { Init(); - ASSERT( pNode->name == "HighScoreList" ); - for( vector::const_iterator child = pNode->childs.begin(); - child != pNode->childs.end(); - child++) + ASSERT( pHighScoreList->name == "HighScoreList" ); + FOREACH_CONST_Child( pHighScoreList, p ) { - if( (*child)->name == "NumTimesPlayed" ) + if( p->name == "NumTimesPlayed" ) { - (*child)->GetValue( iNumTimesPlayed ); + p->GetValue( iNumTimesPlayed ); } - else if( (*child)->name == "HighScore" ) + else if( p->name == "HighScore" ) { vHighScores.resize( vHighScores.size()+1 ); - vHighScores.back().LoadFromNode( (*child) ); + vHighScores.back().LoadFromNode( p ); // ignore all high scores that are 0 if( vHighScores.back().iScore == 0 ) diff --git a/stepmania/src/Profile.cpp b/stepmania/src/Profile.cpp index e6a70d0174..2b8d2afe74 100644 --- a/stepmania/src/Profile.cpp +++ b/stepmania/src/Profile.cpp @@ -45,12 +45,6 @@ const CString COMMON_XSL = "Common.xsl"; #pragma warning (disable : 4706) // assignment within conditional expression #endif -#define FOREACH_Node( Node, Var ) \ - vector::const_iterator Var##Iter; \ - const XNode *Var = NULL; \ - for( Var##Iter = Node->childs.begin(); \ - (Var##Iter != Node->childs.end() && (Var = *Var##Iter) ), Var##Iter != Node->childs.end(); \ - ++Var##Iter ) void Profile::InitEditableData() { @@ -953,7 +947,7 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode ) const XNode* pDefaultModifiers = pNode->GetChild("DefaultModifiers"); if( pDefaultModifiers ) { - FOREACH_Node( pDefaultModifiers, game_type ) + FOREACH_CONST_Child( pDefaultModifiers, game_type ) { m_sDefaultModifiers[game_type->name] = game_type->value; } @@ -964,7 +958,7 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode ) const XNode* pUnlockedSongs = pNode->GetChild("UnlockedSongs"); if( pUnlockedSongs ) { - FOREACH_Node( pUnlockedSongs, song ) + FOREACH_CONST_Child( pUnlockedSongs, song ) { int iUnlock; if( sscanf(song->name.c_str(),"Unlock%d",&iUnlock) == 1 ) @@ -984,7 +978,7 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode ) const XNode* pNumSongsPlayedByStyle = pNode->GetChild("NumSongsPlayedByStyle"); if( pNumSongsPlayedByStyle ) { - FOREACH_Node( pNumSongsPlayedByStyle, style ) + FOREACH_CONST_Child( pNumSongsPlayedByStyle, style ) { if( style->name != "Style" ) continue; @@ -1099,33 +1093,33 @@ XNode* Profile::SaveSongScoresCreateNode() const return pNode; } -void Profile::LoadSongScoresFromNode( const XNode* pNode ) +void Profile::LoadSongScoresFromNode( const XNode* pSongScores ) { CHECKPOINT; - ASSERT( pNode->name == "SongScores" ); + ASSERT( pSongScores->name == "SongScores" ); - FOREACH_CONST( XNode*, pNode->childs, song ) + FOREACH_CONST_Child( pSongScores, pSong ) { - if( (*song)->name != "Song" ) + if( pSong->name != "Song" ) continue; SongID songID; - songID.LoadFromNode( *song ); + songID.LoadFromNode( pSong ); if( !songID.IsValid() ) WARN_AND_CONTINUE; - FOREACH_CONST( XNode*, (*song)->childs, steps ) + FOREACH_CONST_Child( pSong, pSteps ) { - if( (*steps)->name != "Steps" ) + if( pSteps->name != "Steps" ) continue; StepsID stepsID; - stepsID.LoadFromNode( *steps ); + stepsID.LoadFromNode( pSteps ); if( !stepsID.IsValid() ) WARN_AND_CONTINUE; - XNode *pHighScoreListNode = (*steps)->GetChild("HighScoreList"); + const XNode *pHighScoreListNode = pSteps->GetChild("HighScoreList"); if( pHighScoreListNode == NULL ) WARN_AND_CONTINUE; @@ -1182,33 +1176,33 @@ XNode* Profile::SaveCourseScoresCreateNode() const return pNode; } -void Profile::LoadCourseScoresFromNode( const XNode* pNode ) +void Profile::LoadCourseScoresFromNode( const XNode* pCourseScores ) { CHECKPOINT; - ASSERT( pNode->name == "CourseScores" ); + ASSERT( pCourseScores->name == "CourseScores" ); - FOREACH_CONST( XNode*, pNode->childs, course ) + FOREACH_CONST_Child( pCourseScores, pCourse ) { - if( (*course)->name != "Course" ) + if( pCourse->name != "Course" ) continue; CourseID courseID; - courseID.LoadFromNode( *course ); + courseID.LoadFromNode( pCourse ); if( !courseID.IsValid() ) WARN_AND_CONTINUE; - FOREACH_CONST( XNode*, (*course)->childs, trail ) + FOREACH_CONST_Child( pCourse, pTrail ) { - if( (*trail)->name != "Trail" ) + if( pTrail->name != "Trail" ) continue; TrailID trailID; - trailID.LoadFromNode( *trail ); + trailID.LoadFromNode( pTrail ); if( !trailID.IsValid() ) WARN_AND_CONTINUE; - XNode *pHighScoreListNode = (*trail)->GetChild("HighScoreList"); + const XNode *pHighScoreListNode = pTrail->GetChild("HighScoreList"); if( pHighScoreListNode == NULL ) WARN_AND_CONTINUE; @@ -1255,40 +1249,36 @@ XNode* Profile::SaveCategoryScoresCreateNode() const return pNode; } -void Profile::LoadCategoryScoresFromNode( const XNode* pNode ) +void Profile::LoadCategoryScoresFromNode( const XNode* pCategoryScores ) { CHECKPOINT; - ASSERT( pNode->name == "CategoryScores" ); + ASSERT( pCategoryScores->name == "CategoryScores" ); - for( vector::const_iterator stepsType = pNode->childs.begin(); - stepsType != pNode->childs.end(); - stepsType++ ) + FOREACH_CONST_Child( pCategoryScores, pStepsType ) { - if( (*stepsType)->name != "StepsType" ) + if( pStepsType->name != "StepsType" ) continue; CString str; - if( !(*stepsType)->GetAttrValue( "Type", str ) ) + if( !pStepsType->GetAttrValue( "Type", str ) ) WARN_AND_CONTINUE; StepsType st = GameManager::StringToStepsType( str ); if( st == STEPS_TYPE_INVALID ) WARN_AND_CONTINUE_M( str ); - for( vector::iterator radarCategory = (*stepsType)->childs.begin(); - radarCategory != (*stepsType)->childs.end(); - radarCategory++ ) + FOREACH_CONST_Child( pStepsType, pRadarCategory ) { - if( (*radarCategory)->name != "RankingCategory" ) + if( pRadarCategory->name != "RankingCategory" ) continue; - if( !(*radarCategory)->GetAttrValue( "Type", str ) ) + if( !pRadarCategory->GetAttrValue( "Type", str ) ) WARN_AND_CONTINUE; RankingCategory rc = StringToRankingCategory( str ); if( rc == RANKING_INVALID ) WARN_AND_CONTINUE_M( str ); - XNode *pHighScoreListNode = (*radarCategory)->GetChild("HighScoreList"); + const XNode *pHighScoreListNode = pRadarCategory->GetChild("HighScoreList"); if( pHighScoreListNode == NULL ) WARN_AND_CONTINUE; @@ -1319,18 +1309,18 @@ void Profile::AddScreenshot( const Screenshot &screenshot ) m_vScreenshots.push_back( screenshot ); } -void Profile::LoadScreenshotDataFromNode( const XNode* pNode ) +void Profile::LoadScreenshotDataFromNode( const XNode* pScreenshotData ) { CHECKPOINT; - ASSERT( pNode->name == "ScreenshotData" ); - FOREACH_CONST( XNode*, pNode->childs, screenshot ) + ASSERT( pScreenshotData->name == "ScreenshotData" ); + FOREACH_CONST_Child( pScreenshotData, pScreenshot ) { - if( (*screenshot)->name != "Screenshot" ) - WARN_AND_CONTINUE_M( (*screenshot)->name ); + if( pScreenshot->name != "Screenshot" ) + WARN_AND_CONTINUE_M( pScreenshot->name ); Screenshot ss; - ss.LoadFromNode( *screenshot ); + ss.LoadFromNode( pScreenshot ); m_vScreenshots.push_back( ss ); } @@ -1354,18 +1344,18 @@ XNode* Profile::SaveScreenshotDataCreateNode() const return pNode; } -void Profile::LoadCalorieDataFromNode( const XNode* pNode ) +void Profile::LoadCalorieDataFromNode( const XNode* pCalorieData ) { CHECKPOINT; - ASSERT( pNode->name == "CalorieData" ); - FOREACH_CONST( XNode*, pNode->childs, pCaloriesBurned ) + ASSERT( pCalorieData->name == "CalorieData" ); + FOREACH_CONST_Child( pCalorieData, pCaloriesBurned ) { - if( (*pCaloriesBurned)->name != "CaloriesBurned" ) - WARN_AND_CONTINUE_M( (*pCaloriesBurned)->name ); + if( pCaloriesBurned->name != "CaloriesBurned" ) + WARN_AND_CONTINUE_M( pCaloriesBurned->name ); CString sDate; - if( !(*pCaloriesBurned)->GetAttrValue("Date",sDate) ) + if( !pCaloriesBurned->GetAttrValue("Date",sDate) ) WARN_AND_CONTINUE; DateTime date; if( !date.FromString(sDate) ) @@ -1373,7 +1363,7 @@ void Profile::LoadCalorieDataFromNode( const XNode* pNode ) float fCaloriesBurned = 0; - (*pCaloriesBurned)->GetValue(fCaloriesBurned); + pCaloriesBurned->GetValue(fCaloriesBurned); m_mapDayToCaloriesBurned[date] = fCaloriesBurned; } @@ -1437,24 +1427,24 @@ void Profile::HighScoreForASongAndSteps::LoadFromNode( const XNode* pNode ) hs.LoadFromNode( p ); } -void Profile::LoadRecentSongScoresFromNode( const XNode* pNode ) +void Profile::LoadRecentSongScoresFromNode( const XNode* pRecentSongScores ) { CHECKPOINT; - ASSERT( pNode->name == "RecentSongScores" ); - for( vector::const_iterator p = pNode->childs.begin(); - p != pNode->childs.end(); - p++ ) + ASSERT( pRecentSongScores->name == "RecentSongScores" ); + FOREACH_CONST_Child( pRecentSongScores, p ) { - if( (*p)->name == "HighScoreForASongAndSteps" ) + if( p->name == "HighScoreForASongAndSteps" ) { HighScoreForASongAndSteps h; - h.LoadFromNode( *p ); + h.LoadFromNode( p ); m_vRecentStepsScores.push_back( h ); } else - WARN_AND_CONTINUE_M( (*p)->name ); + { + WARN_AND_CONTINUE_M( p->name ); + } } } @@ -1514,24 +1504,24 @@ void Profile::HighScoreForACourseAndTrail::LoadFromNode( const XNode* pNode ) hs.LoadFromNode( p ); } -void Profile::LoadRecentCourseScoresFromNode( const XNode* pNode ) +void Profile::LoadRecentCourseScoresFromNode( const XNode* pRecentCourseScores ) { CHECKPOINT; - ASSERT( pNode->name == "RecentCourseScores" ); - for( vector::const_iterator p = pNode->childs.begin(); - p != pNode->childs.end(); - p++ ) + ASSERT( pRecentCourseScores->name == "RecentCourseScores" ); + FOREACH_CONST_Child( pRecentCourseScores, p ) { - if( (*p)->name == "HighScoreForACourseAndTrail" ) + if( p->name == "HighScoreForACourseAndTrail" ) { HighScoreForACourseAndTrail h; - h.LoadFromNode( *p ); + h.LoadFromNode( p ); m_vRecentCourseScores.push_back( h ); } else - WARN_AND_CONTINUE_M( (*p)->name ); + { + WARN_AND_CONTINUE_M( p->name ); + } } } diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 54e5900cbe..7fa74cb1f1 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -1,5 +1,5 @@ # Microsoft Developer Studio Project File - Name="StepMania" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# Microsoft Developer Studio Generated Build File, Format Version 60000 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Application" 0x0101 @@ -55,14 +55,14 @@ BSC32=bscmake.exe LINK32=link.exe # ADD BASE LINK32 $(intdir)\verstub.obj kernel32.lib shell32.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /pdb:"../debug6/StepMania-debug.pdb" /map /debug /machine:I386 /nodefaultlib:"libcmtd.lib" /out:"../StepMania-debug.exe" # SUBTRACT BASE LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib -# ADD LINK32 $(intdir)\verstub.obj kernel32.lib gdi32.lib shell32.lib user32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../Program/StepMania-debug.exe" +# ADD LINK32 $(intdir)\verstub.obj kernel32.lib gdi32.lib shell32.lib user32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../itg/itg/Program/StepMania-debug.exe" # SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib # Begin Special Build Tool IntDir=.\../Debug6 -TargetDir=\temp\stepmania\Program +TargetDir=\stepmania\itg\itg\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -96,10 +96,10 @@ LINK32=link.exe # SUBTRACT LINK32 /verbose /pdb:none /debug # Begin Special Build Tool IntDir=.\../Release6 -TargetDir=\temp\stepmania\Program +TargetDir=\stepmania\stepmania\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool diff --git a/stepmania/src/XmlFile.cpp b/stepmania/src/XmlFile.cpp index 04d766e4f7..dbf84c5f73 100644 --- a/stepmania/src/XmlFile.cpp +++ b/stepmania/src/XmlFile.cpp @@ -7,6 +7,7 @@ #include "RageLog.h" #include "RageUtil.h" #include "DateTime.h" +#include "Foreach.h" static const char chXMLTagOpen = '<'; @@ -154,16 +155,12 @@ XNode::~XNode() void XNode::Close() { - for( unsigned i = 0 ; i < childs.size(); i ++) - { - SAFE_DELETE( childs[i] ); - } + FOREACH_Child( this, p ) + SAFE_DELETE( p ); childs.clear(); - for( unsigned i = 0 ; i < attrs.size(); i ++) - { - SAFE_DELETE( attrs[i] ); - } + FOREACH_Attr( this, p2 ) + SAFE_DELETE( p2 ); attrs.clear(); } @@ -179,7 +176,7 @@ void XNode::Close() // Coder Date Desc // bro 2002-10-29 //======================================================== -char* XNode::LoadAttributes( const char* pszAttrs , PARSEINFO *pi /*= &piDefault*/) +char* XNode::LoadAttributes( const char* pszAttrs, PARSEINFO *pi /*= &piDefault*/) { char* xml = (char*)pszAttrs; @@ -215,7 +212,7 @@ char* XNode::LoadAttributes( const char* pszAttrs , PARSEINFO *pi /*= &piDefault SetString( xml, pEnd, &attr->name ); // add new attribute - attrs.push_back( attr ); + attrs.insert( pair(attr->name, attr) ); xml = pEnd; // XML Attr Value @@ -373,7 +370,7 @@ char* XNode::Load( const char* pszXml, PARSEINFO *pi /*= &piDefault*/ ) xml = node->Load( xml,pi ); if( !node->name.empty() ) { - childs.push_back( node ); + childs.insert( pair(node->name, node) ); } else { @@ -513,8 +510,8 @@ bool XNode::GetXML( RageFileBasic &f, DISP_OPT *opt /*= &optDefault*/ ) if( !attrs.empty() ) if( f.Write(" ") == -1 ) return false; - for( unsigned i = 0 ; i < attrs.size(); i++ ) - if( !attrs[i]->GetXML(f, opt) ) + FOREACH_Attr( this, p ) + if( !p->GetXML(f, opt) ) return false; if( childs.empty() && value.empty() ) @@ -534,8 +531,8 @@ bool XNode::GetXML( RageFileBasic &f, DISP_OPT *opt /*= &optDefault*/ ) opt->tab_base++; } - for( unsigned i = 0 ; i < childs.size(); i++ ) - if( !childs[i]->GetXML( f, opt ) ) + FOREACH_Child( this, p ) + if( !p->GetXML( f, opt ) ) return false; // Text Value @@ -624,56 +621,20 @@ void XNode::SetValue(const DateTime &v) { value = v.GetString(); } //======================================================== const XAttr *XNode::GetAttr( const char* attrname ) const { - for( unsigned i = 0 ; i < attrs.size(); i++ ) - { - XAttr *attr = attrs[i]; - if( attr ) - { - if( attr->name == attrname ) - return attr; - } - } + multimap::const_iterator it = attrs.find( name ); + if( it != attrs.end() ) + return it->second; return NULL; } XAttr *XNode::GetAttr( const char* attrname ) { - for( unsigned i = 0 ; i < attrs.size(); i++ ) - { - XAttr *attr = attrs[i]; - if( attr ) - { - if( attr->name == attrname ) - return attr; - } - } + multimap::iterator it = attrs.find( name ); + if( it != attrs.end() ) + return it->second; return NULL; } -//======================================================== -// Name : GetAttrs -// Desc : find attributes with attribute name, return its list -// Param : -// Return : -//-------------------------------------------------------- -// Coder Date Desc -// bro 2002-10-29 -//======================================================== -XAttrs XNode::GetAttrs( const char* name ) -{ - XAttrs attrs; - for( unsigned i = 0 ; i < attrs.size(); i++ ) - { - XAttr *attr = attrs[i]; - if( attr ) - { - if( attr->name == name ) - attrs.push_back( attr ); - } - } - return attrs; -} - //======================================================== // Name : GetAttrValue // Desc : get attribute with attribute name, return its value @@ -689,50 +650,6 @@ const char* XNode::GetAttrValue( const char* attrname ) return attr ? (const char*)attr->value : NULL; } -XNodes XNode::GetChilds() -{ - return childs; -} - -//======================================================== -// Name : GetChilds -// Desc : Find childs with name and return childs list -// Param : -// Return : -//-------------------------------------------------------- -// Coder Date Desc -// bro 2002-10-29 -//======================================================== -XNodes XNode::GetChilds( const char* name ) -{ - XNodes nodes; - for( unsigned i = 0 ; i < childs.size(); i++ ) - { - XNode *node = childs[i]; - if( node ) - { - if( node->name == name ) - nodes.push_back( node ); - } - } - return nodes; -} - -//======================================================== -// Name : GetChild -// Desc : get child node with index -// Param : -// Return : NULL return if no child. -//-------------------------------------------------------- -// Coder Date Desc -// bro 2002-10-29 -//======================================================== -XNode *XNode::GetChild( int i ) -{ - if( i >= 0 && i < (int)childs.size() ) - return childs[i]; - return NULL; -} //======================================================== // Name : GetChildCount @@ -759,29 +676,17 @@ int XNode::GetChildCount() //======================================================== XNode *XNode::GetChild( const char* name ) { - for( unsigned i = 0 ; i < childs.size(); i++ ) - { - XNode *node = childs[i]; - if( node ) - { - if( node->name == name ) - return node; - } - } + multimap::iterator it = childs.find( name ); + if( it != childs.end() ) + return it->second; return NULL; } const XNode *XNode::GetChild( const char* name ) const { - for( unsigned i = 0 ; i < childs.size(); i++ ) - { - XNode *node = childs[i]; - if( node ) - { - if( node->name == name ) - return node; - } - } + multimap::const_iterator it = childs.find( name ); + if( it != childs.end() ) + return it->second; return NULL; } @@ -813,26 +718,6 @@ const char* XNode::GetChildAttrValue( const char* name, const char* attrname ) } -//======================================================== -// Name : GetChildIterator -// Desc : get child nodes iterator -// Param : -// Return : NULL return if no childs. -//-------------------------------------------------------- -// Coder Date Desc -// bro 2002-10-29 -//======================================================== -XNodes::iterator XNode::GetChildIterator( XNode *node ) -{ - XNodes::iterator it = childs.begin(); - for( ; it != childs.end() ; ++(it) ) - { - if( *it == node ) - return it; - } - return childs.end(); -} - //======================================================== // Name : AppendChild // Desc : add node @@ -859,7 +744,7 @@ XNode *XNode::AppendChild( const char* name, const DateTime &value ) { XNode *p //======================================================== XNode *XNode::AppendChild( XNode *node ) { - childs.push_back( node ); + childs.insert( pair(node->name,node) ); return node; } @@ -874,51 +759,18 @@ XNode *XNode::AppendChild( XNode *node ) //======================================================== bool XNode::RemoveChild( XNode *node ) { - XNodes::iterator it = GetChildIterator( node ); - if( it != childs.end() ) + FOREACHMM( CString, XNode*, childs, p ) { - delete *it; - childs.erase( it ); - return true; + if( p->second == node ) + { + SAFE_DELETE( p->second ); + childs.erase( p ); + return true; + } } return false; } -//======================================================== -// Name : GetAttr -// Desc : get attribute with index in attribute list -// Param : -// Return : -//-------------------------------------------------------- -// Coder Date Desc -// bro 2002-10-29 -//======================================================== -XAttr *XNode::GetAttr( int i ) -{ - if( i >= 0 && i < (int)attrs.size() ) - return attrs[i]; - return NULL; -} - -//======================================================== -// Name : GetAttrIterator -// Desc : get attribute iterator -// Param : -// Return : XAttrs::iterator -//-------------------------------------------------------- -// Coder Date Desc -// bro 2002-10-29 -//======================================================== -XAttrs::iterator XNode::GetAttrIterator( XAttr *attr ) -{ - XAttrs::iterator it = attrs.begin(); - for( ; it != attrs.end() ; ++(it) ) - { - if( *it == attr ) - return it; - } - return attrs.end(); -} //======================================================== // Name : AppendAttr @@ -931,7 +783,7 @@ XAttrs::iterator XNode::GetAttrIterator( XAttr *attr ) //======================================================== XAttr *XNode::AppendAttr( XAttr *attr ) { - attrs.push_back( attr ); + attrs.insert( pair(attr->name,attr) ); return attr; } @@ -946,12 +798,14 @@ XAttr *XNode::AppendAttr( XAttr *attr ) //======================================================== bool XNode::RemoveAttr( XAttr *attr ) { - XAttrs::iterator it = GetAttrIterator( attr ); - if( it != attrs.end() ) + FOREACHMM( CString, XAttr*, attrs, p ) { - delete *it; - attrs.erase( it ); - return true; + if( p->second == attr ) + { + SAFE_DELETE( p->second ); + attrs.erase( p ); + return true; + } } return false; } @@ -1008,45 +862,6 @@ XAttr *XNode::AppendAttr( const char* name, float value ){ return AppendAttr(nam XAttr *XNode::AppendAttr( const char* name, int value ) { return AppendAttr(name,ssprintf("%d",value)); } XAttr *XNode::AppendAttr( const char* name, unsigned value ) { return AppendAttr(name,ssprintf("%u",value)); } -//======================================================== -// Name : DetachChild -// Desc : no delete object, just detach in list -// Param : -// Return : -//-------------------------------------------------------- -// Coder Date Desc -// bro 2002-10-29 -//======================================================== -XNode *XNode::DetachChild( XNode *node ) -{ - XNodes::iterator it = GetChildIterator( node ); - if( it != childs.end() ) - { - childs.erase( it ); - return node; - } - return NULL; -} - -//======================================================== -// Name : DetachAttr -// Desc : no delete object, just detach in list -// Param : -// Return : -//-------------------------------------------------------- -// Coder Date Desc -// bro 2002-10-29 -//======================================================== -XAttr *XNode::DetachAttr( XAttr *attr ) -{ - XAttrs::iterator it = GetAttrIterator( attr ); - if( it != attrs.end() ) - { - attrs.erase( it ); - return attr; - } - return NULL; -} XENTITYS::XENTITYS( XENTITY *entities, int count ) { diff --git a/stepmania/src/XmlFile.h b/stepmania/src/XmlFile.h index 2d058b392c..827e6114ec 100644 --- a/stepmania/src/XmlFile.h +++ b/stepmania/src/XmlFile.h @@ -19,14 +19,43 @@ // fix escape functions ////////////////////////////////////////////////////////////////////// -#include +#include struct DateTime; class RageFileBasic; struct XAttr; -typedef vector XAttrs; +typedef multimap XAttrs; struct XNode; -typedef vector XNodes; +typedef multimap XNodes; + +#define FOREACH_Attr( pNode, Var ) \ + XAttrs::iterator Var##Iter; \ + XAttr *Var = NULL; \ + for( Var##Iter = pNode->attrs.begin(); \ + (Var##Iter != pNode->attrs.end() && (Var = Var##Iter->second) ), Var##Iter != pNode->attrs.end(); \ + ++Var##Iter ) + +#define FOREACH_CONST_Attr( pNode, Var ) \ + XAttrs::const_iterator Var##Iter; \ + const XAttr *Var = NULL; \ + for( Var##Iter = pNode->attrs.begin(); \ + (Var##Iter != pNode->attrs.end() && (Var = Var##Iter->second) ), Var##Iter != pNode->attrs.end(); \ + ++Var##Iter ) + +#define FOREACH_Child( pNode, Var ) \ + XNodes::iterator Var##Iter; \ + XNode *Var = NULL; \ + for( Var##Iter = pNode->childs.begin(); \ + (Var##Iter != pNode->childs.end() && (Var = Var##Iter->second) ), Var##Iter != pNode->childs.end(); \ + ++Var##Iter ) + +#define FOREACH_CONST_Child( pNode, Var ) \ + XNodes::const_iterator Var##Iter; \ + const XNode *Var = NULL; \ + for( Var##Iter = pNode->childs.begin(); \ + (Var##Iter != pNode->childs.end() && (Var = Var##Iter->second) ), Var##Iter != pNode->childs.end(); \ + ++Var##Iter ) + // Entity Encode/Decode Support struct XENTITY @@ -106,7 +135,7 @@ extern DISP_OPT optDefault; // XAttr : Attribute Implementation struct XAttr { - CString name; + CString name; // a duplicate of the name in the parent's map CString value; void GetValue(CString &out) const; void GetValue(int &out) const; @@ -121,8 +150,7 @@ struct XAttr // XMLNode structure struct XNode { - // name and value - CString name; + CString name; // a duplicate of the name in the parent's map CString value; void GetValue(CString &out) const; void GetValue(int &out) const; @@ -159,7 +187,6 @@ struct XNode bool GetAttrValue(const char* name,bool &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } bool GetAttrValue(const char* name,unsigned &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } bool GetAttrValue(const char* name,DateTime &out) const { const XAttr* pAttr=GetAttr(name); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } - XAttrs GetAttrs( const char* name ); // in one level child nodes const XNode *GetChild( const char* name ) const; @@ -171,16 +198,12 @@ struct XNode bool GetChildValue(const char* name,bool &out) const { const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } bool GetChildValue(const char* name,unsigned &out) const{ const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } bool GetChildValue(const char* name,DateTime &out) const{ const XNode* pChild=GetChild(name); if(pChild==NULL) return false; pChild->GetValue(out); return true; } - XNodes GetChilds( const char* name ); - XNodes GetChilds(); XAttr *GetChildAttr( const char* name, const char* attrname ); const char* GetChildAttrValue( const char* name, const char* attrname ); // modify DOM int GetChildCount(); - XNode *GetChild( int i ); - XNodes::iterator GetChildIterator( XNode *node ); XNode *CreateNode( const char* name = NULL, const char* value = NULL ); XNode *AppendChild( const char* name = NULL, const char* value = NULL ); XNode *AppendChild( const char* name, float value ); @@ -189,11 +212,7 @@ struct XNode XNode *AppendChild( const char* name, const DateTime &value ); XNode *AppendChild( XNode *node ); bool RemoveChild( XNode *node ); - XNode *DetachChild( XNode *node ); - - XAttr *GetAttr( int i ); - XAttrs::iterator GetAttrIterator( XAttr *node ); XAttr *CreateAttr( const char* anem = NULL, const char* value = NULL ); XAttr *AppendAttr( const char* name = NULL, const char* value = NULL ); XAttr *AppendAttr( const char* name, float value ); @@ -202,7 +221,6 @@ struct XNode XAttr *AppendAttr( const char* name, const DateTime &value ); XAttr *AppendAttr( XAttr *attr ); bool RemoveAttr( XAttr *attr ); - XAttr *DetachAttr( XAttr *attr ); XNode() { } ~XNode();