/* Copyright 2015, Michele Santullo
* This file is part of DoorKeeper.
*
* DoorKeeper is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DoorKeeper is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DoorKeeper. If not, see .
*/
namespace dkh {
template
dk::Tyler map_load (C& parFileOpener, const std::string& parOpen, const PushLayerMapType& parPusher) {
dk::BaseMapSource* reader = parFileOpener(parOpen);
dk::Tyler tyler(reader->tileSize());
for (int z = 0; z < reader->layersCount(); ++z) {
implem::call_push_layer(tyler, parPusher, reader, z);
}
std::vector submaps;
reader->chainedMaps(submaps);
for (const auto& name : submaps) {
map_load(tyler, parFileOpener, name, parPusher);
}
return std::move(tyler);
}
template
dk::Tyler& map_load (dk::Tyler& parTyler, C& parFileOpener, const std::string& parOpen, const PushLayerMapType& parPusher) {
std::stack> name_stack;
std::vector submaps;
name_stack.push(parOpen);
do {
dk::BaseMapSource* reader = parFileOpener(name_stack.top());
name_stack.pop();
submaps.clear();
reader->chainedMaps(submaps);
for (auto&& curr_name : submaps) {
name_stack.emplace(std::move(curr_name));
}
for (int z = 0; z < reader->layersCount(); ++z) {
implem::call_push_layer(parTyler, parPusher, reader, z);
}
} while (not name_stack.empty());
return parTyler;
}
template
dk::BaseMapSource* MapLoaderPool::operator() (const std::string& parName) {
auto it_found = pool.find(parName);
if (pool.end() != it_found) {
return it_found->second.get();
}
else {
std::pair new_item = pool.insert(std::make_pair(parName, BaseMapSourceUPtr(nullptr)));
DK_ASSERT(new_item.second);
new_item.first->second.reset(opener(parName));
return new_item.first->second.get();
}
}
template
dk::Tyler call_map_load (M& parFileOpener, const std::string& parOpen, const PushLayerMapType& parPusher) {
return map_load(parFileOpener, parOpen, parPusher);
}
template
dk::Tyler call_map_load (dk::Tyler& parTyler, M& parFileOpener, const std::string& parOpen, const PushLayerMapType& parPusher) {
return map_load(parTyler, parFileOpener, parOpen, parPusher);
}
namespace implem {
template
void call_push_layer (dk::Tyler& parTyler, const PushLayerMapType& parPusher, dk::BaseMapSource* parReader, int parLayerIndex) {
auto it_found = parPusher.find(parReader->layerTypeHash(parLayerIndex));
if (parPusher.end() == it_found)
throw UnknownLayerTemplateException();
(parTyler.*(it_found->second))(parReader, parLayerIndex);
}
} //namespace implem
} //namespace dkh