From a82e8c16f6259dabf01368abf3d06337e07b86ff Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 28 May 2015 00:20:40 +0200 Subject: [PATCH] Helper recursive map loader. Recursion not tested since the file format is not ready yet, sorry. --- game/main.cpp | 8 ++- .../doorkeeper/components/basemapsource.hpp | 4 ++ include/doorkeeper/components/tyler.hpp | 1 + include/doorkeeper/doorkeeper2d.hpp | 10 ++++ include/doorkeeper/helpers/asciimapsource.hpp | 9 ++- include/doorkeeper/helpers/maploader.hpp | 45 ++++++++++++++ include/doorkeeper/implem/maploader.inl | 59 +++++++++++++++++++ src/asciimapsource.cpp | 16 ++++- test/main.cpp | 4 +- 9 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 include/doorkeeper/helpers/maploader.hpp create mode 100644 include/doorkeeper/implem/maploader.inl diff --git a/game/main.cpp b/game/main.cpp index 925cfea..0689648 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -1,4 +1,6 @@ #include "doorkeeper/doorkeeper2d.hpp" +#include "doorkeeper/helpers/maploader.hpp" +#include "doorkeeper/helpers/asciimapsource.hpp" #include "gameConfig.h" #include @@ -7,9 +9,13 @@ int main() { using dk::coords2; using dk::Viewport2d; using dk::Layer2d; + typedef dkh::MapLoaderPool2d*(const std::string&)>> IntPoolType; std::cout << "Welcome to " GAME_NAME " v" << GAME_VER_MAJOR << '.' << GAME_VER_MINOR << '.' << GAME_VER_PATCH << '\n'; - Tyler2d tiler(coords2(64, 33)); + IntPoolType pool; + pool.opener = [](const std::string& parName) { std::cout << "Opening " << parName << std::endl; return new dkh::AsciiMapSource(parName, coords2(10, 8), dk::MapType_IsometricStaggered, coords2(64, 64)); }; + Tyler2d tiler(dkh::call_map_load(pool, std::string("test_level.dk"))); + return 0; } diff --git a/include/doorkeeper/components/basemapsource.hpp b/include/doorkeeper/components/basemapsource.hpp index bcbdaaa..2477b6b 100644 --- a/include/doorkeeper/components/basemapsource.hpp +++ b/include/doorkeeper/components/basemapsource.hpp @@ -4,6 +4,8 @@ #include "doorkeeper/implem/maptypes.hpp" #include "doorkeeper/primitivetypes.hpp" #include +#include +#include namespace dk { template @@ -15,8 +17,10 @@ namespace dk { virtual void fetch ( std::vector& parOut, const coords& parFrom, const coords& parTo ) = 0; virtual const coords& mapSize ( void ) const = 0; + virtual const coords& tileSize ( void ) const = 0; virtual MapTypes mapType ( void ) const = 0; virtual int layersCount ( void ) const = 0; + virtual void chainedMaps ( std::vector& parOut ) const = 0; }; } //namespace dk diff --git a/include/doorkeeper/components/tyler.hpp b/include/doorkeeper/components/tyler.hpp index 8c2be89..3f97e3e 100644 --- a/include/doorkeeper/components/tyler.hpp +++ b/include/doorkeeper/components/tyler.hpp @@ -21,6 +21,7 @@ namespace dk { typedef typename LayerBase::coords coords; Tyler ( void ) = delete; + Tyler ( Tyler&& ) = default; explicit Tyler ( const coords& parTileSize ); ~Tyler ( void ) noexcept = default; diff --git a/include/doorkeeper/doorkeeper2d.hpp b/include/doorkeeper/doorkeeper2d.hpp index 4f35c63..3fb4298 100644 --- a/include/doorkeeper/doorkeeper2d.hpp +++ b/include/doorkeeper/doorkeeper2d.hpp @@ -2,12 +2,22 @@ #define id6327FA76CFB44F65A459C69096EC65D5 #include "doorkeeper.hpp" +#include namespace dk { typedef Tyler<2>::coords coords2; typedef Tyler<2> Tyler2d; template using Layer2d = Layer; typedef Viewport<2> Viewport2d; + template using BaseMapSource2d = BaseMapSource; } //namespace dk +namespace dkh { + template + struct MapLoaderPool; + + template + using MapLoaderPool2d = MapLoaderPool; +} //namespace dkh + #endif diff --git a/include/doorkeeper/helpers/asciimapsource.hpp b/include/doorkeeper/helpers/asciimapsource.hpp index 53ab6e6..9e43858 100644 --- a/include/doorkeeper/helpers/asciimapsource.hpp +++ b/include/doorkeeper/helpers/asciimapsource.hpp @@ -23,15 +23,17 @@ namespace dkh { AsciiMapSource ( void ) = delete; AsciiMapSource ( const AsciiMapSource& ) = delete; AsciiMapSource ( AsciiMapSource&& parOther ) = default; - AsciiMapSource ( const char* parFilename, const coords& parSize, dk::MapTypes parMapType ); - AsciiMapSource ( const std::string& parFilename, const coords& parSize, dk::MapTypes parMapType ); - AsciiMapSource ( std::istream& parData, const coords& parSize, dk::MapTypes parMapType ); + AsciiMapSource ( const char* parFilename, const coords& parSize, dk::MapTypes parMapType, const coords& parTileSize ); + AsciiMapSource ( const std::string& parFilename, const coords& parSize, dk::MapTypes parMapType, const coords& parTileSize ); + AsciiMapSource ( std::istream& parData, const coords& parSize, dk::MapTypes parMapType, const coords& parTileSize ); virtual ~AsciiMapSource ( void ) noexcept = default; virtual const coords& mapSize ( void ) const; virtual void fetch ( std::vector& parOut, const coords& parFrom, const coords& parTo ); virtual dk::MapTypes mapType ( void ) const; virtual int layersCount ( void ) const; + virtual const coords& tileSize ( void ) const; + virtual void chainedMaps ( std::vector& parOut ) const; private: enum { @@ -42,6 +44,7 @@ namespace dkh { std::vector m_wholedata; const coords m_mapSize; + const coords m_tileSize; std::size_t m_bytepos; const dk::MapTypes m_mapType; }; diff --git a/include/doorkeeper/helpers/maploader.hpp b/include/doorkeeper/helpers/maploader.hpp new file mode 100644 index 0000000..b07b73e --- /dev/null +++ b/include/doorkeeper/helpers/maploader.hpp @@ -0,0 +1,45 @@ +#ifndef idA52FEA0859494D3FBDF8ED5565091C59 +#define idA52FEA0859494D3FBDF8ED5565091C59 + +#include "doorkeeper/components/tyler.hpp" +#include "doorkeeper/components/basemapsource.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace dkh { + template + struct MapLoaderPool { + typedef std::unique_ptr> BaseMapSourceUPtr; + typedef std::map PoolMapType; + + enum { dimensions = D }; + typedef C opener_type; + typedef T tile_type; + + PoolMapType pool; + C opener; + + dk::BaseMapSource* operator() ( const std::string& parName ); + }; + + template + dk::Tyler call_map_load ( M& parFileOpener, const std::string& parOpen ); + + template + dk::Tyler call_map_load ( dk::Tyler& parTyler, M& parFileOpener, const std::string& parOpen ); + + template + dk::Tyler map_load ( C& parFileOpener, const std::string& parOpen ); + + template + dk::Tyler& map_load ( dk::Tyler& parTyler, C& parFileOpener, const std::string& parOpen ); +} //namespace dkh + +#include "doorkeeper/implem/maploader.inl" + +#endif diff --git a/include/doorkeeper/implem/maploader.inl b/include/doorkeeper/implem/maploader.inl new file mode 100644 index 0000000..e02e21f --- /dev/null +++ b/include/doorkeeper/implem/maploader.inl @@ -0,0 +1,59 @@ +namespace dkh { + template + dk::Tyler map_load (C& parFileOpener, const std::string& parOpen) { + dk::BaseMapSource* reader = parFileOpener(parOpen); + dk::Tyler tyler(reader->tileSize()); + tyler.push_layer(reader); + std::vector submaps; + reader->chainedMaps(submaps); + for (const auto& name : submaps) { + map_load(tyler, parFileOpener, name); + } + return std::move(tyler); + } + + template + dk::Tyler& map_load (dk::Tyler& parTyler, C& parFileOpener, const std::string& parOpen) { + 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)); + } + + parTyler.push_layer(reader); + } 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) { + return map_load(parFileOpener, parOpen); + } + + template + dk::Tyler call_map_load (dk::Tyler& parTyler, M& parFileOpener, const std::string& parOpen) { + return map_load(parTyler, parFileOpener, parOpen); + } +} //namespace dkh diff --git a/src/asciimapsource.cpp b/src/asciimapsource.cpp index c174a38..acf6f82 100644 --- a/src/asciimapsource.cpp +++ b/src/asciimapsource.cpp @@ -10,8 +10,9 @@ namespace dkh { ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- - AsciiMapSource::AsciiMapSource (const char* parFilename, const coords& parSize, dk::MapTypes parMapType) : + AsciiMapSource::AsciiMapSource (const char* parFilename, const coords& parSize, dk::MapTypes parMapType, const coords& parTileSize) : m_mapSize(parSize), + m_tileSize(parTileSize), m_bytepos(0), m_mapType(parMapType) { @@ -21,8 +22,9 @@ namespace dkh { ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- - AsciiMapSource::AsciiMapSource (const std::string& parFilename, const coords& parSize, dk::MapTypes parMapType) : + AsciiMapSource::AsciiMapSource (const std::string& parFilename, const coords& parSize, dk::MapTypes parMapType, const coords& parTileSize) : m_mapSize(parSize), + m_tileSize(parTileSize), m_bytepos(0), m_mapType(parMapType) { @@ -32,8 +34,9 @@ namespace dkh { ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- - AsciiMapSource::AsciiMapSource (std::istream& parData, const coords& parSize, dk::MapTypes parMapType) : + AsciiMapSource::AsciiMapSource (std::istream& parData, const coords& parSize, dk::MapTypes parMapType, const coords& parTileSize) : m_mapSize(parSize), + m_tileSize(parTileSize), m_bytepos(0), m_mapType(parMapType) { @@ -85,6 +88,10 @@ namespace dkh { return m_mapSize; } + const AsciiMapSource::coords& AsciiMapSource::tileSize() const { + return m_tileSize; + } + void AsciiMapSource::fetch (std::vector& parOut, const coords& parFrom, const coords& parTo) { const std::size_t from = parFrom.x() + parFrom.y() * m_mapSize.x(); const std::size_t to = parTo.x() + parTo.y() * m_mapSize.x() + 1; @@ -100,4 +107,7 @@ namespace dkh { int AsciiMapSource::layersCount() const { return 1; } + + void AsciiMapSource::chainedMaps (std::vector&) const { + } } //namespace dkh diff --git a/test/main.cpp b/test/main.cpp index ae7d066..8a43808 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -144,8 +144,10 @@ namespace { } void addLayer (dk::Tyler<2>& parTiler, LayerWithData& parLayerInfo, const char* parPath) { + typedef dkh::AsciiMapSource::coords coords; + parLayerInfo.path = parPath; - parLayerInfo.device.reset(new dkh::AsciiMapSource(parLayerInfo.path, dkh::AsciiMapSource::coords(10, 8), dk::MapType_IsometricStaggered)); + parLayerInfo.device.reset(new dkh::AsciiMapSource(parLayerInfo.path, coords(10, 8), dk::MapType_IsometricStaggered, coords(64, 64))); parLayerInfo.layer = &parTiler.push_layer(parLayerInfo.device.get()); }