From 1c3db825374e4bdb5ede8b398584d2b11939f0b2 Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Fri, 10 Apr 2015 09:10:51 -0600 Subject: [PATCH] Modified StepsID operators to consider 0 equal to all other hash values. See comment in source for details. Changed operator>>(RString&, int&) functions to be based off a template. --- src/RageUtil.cpp | 10 ---------- src/RageUtil.h | 8 ++++++-- src/StepsUtil.cpp | 21 ++++++++++++++++++++- src/StepsUtil.h | 19 +++++++++++++++++++ 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index 6fad93c022..9080ea55be 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -1845,16 +1845,6 @@ void MakeLower( wchar_t *p, size_t iLen ) UnicodeUpperLower( p, iLen, g_LowerCase ); } -bool operator>>(const RString& lhs, int& rhs) -{ - return !!(istringstream(lhs) >> rhs); -} - -bool operator>>(const RString& lhs, float& rhs) -{ - return !!(istringstream(lhs) >> rhs); -} - int StringToInt( const RString &sString ) { int ret; diff --git a/src/RageUtil.h b/src/RageUtil.h index 8a04ac8c4c..1ea979a785 100644 --- a/src/RageUtil.h +++ b/src/RageUtil.h @@ -5,6 +5,7 @@ #include #include +#include class RageFileDriver; /** @brief Safely delete pointers. */ @@ -414,8 +415,11 @@ float StringToFloat( const RString &sString ); RString FloatToString( const float &num ); bool StringToFloat( const RString &sString, float &fOut ); // Better than IntToString because you can check for success. -bool operator>>(const RString& lhs, int& rhs); -bool operator>>(const RString& lhs, float& rhs); +template +inline bool operator>>(const RString& lhs, T& rhs) +{ + return !!(istringstream(lhs) >> rhs); +} RString WStringToRString( const wstring &sString ); RString WcharToUTF8( wchar_t c ); diff --git a/src/StepsUtil.cpp b/src/StepsUtil.cpp index 075ac03716..f4b9240c5c 100644 --- a/src/StepsUtil.cpp +++ b/src/StepsUtil.cpp @@ -336,11 +336,30 @@ bool StepsID::operator<( const StepsID &rhs ) const COMP(st); COMP(dc); COMP(sDescription); - COMP(uHash); + // See explanation in class declaration. -Kyz + if(uHash != 0 && rhs.uHash != 0) + { + COMP(uHash); + } #undef COMP return false; } +bool StepsID::operator==(const StepsID &rhs) const +{ +#define COMP(a) if(a != rhs.a) return false; + COMP(st); + COMP(dc); + COMP(sDescription); + // See explanation in class declaration. -Kyz + if(uHash != 0 && rhs.uHash != 0) + { + COMP(uHash); + } +#undef COMP + return true; +} + /* * (c) 2001-2004 Chris Danford, Glenn Maynard * All rights reserved. diff --git a/src/StepsUtil.h b/src/StepsUtil.h index fa61a61900..31e644f656 100644 --- a/src/StepsUtil.h +++ b/src/StepsUtil.h @@ -173,7 +173,26 @@ public: void Unset() { FromSteps(NULL); } void FromSteps( const Steps *p ); Steps *ToSteps( const Song *p, bool bAllowNull ) const; + // FIXME: (interferes with unlimited charts per song) + // When performing comparisons, the hash value 0 is considered equal to + // all other values. This is because the hash value for a Steps is + // discarded immediately after loading and figuring out a way to preserve + // and cache it turned into a mess that still didn't work. + // When scores are looked up by the theme, the theme passes in a Steps + // which is transformed into a StepsID, which is then used to index into a + // map. So when the theme goes to look up the scores for a Steps, the + // Steps has a hash value of 0, unless it has been played. But when the + // scores are saved, the Steps has a correct hash value. So before a + // Steps is played, the scores could not be correctly accessed. This was + // only visible on Edit charts because scores on all other difficulties + // are saved without a hash value. + // Making operator< and operator== treat 0 as equal to all other hash + // values allows the theme to fetch the scores even though the Steps has + // a cleared hash value, but is not a good long term solution because the + // description field isn't always going to be unique. + // -Kyz bool operator<( const StepsID &rhs ) const; + bool operator==(const StepsID &rhs) const; bool MatchesStepsType( StepsType s ) const { return st == s; } XNode* CreateNode() const;