1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Improve performance of parsing of map headers for map list

This commit is contained in:
Ivan Savenko 2024-05-10 14:30:39 +00:00
parent 119c9a8fb4
commit 3acc1f1845
2 changed files with 49 additions and 12 deletions

View File

@ -66,7 +66,9 @@ void CBufferedStream::ensureSize(si64 size)
{ {
si64 initialSize = buffer.size(); si64 initialSize = buffer.size();
si64 currentStep = std::min<si64>(size, buffer.size()); si64 currentStep = std::min<si64>(size, buffer.size());
vstd::amax(currentStep, 1024); // to avoid large number of calls at start // to avoid large number of calls at start
// this is often used to load h3m map headers, most of which are ~300 bytes in size
vstd::amax(currentStep, 512);
buffer.resize(initialSize + currentStep); buffer.resize(initialSize + currentStep);

View File

@ -124,6 +124,49 @@ void CMapLoaderH3M::init()
//map->banWaterContent(); //Not sure if force this for custom scenarios //map->banWaterContent(); //Not sure if force this for custom scenarios
} }
static MapIdentifiersH3M generateMapping(EMapFormat format)
{
auto features = MapFormatFeaturesH3M::find(format, 0);
MapIdentifiersH3M identifierMapper;
if(features.levelROE)
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_RESTORATION_OF_ERATHIA));
if(features.levelAB)
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_ARMAGEDDONS_BLADE));
if(features.levelSOD)
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_SHADOW_OF_DEATH));
if(features.levelWOG)
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_IN_THE_WAKE_OF_GODS));
if(features.levelHOTA0)
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_HORN_OF_THE_ABYSS));
return identifierMapper;
}
static std::map<EMapFormat, MapIdentifiersH3M> generateMappings()
{
std::map<EMapFormat, MapIdentifiersH3M> result;
auto addMapping = [&result](EMapFormat format)
{
try
{
result[format] = generateMapping(format);
}
catch(const std::runtime_error &)
{
// unsupported map format - skip
}
};
addMapping(EMapFormat::ROE);
addMapping(EMapFormat::AB);
addMapping(EMapFormat::SOD);
addMapping(EMapFormat::HOTA);
addMapping(EMapFormat::WOG);
return result;
}
void CMapLoaderH3M::readHeader() void CMapLoaderH3M::readHeader()
{ {
// Map version // Map version
@ -159,18 +202,10 @@ void CMapLoaderH3M::readHeader()
features = MapFormatFeaturesH3M::find(mapHeader->version, 0); features = MapFormatFeaturesH3M::find(mapHeader->version, 0);
reader->setFormatLevel(features); reader->setFormatLevel(features);
} }
MapIdentifiersH3M identifierMapper;
if (features.levelROE) // optimization - load mappings only once to avoid slow parsing of map headers for map list
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_RESTORATION_OF_ERATHIA)); static const std::map<EMapFormat, MapIdentifiersH3M> identifierMappers = generateMappings();
if (features.levelAB) const MapIdentifiersH3M & identifierMapper = identifierMappers.at(mapHeader->version);
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_ARMAGEDDONS_BLADE));
if (features.levelSOD)
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_SHADOW_OF_DEATH));
if (features.levelWOG)
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_IN_THE_WAKE_OF_GODS));
if (features.levelHOTA0)
identifierMapper.loadMapping(VLC->settings()->getValue(EGameSettings::MAP_FORMAT_HORN_OF_THE_ABYSS));
reader->setIdentifierRemapper(identifierMapper); reader->setIdentifierRemapper(identifierMapper);