From 5637bf4e5c28a9a0923d9aa264fb3bbc8737ea1d Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 31 Aug 2015 17:11:11 +0200 Subject: [PATCH] DELEME --- CMakeLists.txt | 2 +- .../doorkeeper/components/layeredviewport.hpp | 18 ++-- include/doorkeeper/components/tyler.hpp | 10 ++- include/doorkeeper/components/viewport.hpp | 8 +- .../doorkeeper/implem/iterableviewport.hpp | 50 +++++++++++ include/doorkeeper/implem/layeredviewport.inl | 83 ++++++++++++++----- include/doorkeeper/implem/tyler.inl | 33 ++++++++ include/doorkeeper/implem/viewport.inl | 16 +--- test/main.cpp | 2 - test/unit/asciimapsource.cpp | 28 +++---- test/unit/layeredviewport.cpp | 2 +- 11 files changed, 183 insertions(+), 69 deletions(-) create mode 100644 include/doorkeeper/implem/iterableviewport.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f385dc2..a0e606e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(gdb_scripts_path "${CMAKE_CURRENT_SOURCE_DIR}/tools/gdb") #add_subdirectory(lib/sprout) add_subdirectory(src) -add_subdirectory(test) +#add_subdirectory(test) add_subdirectory(game) #add_subdirectory(tools/mapconv) add_subdirectory(test/gtest-1.7.0) diff --git a/include/doorkeeper/components/layeredviewport.hpp b/include/doorkeeper/components/layeredviewport.hpp index f299e13..b99c4f0 100644 --- a/include/doorkeeper/components/layeredviewport.hpp +++ b/include/doorkeeper/components/layeredviewport.hpp @@ -22,7 +22,8 @@ #include "doorkeeper/components/viewport.hpp" #include "doorkeeper/components/tyler.hpp" #include "doorkeeper/components/layer.hpp" -#include +#include "doorkeeper/implem/iterableviewport.hpp" +#include #include #include #include @@ -33,11 +34,12 @@ namespace dk { template class LayeredViewport { - typedef std::map, Viewport> ViewportList; + struct ViewportItem; + typedef std::vector ViewportList; public: typedef VectorT coords_f; - typedef boost::transform_iterator&(const LayerBase&)>, typename Tyler::iterator> iterator; - typedef boost::transform_iterator&(const LayerBase&)>, typename Tyler::const_iterator> const_iterator; + typedef boost::transform_iterator&(const LayerBase&)>, typename Tyler::iterator> iterator; + typedef boost::transform_iterator&(const LayerBase&)>, typename Tyler::const_iterator> const_iterator; explicit LayeredViewport ( Tyler& parTyler ); ~LayeredViewport ( void ) noexcept; @@ -45,18 +47,18 @@ namespace dk { LayeredViewport& operator+= ( const coords_f& parValue ); LayeredViewport& operator-= ( const coords_f& parValue ); - void on_layer_added ( const LayerBase* parLayer ); - void on_layer_removed ( const LayerBase* parLayer ); + void on_layer ( const LayerBase& parLayer, bool parAdded ); iterator begin ( void ); const_iterator begin ( void ) const; iterator end ( void ); const_iterator end ( void ) const; - Viewport& viewport ( const LayerBase& parLayer ); - const Viewport& viewport ( const LayerBase& parLayer ) const; + IterableViewport viewport ( const LayerBase& parLayer ); + const IterableViewport viewport ( const LayerBase& parLayer ) const; private: ViewportList m_views; Tyler& m_tyler; + typename Tyler::LayerObsID m_tyler_id; }; } //namespace dk diff --git a/include/doorkeeper/components/tyler.hpp b/include/doorkeeper/components/tyler.hpp index f2d38bf..acce86d 100644 --- a/include/doorkeeper/components/tyler.hpp +++ b/include/doorkeeper/components/tyler.hpp @@ -20,6 +20,7 @@ #include "doorkeeper/components/layer.hpp" #include "doorkeeper/components/exception.hpp" +#include "doorkeeper/implem/idmanager.hpp" #include #include #include @@ -35,11 +36,13 @@ namespace dk { class Tyler { typedef std::unique_ptr> LayerPtr; typedef std::vector LayerList; + typedef IDManager<7, 9> LayerObsIDManager; public: typedef typename LayerBase::coords coords; typedef boost::indirect_iterator iterator; typedef boost::indirect_iterator const_iterator; typedef std::function&, bool) noexcept> layer_callback; + typedef LayerObsIDManager::value_type LayerObsID; Tyler ( void ); Tyler ( Tyler&& ) = default; @@ -56,12 +59,13 @@ namespace dk { const_iterator end ( void ) const; void preload ( const coords& parFrom, const coords& parTo ); - void register_for_layeradd ( layer_callback parCallback ); - void unregister_for_layeradd ( layer_callback parCallback ); + LayerObsID register_for_layeradd ( layer_callback parCallback ); + void unregister_for_layeradd ( LayerObsID parID ); private: + LayerObsIDManager m_layerobs_idmanager; LayerList m_layers; - std::vector m_layer_add_callbacks; + std::vector m_layerobs_callbacks; }; } //namespace dk diff --git a/include/doorkeeper/components/viewport.hpp b/include/doorkeeper/components/viewport.hpp index d2a06a3..e99cf9e 100644 --- a/include/doorkeeper/components/viewport.hpp +++ b/include/doorkeeper/components/viewport.hpp @@ -24,7 +24,6 @@ #include "doorkeeper/components/tilecoords.hpp" #include #include -#include namespace dk { template @@ -39,13 +38,12 @@ namespace dk { TileInfo ( const LayerBase& parLayer ); + bool operator== ( const TileInfo& parOther ) const; + coords tile_size; coords map_size; }; - template - std::size_t hash_value ( const TileInfo& parTProps ) noexcept a_pure; - template class Viewport { public: @@ -78,8 +76,6 @@ namespace dk { template typename Layer::const_iterator cend ( const Layer& parLayer ) const; - void set_tile_info ( const TileInfo* parTileInfo ); - private: void clip_pixel_offset ( void ); diff --git a/include/doorkeeper/implem/iterableviewport.hpp b/include/doorkeeper/implem/iterableviewport.hpp new file mode 100644 index 0000000..7f38054 --- /dev/null +++ b/include/doorkeeper/implem/iterableviewport.hpp @@ -0,0 +1,50 @@ +/* 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 . + */ + +#ifndef idD358B9737CC045D3B35F2B5C2FCF84FA +#define idD358B9737CC045D3B35F2B5C2FCF84FA + +#include "doorkeeper/components/viewport.hpp" +#include + +namespace dk { + template + class LayerBase; + + template + class IterableViewport { + public: + typedef typename Viewport::const_iterator const_iterator; + + IterableViewport ( const Viewport* parViewport, const LayerBase* parLayerBase ) : + m_viewport(parViewport), + m_layer(parLayerBase) + { + DK_ASSERT(m_viewport); + DK_ASSERT(m_layer); + } + + const_iterator begin ( void ) const { return m_viewport->begin(m_layer); } + const_iterator end ( void ) const { return m_viewport->end(m_layer); } + + private: + const Viewport* const m_viewport; + const LayerBase* const m_layer; + }; +} //namespace dk + +#endif diff --git a/include/doorkeeper/implem/layeredviewport.inl b/include/doorkeeper/implem/layeredviewport.inl index 597a154..e41ec5c 100644 --- a/include/doorkeeper/implem/layeredviewport.inl +++ b/include/doorkeeper/implem/layeredviewport.inl @@ -16,31 +16,53 @@ */ namespace dk { + template + struct LayeredViewport::ViewportItem { + ViewportItem ( const TileInfo& parTInfo, Tyler& parTyler ); + ViewportItem ( ViewportItem&& ) = default; + + TileInfo tile_info; + Viewport viewport; + int ref_count; + + bool operator== ( const TileInfo& parOther ) const a_pure; + }; + + template + LayeredViewport::ViewportItem::ViewportItem (const TileInfo& parTInfo, Tyler& parTyler) : + tile_info(parTInfo), + viewport(parTyler, &tile_info), + ref_count(1) + { + } + + template + bool LayeredViewport::ViewportItem::operator== (const TileInfo& parOther) const { + return tile_info == parOther; + } + template LayeredViewport::LayeredViewport (Tyler& parTyler) : m_tyler(parTyler) { for (const auto& layer : m_tyler) { - const TileInfo tinfo(layer); - auto it_found = m_views.find(tinfo); - if (m_views.end() == it_found) { - auto it_new = m_views.insert(it_found, Viewport(m_tyler, nullptr)); - it_new->second.set_tile_info(&it_new->first); - } + this->on_layer(layer, true); } - m_tyler.register_for_layeradd(this); + using std::placeholders::_1; + using std::placeholders::_2; + m_tyler_id = m_tyler.register_for_layeradd(std::bind(&LayeredViewport::on_layer, this, _1, _2)); } template LayeredViewport::~LayeredViewport() noexcept { - m_tyler.unregister_for_layeradd(this); + m_tyler.unregister_for_layeradd(m_tyler_id); } template LayeredViewport& LayeredViewport::operator+= (const coords_f& parValue) { for (auto& view : m_views) { - view.second += parValue; + view.viewport += parValue; } return *this; } @@ -48,44 +70,61 @@ namespace dk { template LayeredViewport& LayeredViewport::operator-= (const coords_f& parValue) { for (auto& view : m_views) { - view.second -= parValue; + view.viewport -= parValue; } return *this; } template - void LayeredViewport::on_layer_added (const LayerBase* parLayer) { - } + void LayeredViewport::on_layer (const LayerBase& parLayer, bool parAdded) { + const TileInfo tinfo(parLayer); + auto it_found = std::find(m_views.begin(), m_views.end(), tinfo); - template - void LayeredViewport::on_layer_removed (const LayerBase* parLayer) { + if (parAdded) { + if (m_views.end() == it_found) { + m_views.push_back(ViewportItem(tinfo, m_tyler)); + } + else { + ++it_found->ref_count; + } + } + else { + DK_ASSERT(m_views.end() != it_found); + --it_found->ref_count; + if (0 == it_found->ref_count) { + m_views.erase(it_found); + } + } } template auto LayeredViewport::begin() -> iterator { - return iterator(m_view.begin(), std::bind(&LayeredViewport::viewport, this, std::placeholders::_1)); + return iterator(m_views.begin(), std::bind(&LayeredViewport::viewport, this, std::placeholders::_1)); + } template auto LayeredViewport::begin() const -> const_iterator { - return const_iterator(m_view.begin(), std::bind(&LayeredViewport::viewport, this, std::placeholders::_1)); + return const_iterator(m_views.begin(), std::bind(&LayeredViewport::viewport, this, std::placeholders::_1)); } template auto LayeredViewport::end() -> iterator { - return iterator(m_view.end(), std::bind(&LayeredViewport::viewport, this, std::placeholders::_1)); + return iterator(m_views.end(), std::bind(&LayeredViewport::viewport, this, std::placeholders::_1)); + } template auto LayeredViewport::end() const -> const_iterator { - return const_iterator(m_view.end(), std::bind(&LayeredViewport::viewport, this, std::placeholders::_1)); + return const_iterator(m_views.end(), std::bind(&LayeredViewport::viewport, this, std::placeholders::_1)); } template - Viewport& LayeredViewport::viewport (const LayerBase& parLayer) { + IterableViewport LayeredViewport::viewport (const LayerBase& parLayer) { return const_cast&>(const_cast*>(this)->viewport(parLayer)); + } template - const Viewport& LayeredViewport::viewport (const LayerBase& parLayer) const { - const TileInfo tinfo { parLayer.tile_size(), parLayer.map_size() }; - return m_views[tinfo]; + const IterableViewport LayeredViewport::viewport (const LayerBase& parLayer) const { + const TileInfo tinfo { parLayer.tile_size(), parLayer.map_size() }; + return IterableViewport(&m_views[tinfo].first, &parLayer); } } //namespace dk diff --git a/include/doorkeeper/implem/tyler.inl b/include/doorkeeper/implem/tyler.inl index e15e2bd..c1eeada 100644 --- a/include/doorkeeper/implem/tyler.inl +++ b/include/doorkeeper/implem/tyler.inl @@ -32,6 +32,12 @@ namespace dk { auto newLayer = new Layer(parTilemap); m_layers.push_back(LayerPtr(newLayer)); + + for (auto& callback : m_layerobs_callbacks) { + if (nullptr != callback) { + callback(*newLayer, true); + } + } return *newLayer; } @@ -79,4 +85,31 @@ namespace dk { auto Tyler::end() const -> const_iterator { return const_iterator(m_layers.end()); } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + template + auto Tyler::register_for_layeradd (layer_callback parCallback) -> LayerObsID { + auto retval = m_layerobs_idmanager.allocate(); + DK_ASSERT(retval.index() > 0); + if (retval.index() > m_layerobs_callbacks.size()) { + DK_ASSERT(retval.index() == m_layerobs_callbacks.size() + 1); + m_layerobs_callbacks.resize(retval.index()); + } + else { + DK_ASSERT(retval.salt() > 0); + } + m_layerobs_callbacks[retval.index() - 1] = parCallback; + return retval; + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + template + void Tyler::unregister_for_layeradd (LayerObsID parID) { + DK_ASSERT(parID.index() <= m_layerobs_callbacks.size()); + DK_ASSERT(nullptr != m_layerobs_callbacks[parID.index() - 1]); + m_layerobs_callbacks[parID.index() - 1] = nullptr; + m_layerobs_idmanager.free(parID); + } } //namespace dk diff --git a/include/doorkeeper/implem/viewport.inl b/include/doorkeeper/implem/viewport.inl index bd86bd9..570de30 100644 --- a/include/doorkeeper/implem/viewport.inl +++ b/include/doorkeeper/implem/viewport.inl @@ -24,13 +24,8 @@ namespace dk { } template - inline std::size_t hash_value (const TileInfo& parTProps) noexcept { - std::size_t seed = 0; - for (uint32_t z = 0; z < D; ++z) { - boost::hash_combine(seed, parTProps.map_size[z]); - boost::hash_combine(seed, parTProps.tile_size[z]); - } - return seed; + bool TileInfo::operator== (const TileInfo& parOther) const { + return tile_size == parOther.tile_size and map_size == parOther.map_size; } template @@ -40,6 +35,7 @@ namespace dk { m_tyler(parTyler), m_tile_info(parTileInfo) { + DK_ASSERT(parTileInfo); } template @@ -49,6 +45,7 @@ namespace dk { m_tyler(parTyler), m_tile_info(parTileInfo) { + DK_ASSERT(parTileInfo); DK_ASSERT(parPos < parPos + m_tile_info->map_size); //parSize > 0 DK_ASSERT(m_tile_info->map_size + parPos <= m_tile_info->map_size); m_tyler.preload(m_view.position(), m_view.position() + this->size()); @@ -150,9 +147,4 @@ namespace dk { auto Viewport::pixel_offset() const -> coords { return static_cast(m_pixel_offset); } - - template - void Viewport::set_tile_info (const TileInfo* parTileInfo) { - m_tile_info = parTileInfo; - } } //namespace dk diff --git a/test/main.cpp b/test/main.cpp index 767e72d..bdd688a 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -96,8 +96,6 @@ int main() { addLayer(tiler, topLayer, DATA_PATH"/test_2.map"); dk::LayeredViewport<2> view_10_6(tiler); - dk::TileInfo<2> tinfo_10_6 { coords2(64), coords2(10, 6) }; - dk::TileInfo<2> tinfo_4_4 { coords2(64), coords2(4, 4) }; printViewport(dk::Viewport<2>(tiler, coords2(10, 6), coords2(0)), *bottomLayer.layer); printViewport(dk::Viewport<2>(tiler, coords2(4, 4), coords2(0)), *bottomLayer.layer); diff --git a/test/unit/asciimapsource.cpp b/test/unit/asciimapsource.cpp index 090ba60..0949642 100644 --- a/test/unit/asciimapsource.cpp +++ b/test/unit/asciimapsource.cpp @@ -31,7 +31,7 @@ const dk::CoordinateScalarType asciimapsource::map_width = 10; const dk::CoordinateScalarType asciimapsource::map_height = 8; asciimapsource::asciimapsource() : - tiler(coords2(map_width, map_height), coords2(tile_size)), + tiler(), layer(nullptr) { std::istringstream iss((std::string(map_data))); @@ -44,23 +44,23 @@ void asciimapsource::SetUp() { } TEST_F(asciimapsource, load) { - dk::Viewport<2> full_view(tiler, tiler.map_size(), coords2(0)); - - EXPECT_EQ(coords2(map_width, map_height), tiler.map_size()); + dk::LayeredViewport<2> full_view(tiler); dk::CoordinateDistType index = 0; int data_index = 0; - full_view.setFrom(coords2(0)); - for (auto itTile = full_view.begin(*layer), itTileEND = full_view.end(*layer); itTile != itTileEND; ++itTile) { - EXPECT_EQ(index, dk::to_index(itTile->raw_coords())); - EXPECT_LT(index, sizeof(map_data)); - ASSERT_LT(data_index, sizeof(map_data)); - const auto expected_value = static_cast(map_data[data_index] - '0'); - EXPECT_EQ(expected_value, itTile->data()); - ++index; - ++data_index; - if (map_data[data_index] == '\n') { + for (const auto& viewport : full_view) { + EXPECT_EQ(coords2(map_width, map_height), viewport.size()); + for (const auto& tile : viewport) { + EXPECT_EQ(index, dk::to_index(tile.raw_coords())); + EXPECT_LT(index, sizeof(map_data)); + ASSERT_LT(data_index, sizeof(map_data)); + const auto expected_value = static_cast(map_data[data_index] - '0'); + EXPECT_EQ(expected_value, tile.data()); + ++index; ++data_index; + if (map_data[data_index] == '\n') { + ++data_index; + } } } EXPECT_EQ(map_width * map_height, index); diff --git a/test/unit/layeredviewport.cpp b/test/unit/layeredviewport.cpp index 7eb35a4..547d0cb 100644 --- a/test/unit/layeredviewport.cpp +++ b/test/unit/layeredviewport.cpp @@ -21,5 +21,5 @@ TEST(components, layeredviewport) { dk::Tyler<3> tiler; - dk::layeredviewport<3> lview(tiler); + dk::LayeredViewport<3> lview(tiler); } \ No newline at end of file