From d815b394eae8a3400acfcaa0135db16b99c333c2 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sun, 28 Jun 2015 19:11:21 +0200 Subject: [PATCH] Move code that doesn't need to be templated to another class. --- include/doorkeeper/helpers/tylermapsource.hpp | 41 ++++-- include/doorkeeper/implem/tylermapsource.inl | 74 +++------- src/tylermapsource.cpp | 130 ++++++++++++++---- 3 files changed, 145 insertions(+), 100 deletions(-) diff --git a/include/doorkeeper/helpers/tylermapsource.hpp b/include/doorkeeper/helpers/tylermapsource.hpp index c895a3b..b804ff7 100644 --- a/include/doorkeeper/helpers/tylermapsource.hpp +++ b/include/doorkeeper/helpers/tylermapsource.hpp @@ -18,9 +18,34 @@ #endif namespace dkh { + namespace implem { + class TylerMapSourceBase { + public: + typedef std::istream::pos_type pos_type; + + explicit TylerMapSourceBase ( pos_type parStreamStartPos ); + ~TylerMapSourceBase ( void ); + + dk::HashType layerTypeHash ( int parIndex ) const; + void chainedMaps ( std::vector& parOut ) const; + dk::MapTypes mapType ( void ) const; + void parseMapHeaders ( std::istream& parSrc, uint32_t parDim, std::vector& parMapDims, std::vector& parTileDims ); + + private: + struct LayerInfo; + + std::vector m_layers_info; + dk::MapTypes m_map_type; + std::map m_comments; + std::string m_file_vendor; + pos_type m_stream_start; + }; + } //namespace implem + template - class TylerMapSource : public dk::BaseMapSource { - typedef std::istream::pos_type pos_type; + class TylerMapSource : private implem::TylerMapSourceBase, public dk::BaseMapSource { + typedef implem::TylerMapSourceBase base_class; + typedef base_class::pos_type pos_type; public: typedef dk::Vector coords; enum { @@ -43,20 +68,13 @@ namespace dkh { virtual dk::HashType layerTypeHash ( int parIndex ) const; private: - struct LayerInfo; - void parse_map_data ( std::istream& parSrc ); virtual void fetch_raw ( char* parOut, const coords& parFrom, const coords& parTo, std::size_t parSize ); std::unique_ptr m_stream; - std::map m_comments; - std::vector m_layers_info; coords m_map_size; coords m_tile_size; - pos_type m_stream_start; - std::string m_file_vendor; - dk::MapTypes m_map_type; uint16_t m_map_version_major; uint16_t m_map_version_minor; uint8_t m_layer_count; @@ -99,14 +117,9 @@ namespace dkh { uint32_t layer_format; } __attribute__((packed, aligned(__alignof__(uint32_t)))); - typedef std::map CommentMap; - void read_header ( std::istream& parStream, TylerMapHeader& parHeader ); void read_layer_header ( std::istream& parStream, TylerMapLayerHeader& parHeader ); - void read_comments ( std::istream& parStream, std::string& parVendor, CommentMap& parComments ); void read_dimensions ( std::istream& parStream, uint32_t parDimensions, std::vector& parMap, std::vector& parTile ); - - void extract_array_from_comments ( std::vector& parOut, const std::string& parPrefix, const std::map& parMap ); } //namespace implem } //namespace dkh diff --git a/include/doorkeeper/implem/tylermapsource.inl b/include/doorkeeper/implem/tylermapsource.inl index 2f36a3c..d104bf8 100644 --- a/include/doorkeeper/implem/tylermapsource.inl +++ b/include/doorkeeper/implem/tylermapsource.inl @@ -1,78 +1,40 @@ namespace dkh { - template - struct TylerMapSource::LayerInfo { - dk::HashType hash; - uint32_t data_start; - uint32_t data_length; - }; - template TylerMapSource::TylerMapSource (const char* parFilename) : - m_stream(new std::ifstream(parFilename)), - m_stream_start(m_stream->tellg()) + base_class(m_stream->tellg()), + m_stream(new std::ifstream(parFilename)) { parse_map_data(*m_stream); } template TylerMapSource::TylerMapSource (const std::string& parFilename) : - m_stream(new std::ifstream(parFilename)), - m_stream_start(m_stream->tellg()) + base_class(m_stream->tellg()), + m_stream(new std::ifstream(parFilename)) { parse_map_data(*m_stream); } template TylerMapSource::TylerMapSource (std::istream* parData) : - m_stream(parData), - m_stream_start(m_stream->tellg()) + base_class(m_stream->tellg()), + m_stream(parData) { parse_map_data(*m_stream); } template void TylerMapSource::parse_map_data (std::istream& parSrc) { - //Read file header - implem::TylerMapHeader header; - implem::read_header(parSrc, header); + std::vector map_dims; + std::vector tile_dims; - if (header.dimensions != D) { - throw InvalidMapDimensionsException(); + parseMapHeaders(parSrc, D, map_dims, tile_dims); + DK_ASSERT(map_dims.size() == D); + DK_ASSERT(tile_dims.size() == D); + for (std::size_t z = 0; z < D; ++z) { + m_map_size[z] = map_dims[z]; + m_tile_size[z] = tile_dims[z]; } - - switch (header.map_type) { - case dk::MapType_IsometricStaggered: - m_map_type = dk::MapType_IsometricStaggered; - break; - case dk::MapType_Isometric: - m_map_type = dk::MapType_Isometric; - break; - case dk::MapType_Orthogonal: - m_map_type = dk::MapType_Orthogonal; - break; - case dk::MapType_Hex: - m_map_type = dk::MapType_Hex; - break; - default: - throw InvalidMapFileException(); - } - - //Read map and tile dimensions - { - std::vector map_dims; - std::vector tile_dims; - const auto read_start = (header.dimensions_start > sizeof(header) ? header.dimensions_start - sizeof(header) : sizeof(header)); - parSrc.seekg(read_start, std::ios_base::cur); - implem::read_dimensions(parSrc, D, map_dims, tile_dims); - for (std::size_t z = 0; z < map_dims.size(); ++z) { - m_map_size[z] = map_dims[z]; - m_tile_size[z] = tile_dims[z]; - } - } - - //Read vorbis comments - parSrc.seekg(header.comment_start + m_stream_start, std::ios_base::beg); - implem::read_comments(parSrc, m_file_vendor, m_comments); } template @@ -95,7 +57,7 @@ namespace dkh { template dk::MapTypes TylerMapSource::mapType() const { - return m_map_type; + return base_class::mapType(); } template @@ -105,13 +67,11 @@ namespace dkh { template void TylerMapSource::chainedMaps (std::vector& parOut) const { - implem::extract_array_from_comments(parOut, "chained_map", m_comments); + return base_class::chainedMaps(parOut); } template dk::HashType TylerMapSource::layerTypeHash (int parIndex) const { - DK_ASSERT(parIndex >= 0); - DK_ASSERT(static_cast(parIndex) < m_layers_info.size()); - return m_layers_info[parIndex].hash; + return base_class::layerTypeHash(parIndex); } } //namespace dkh diff --git a/src/tylermapsource.cpp b/src/tylermapsource.cpp index 2803959..4b82dc3 100644 --- a/src/tylermapsource.cpp +++ b/src/tylermapsource.cpp @@ -35,6 +35,8 @@ namespace dkh { namespace { + typedef std::map CommentMap; + const uint32_t g_signature = 0x52504B44; //DKPR template T lil_endian_to_machine ( T parIn ) a_pure; @@ -148,16 +150,6 @@ namespace dkh { bool isdigit (char parChar) { return std::isdigit(parChar); } - } //unnamed namespace - - namespace implem { - void read_header (std::istream& parStream, TylerMapHeader& parHeader) { - parStream.read(reinterpret_cast(&parHeader), sizeof(TylerMapHeader)); - parHeader = lil_endian_to_machine(parHeader); - - if (g_signature != parHeader.signature) - throw InvalidMapFileException(); - } void read_comments (std::istream& parStream, std::string& parVendor, CommentMap& parComments) { //Technically there is no limit on strings other than the uint32 @@ -177,25 +169,6 @@ namespace dkh { } } - void read_layer_header (std::istream& parStream, TylerMapLayerHeader& parHeader) { - parStream.read(reinterpret_cast(&parHeader), sizeof(TylerMapLayerHeader)); - parHeader = lil_endian_to_machine(parHeader); - } - - void read_dimensions (std::istream& parStream, uint32_t parDimensions, std::vector& parMap, std::vector& parTile) { - parMap.reserve(parMap.size() + parDimensions); - for (uint32_t z = 0; z < parDimensions; ++z) { - const auto dim = read_int(parStream); - parMap.push_back(dim); - } - - parTile.reserve(parTile.size() + parDimensions); - for (uint32_t z = 0; z < parDimensions; ++z) { - const auto dim = read_int(parStream); - parTile.push_back(dim); - } - } - void extract_array_from_comments (std::vector& parOut, const std::string& parPrefix, const std::map& parMap) { typedef decltype(std::distance(parPrefix.begin(), parPrefix.end())) diff_type; using std::size_t; @@ -235,5 +208,104 @@ namespace dkh { parOut[index] = itcurr.second; } } + } //unnamed namespace + + namespace implem { + struct TylerMapSourceBase::LayerInfo { + dk::HashType hash; + uint32_t data_start; + uint32_t data_length; + }; + + TylerMapSourceBase::TylerMapSourceBase (pos_type parStreamStartPos) : + m_stream_start(parStreamStartPos) + { + } + + TylerMapSourceBase::~TylerMapSourceBase() { + } + + dk::HashType TylerMapSourceBase::layerTypeHash (int parIndex) const { + DK_ASSERT(parIndex >= 0); + DK_ASSERT(static_cast(parIndex) < m_layers_info.size()); + return m_layers_info[parIndex].hash; + } + + void TylerMapSourceBase::chainedMaps (std::vector& parOut) const { + extract_array_from_comments(parOut, "chained_map", m_comments); + } + + dk::MapTypes TylerMapSourceBase::mapType() const { + return m_map_type; + } + + void TylerMapSourceBase::parseMapHeaders (std::istream& parSrc, uint32_t parDim, std::vector& parMapDims, std::vector& parTileDims) { + //Read file header + implem::TylerMapHeader header; + implem::read_header(parSrc, header); + + if (header.dimensions != parDim) { + throw InvalidMapDimensionsException(); + } + + switch (header.map_type) { + case dk::MapType_IsometricStaggered: + m_map_type = dk::MapType_IsometricStaggered; + break; + case dk::MapType_Isometric: + m_map_type = dk::MapType_Isometric; + break; + case dk::MapType_Orthogonal: + m_map_type = dk::MapType_Orthogonal; + break; + case dk::MapType_Hex: + m_map_type = dk::MapType_Hex; + break; + default: + throw InvalidMapFileException(); + } + + //Read map and tile dimensions + { + std::vector map_dims; + std::vector tile_dims; + const auto read_start = (header.dimensions_start > sizeof(header) ? header.dimensions_start - sizeof(header) : sizeof(header)); + parSrc.seekg(read_start, std::ios_base::cur); + implem::read_dimensions(parSrc, parDim, map_dims, tile_dims); + parMapDims.swap(map_dims); + parTileDims.swap(tile_dims); + } + + //Read vorbis comments + parSrc.seekg(header.comment_start + m_stream_start, std::ios_base::beg); + read_comments(parSrc, m_file_vendor, m_comments); + } + + void read_header (std::istream& parStream, TylerMapHeader& parHeader) { + parStream.read(reinterpret_cast(&parHeader), sizeof(TylerMapHeader)); + parHeader = lil_endian_to_machine(parHeader); + + if (g_signature != parHeader.signature) + throw InvalidMapFileException(); + } + + void read_layer_header (std::istream& parStream, TylerMapLayerHeader& parHeader) { + parStream.read(reinterpret_cast(&parHeader), sizeof(TylerMapLayerHeader)); + parHeader = lil_endian_to_machine(parHeader); + } + + void read_dimensions (std::istream& parStream, uint32_t parDimensions, std::vector& parMap, std::vector& parTile) { + parMap.reserve(parMap.size() + parDimensions); + for (uint32_t z = 0; z < parDimensions; ++z) { + const auto dim = read_int(parStream); + parMap.push_back(dim); + } + + parTile.reserve(parTile.size() + parDimensions); + for (uint32_t z = 0; z < parDimensions; ++z) { + const auto dim = read_int(parStream); + parTile.push_back(dim); + } + } } //namespace implem } //namespace dkh