1414#include " components/utilities/KeyValueFile.h"
1515#include " components/utilities/StringView.h"
1616
17- #define MAKE_MUSIC_DEFINITION_PAIR ( name ) { #name, MusicType ::name }
17+ #define MAKE_NAME_TYPE_PAIR ( type, name ) { #name, type ::name }
1818
1919namespace
2020{
21- constexpr std::pair<const char *, MusicType> MusicDefinitionTypes [] =
21+ constexpr std::pair<const char *, MusicType> MusicTypes [] =
2222 {
23- MAKE_MUSIC_DEFINITION_PAIR ( CharacterCreation),
24- MAKE_MUSIC_DEFINITION_PAIR ( Cinematic),
25- MAKE_MUSIC_DEFINITION_PAIR ( Interior),
26- MAKE_MUSIC_DEFINITION_PAIR ( Jingle),
27- MAKE_MUSIC_DEFINITION_PAIR ( MainMenu),
28- MAKE_MUSIC_DEFINITION_PAIR ( Night),
29- MAKE_MUSIC_DEFINITION_PAIR ( Swimming),
30- MAKE_MUSIC_DEFINITION_PAIR ( Weather)
23+ MAKE_NAME_TYPE_PAIR (MusicType, CharacterCreation),
24+ MAKE_NAME_TYPE_PAIR (MusicType, Cinematic),
25+ MAKE_NAME_TYPE_PAIR (MusicType, Interior),
26+ MAKE_NAME_TYPE_PAIR (MusicType, Jingle),
27+ MAKE_NAME_TYPE_PAIR (MusicType, MainMenu),
28+ MAKE_NAME_TYPE_PAIR (MusicType, Night),
29+ MAKE_NAME_TYPE_PAIR (MusicType, Swimming),
30+ MAKE_NAME_TYPE_PAIR (MusicType, Weather)
3131 };
3232
33- bool TryParseCinematicType ( const std::string_view str , CinematicMusicType *outCinematicType)
33+ constexpr std::pair< const char * , CinematicMusicType> CinematicMusicTypes[] =
3434 {
35- if (str == " Intro" )
36- {
37- *outCinematicType = CinematicMusicType::Intro;
38- }
39- else if (str == " DreamGood" )
35+ MAKE_NAME_TYPE_PAIR (CinematicMusicType, Intro),
36+ MAKE_NAME_TYPE_PAIR (CinematicMusicType, DreamGood),
37+ MAKE_NAME_TYPE_PAIR (CinematicMusicType, DreamBad),
38+ MAKE_NAME_TYPE_PAIR (CinematicMusicType, Ending)
39+ };
40+
41+ constexpr std::pair<const char *, InteriorMusicType> InteriorMusicTypes[] =
42+ {
43+ MAKE_NAME_TYPE_PAIR (InteriorMusicType, Dungeon),
44+ MAKE_NAME_TYPE_PAIR (InteriorMusicType, Equipment),
45+ MAKE_NAME_TYPE_PAIR (InteriorMusicType, House),
46+ MAKE_NAME_TYPE_PAIR (InteriorMusicType, MagesGuild),
47+ MAKE_NAME_TYPE_PAIR (InteriorMusicType, Palace),
48+ MAKE_NAME_TYPE_PAIR (InteriorMusicType, Tavern),
49+ MAKE_NAME_TYPE_PAIR (InteriorMusicType, Temple)
50+ };
51+
52+ constexpr std::pair<const char *, ArenaCityType> JingleCityTypes[] =
53+ {
54+ MAKE_NAME_TYPE_PAIR (ArenaCityType, CityState),
55+ MAKE_NAME_TYPE_PAIR (ArenaCityType, Town),
56+ MAKE_NAME_TYPE_PAIR (ArenaCityType, Village)
57+ };
58+
59+ constexpr std::pair<const char *, ArenaClimateType> JingleClimateTypes[] =
60+ {
61+ MAKE_NAME_TYPE_PAIR (ArenaClimateType, Temperate),
62+ MAKE_NAME_TYPE_PAIR (ArenaClimateType, Desert),
63+ MAKE_NAME_TYPE_PAIR (ArenaClimateType, Mountain)
64+ };
65+
66+ constexpr std::pair<const char *, WeatherType> WeatherTypes[] =
67+ {
68+ MAKE_NAME_TYPE_PAIR (WeatherType, Clear),
69+ MAKE_NAME_TYPE_PAIR (WeatherType, Overcast),
70+ MAKE_NAME_TYPE_PAIR (WeatherType, Rain),
71+ MAKE_NAME_TYPE_PAIR (WeatherType, Snow)
72+ };
73+
74+ template <typename T>
75+ bool TryParseTypeInternal (const std::string_view str, Span<const std::pair<const char *, T>> types, T *outType)
76+ {
77+ const auto iter = std::find_if (types.begin (), types.end (),
78+ [str](const std::pair<const char *, T> &pair)
4079 {
41- *outCinematicType = CinematicMusicType::DreamGood;
42- }
43- else if (str == " DreamBad" )
80+ return StringView::equals (pair.first , str);
81+ });
82+
83+ if (iter == types.end ())
4484 {
45- *outCinematicType = CinematicMusicType::DreamBad ;
85+ return false ;
4686 }
47- else if (str == " Ending" )
87+
88+ *outType = iter->second ;
89+ return true ;
90+ }
91+
92+ bool TryParseMusicType (const std::string_view str, MusicType *outType)
93+ {
94+ if (!TryParseTypeInternal<MusicType>(str, MusicTypes, outType))
4895 {
49- *outCinematicType = CinematicMusicType::Ending;
96+ DebugLogWarningFormat (" Unrecognized music type \" %s\" ." , std::string (str).c_str ());
97+ return false ;
5098 }
51- else
99+
100+ return true ;
101+ }
102+
103+ bool TryParseCinematicType (const std::string_view str, CinematicMusicType *outCinematicType)
104+ {
105+ if (!TryParseTypeInternal<CinematicMusicType>(str, CinematicMusicTypes, outCinematicType))
52106 {
53107 DebugLogWarningFormat (" Unrecognized cinematic music type \" %s\" ." , std::string (str).c_str ());
54108 return false ;
@@ -59,35 +113,7 @@ namespace
59113
60114 bool TryParseInteriorType (const std::string_view str, InteriorMusicType *outInteriorType)
61115 {
62- if (str == " Dungeon" )
63- {
64- *outInteriorType = InteriorMusicType::Dungeon;
65- }
66- else if (str == " Equipment" )
67- {
68- *outInteriorType = InteriorMusicType::Equipment;
69- }
70- else if (str == " House" )
71- {
72- *outInteriorType = InteriorMusicType::House;
73- }
74- else if (str == " MagesGuild" )
75- {
76- *outInteriorType = InteriorMusicType::MagesGuild;
77- }
78- else if (str == " Palace" )
79- {
80- *outInteriorType = InteriorMusicType::Palace;
81- }
82- else if (str == " Tavern" )
83- {
84- *outInteriorType = InteriorMusicType::Tavern;
85- }
86- else if (str == " Temple" )
87- {
88- *outInteriorType = InteriorMusicType::Temple;
89- }
90- else
116+ if (!TryParseTypeInternal<InteriorMusicType>(str, InteriorMusicTypes, outInteriorType))
91117 {
92118 DebugLogWarningFormat (" Unrecognized interior music type \" %s\" ." , std::string (str).c_str ());
93119 return false ;
@@ -98,19 +124,7 @@ namespace
98124
99125 bool TryParseJingleCityType (const std::string_view str, ArenaCityType *outCityType)
100126 {
101- if (str == " CityState" )
102- {
103- *outCityType = ArenaCityType::CityState;
104- }
105- else if (str == " Town" )
106- {
107- *outCityType = ArenaCityType::Town;
108- }
109- else if (str == " Village" )
110- {
111- *outCityType = ArenaCityType::Village;
112- }
113- else
127+ if (!TryParseTypeInternal<ArenaCityType>(str, JingleCityTypes, outCityType))
114128 {
115129 DebugLogWarningFormat (" Unrecognized city type \" %s\" ." , std::string (str).c_str ());
116130 return false ;
@@ -121,19 +135,7 @@ namespace
121135
122136 bool TryParseJingleClimateType (const std::string_view str, ArenaClimateType *outClimateType)
123137 {
124- if (str == " Temperate" )
125- {
126- *outClimateType = ArenaClimateType::Temperate;
127- }
128- else if (str == " Desert" )
129- {
130- *outClimateType = ArenaClimateType::Desert;
131- }
132- else if (str == " Mountain" )
133- {
134- *outClimateType = ArenaClimateType::Mountain;
135- }
136- else
138+ if (!TryParseTypeInternal<ArenaClimateType>(str, JingleClimateTypes, outClimateType))
137139 {
138140 DebugLogWarningFormat (" Unrecognized climate type \" %s\" ." , std::string (str).c_str ());
139141 return false ;
@@ -144,23 +146,7 @@ namespace
144146
145147 bool TryParseWeatherType (const std::string_view str, WeatherType *outWeatherType)
146148 {
147- if (str == " Clear" )
148- {
149- *outWeatherType = WeatherType::Clear;
150- }
151- else if (str == " Overcast" )
152- {
153- *outWeatherType = WeatherType::Overcast;
154- }
155- else if (str == " Rain" )
156- {
157- *outWeatherType = WeatherType::Rain;
158- }
159- else if (str == " Snow" )
160- {
161- *outWeatherType = WeatherType::Snow;
162- }
163- else
149+ if (!TryParseTypeInternal<WeatherType>(str, WeatherTypes, outWeatherType))
164150 {
165151 DebugLogWarningFormat (" Unrecognized weather type \" %s\" ." , std::string (str).c_str ());
166152 return false ;
@@ -169,7 +155,6 @@ namespace
169155 return true ;
170156 }
171157
172- // All weather arguments (heavy fog, etc.) are bools.
173158 bool TryParseWeatherBoolArg (const std::string_view str, bool *outValue)
174159 {
175160 if (StringView::caseInsensitiveEquals (str, " True" ))
@@ -190,25 +175,6 @@ namespace
190175 }
191176}
192177
193- bool MusicLibrary::tryParseType (const std::string_view typeStr, MusicType *outType)
194- {
195- const auto beginIter = std::begin (MusicDefinitionTypes);
196- const auto endIter = std::end (MusicDefinitionTypes);
197- const auto iter = std::find_if (beginIter, endIter,
198- [&typeStr](const std::pair<const char *, MusicType> &pair)
199- {
200- return StringView::equals (pair.first , typeStr);
201- });
202-
203- if (iter == endIter)
204- {
205- return false ;
206- }
207-
208- *outType = iter->second ;
209- return true ;
210- }
211-
212178bool MusicLibrary::tryParseValue (const std::string_view valueStr, MusicType type, MusicDefinition *outDefinition)
213179{
214180 constexpr char VALUE_SEPARATOR = ' ,' ;
@@ -434,7 +400,7 @@ bool MusicLibrary::init(const char *filename)
434400 const KeyValueFileSection §ion = keyValueFile.getSection (i);
435401
436402 MusicType sectionType;
437- if (!MusicLibrary::tryParseType (section.getName (), §ionType))
403+ if (!TryParseMusicType (section.getName (), §ionType))
438404 {
439405 DebugLogWarningFormat (" Couldn't parse section type \" %s\" ." , section.getName ().c_str ());
440406 continue ;
@@ -509,7 +475,7 @@ const MusicDefinition *MusicLibrary::getRandomMusicDefinition(MusicType type, Ra
509475 return this ->getMusicDefinition (type, index);
510476}
511477
512- const MusicDefinition *MusicLibrary::getRandomMusicDefinitionIf (MusicType type, Random &random, const Predicate &predicate) const
478+ const MusicDefinition *MusicLibrary::getRandomMusicDefinitionIf (MusicType type, Random &random, const MusicDefinitionPredicate &predicate) const
513479{
514480 Buffer<int > musicDefIndices (this ->getMusicDefinitionCount (type));
515481 std::iota (musicDefIndices.begin (), musicDefIndices.end (), 0 );
0 commit comments