diff --git a/include/doorkeeper/components/layer.hpp b/include/doorkeeper/components/layer.hpp index 3a66736..2ea3691 100644 --- a/include/doorkeeper/components/layer.hpp +++ b/include/doorkeeper/components/layer.hpp @@ -66,22 +66,26 @@ namespace dk { typedef typename LayerBase::coords coords; typedef TileIterator iterator; typedef TileIterator const_iterator; + typedef std::function&, const T&)> EachTileCallback; Layer ( const Layer& ) = delete; Layer ( Layer&& ) = default; explicit Layer ( BaseMapSource* parTilemap ); + Layer ( BaseMapSource* parTilemap, EachTileCallback parEachTile ); virtual ~Layer ( void ) noexcept = default; - virtual void each_tile ( const Viewport& parViewport ) const; Layer& operator= ( const Layer& ) = delete; iterator begin ( void ); iterator end ( void ); + virtual void each_tile ( const Viewport& parViewport ) const; + private: virtual void onPreload ( const coords& parFrom, const coords& parTo ); std::vector m_tiles; + EachTileCallback m_each_tile; BaseMapSource* m_tilemap; }; diff --git a/include/doorkeeper/components/layeredviewport.hpp b/include/doorkeeper/components/layeredviewport.hpp index 32411dc..b1daf63 100644 --- a/include/doorkeeper/components/layeredviewport.hpp +++ b/include/doorkeeper/components/layeredviewport.hpp @@ -59,10 +59,11 @@ namespace dk { const IterableViewport viewport ( const LayerBase& parLayer ) const; LayeredViewport& operator= ( const LayeredViewport& ) = delete; + LayeredViewport& operator= ( LayeredViewport&& ) = default; private: ViewportList m_views; - Tyler& m_tyler; + Tyler* m_tyler; typename Tyler::LayerObsID m_tyler_id; }; } //namespace dk diff --git a/include/doorkeeper/components/viewport.hpp b/include/doorkeeper/components/viewport.hpp index 9acf038..4d64b5c 100644 --- a/include/doorkeeper/components/viewport.hpp +++ b/include/doorkeeper/components/viewport.hpp @@ -28,16 +28,20 @@ namespace dk { template class Tyler; - template - class Layer; + template + class LayerBase; template struct TileInfo { typedef Vector coords; TileInfo ( const LayerBase& parLayer ); + TileInfo ( const TileInfo& ) = default; + TileInfo ( TileInfo&& ) = default; bool operator== ( const TileInfo& parOther ) const; + TileInfo& operator= ( const TileInfo& ) = default; + TileInfo& operator= ( TileInfo&& ) = default; coords tile_size; coords map_size; @@ -55,12 +59,15 @@ namespace dk { ~Viewport ( void ) noexcept = default; Viewport& operator= ( const Viewport& ) = default; + Viewport& operator= ( Viewport&& ) = default; Viewport& operator+= ( const coords_f& parValue ); Viewport& operator-= ( const coords_f& parValue ); void setFrom ( const coords& parFrom ); coords size ( void ) const; coords pixel_offset ( void ) const; + const coords& upper ( void ) const; + const coords& block_position ( void ) const; private: void clip_pixel_offset ( void ); @@ -68,7 +75,7 @@ namespace dk { TileCoords m_view; coords_f m_pixel_offset; Tyler* m_tyler; - const TileInfo* const m_tile_info; + const TileInfo* m_tile_info; }; } //namespace dk diff --git a/include/doorkeeper/implem/layer.inl b/include/doorkeeper/implem/layer.inl index 1d5135c..6a85445 100644 --- a/include/doorkeeper/implem/layer.inl +++ b/include/doorkeeper/implem/layer.inl @@ -61,7 +61,16 @@ namespace dk { ///-------------------------------------------------------------------------- template Layer::Layer (BaseMapSource* parTilemap) : + Layer(parTilemap, EachTileCallback(nullptr)) + { + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + template + Layer::Layer (BaseMapSource* parTilemap, EachTileCallback parEachTile) : LayerBase(parTilemap->mapSize(), parTilemap->tileSize()), + m_each_tile(parEachTile), m_tilemap(parTilemap) { DK_ASSERT(m_tilemap); @@ -95,7 +104,16 @@ namespace dk { ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- template - void Layer::each_tile(const Viewport& parViewport) const { - DK_ASSERT(false); //TODO not implemented + void Layer::each_tile (const Viewport& parViewport) const { + if (not m_each_tile) { + return; + } + + const_iterator it(&m_tiles, m_tilemap->pixel_conv(), parViewport.block_position(), make_past_end_coords(parViewport.upper())); + const_iterator it_end(&m_tiles, m_tilemap->pixel_conv(), make_past_end_coords(parViewport.upper()), make_past_end_coords(parViewport.upper())); + + for (; it != it_end; ++it) { + m_each_tile(*this, *it); + } } } diff --git a/include/doorkeeper/implem/layeredviewport.inl b/include/doorkeeper/implem/layeredviewport.inl index c863f1c..ed031c1 100644 --- a/include/doorkeeper/implem/layeredviewport.inl +++ b/include/doorkeeper/implem/layeredviewport.inl @@ -28,7 +28,7 @@ namespace dk { bool operator== ( const TileInfo& parOther ) const a_pure; ViewportItem& operator= ( const ViewportItem& ) = default; - ViewportItem& operator= ( ViewportItem&& ) = delete; + ViewportItem& operator= ( ViewportItem&& ); }; template @@ -44,6 +44,14 @@ namespace dk { return tile_info == parOther; } + template + typename LayeredViewport::ViewportItem& LayeredViewport::ViewportItem::operator= (ViewportItem&& parOther) { + tile_info = std::move(parOther.tile_info); + viewport = std::move(parOther.viewport); + ref_count = parOther.ref_count; + return *this; + } + template LayeredViewport::LayeredViewport (LayeredViewport&& parOther) : m_views(std::move(parOther.m_views)), @@ -54,20 +62,21 @@ namespace dk { template LayeredViewport::LayeredViewport (Tyler& parTyler) : - m_tyler(parTyler) + m_tyler(&parTyler) { - for (const auto& layer : m_tyler) { + DK_ASSERT(m_tyler); + for (const auto& layer : *m_tyler) { this->on_layer(layer, true); } using std::placeholders::_1; using std::placeholders::_2; - m_tyler_id = m_tyler.register_for_layeradd(std::bind(&LayeredViewport::on_layer, this, _1, _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(m_tyler_id); + m_tyler->unregister_for_layeradd(m_tyler_id); } template @@ -93,7 +102,7 @@ namespace dk { if (parAdded) { if (m_views.end() == it_found) { - m_views.emplace_back(ViewportItem(tinfo, m_tyler)); + m_views.emplace_back(ViewportItem(tinfo, *m_tyler)); } else { ++it_found->ref_count; @@ -112,37 +121,39 @@ namespace dk { auto LayeredViewport::begin() -> iterator { IterableViewport (LayeredViewport::*vpfunc)(const LayerBase&) = &LayeredViewport::viewport; boost::function(const LayerBase&)> functor = boost::bind(vpfunc, this, _1); - auto it_beg = m_tyler.begin(); + auto it_beg = m_tyler->begin(); return boost::make_transform_iterator(it_beg, functor); } template auto LayeredViewport::begin() const -> const_iterator { const IterableViewport (LayeredViewport::*vpfunc)(const LayerBase&) const = &LayeredViewport::viewport; - return const_iterator(m_tyler.begin(), boost::bind(&vpfunc, this, _1)); + return const_iterator(m_tyler->begin(), boost::bind(&vpfunc, this, _1)); } template auto LayeredViewport::end() -> iterator { IterableViewport (LayeredViewport::*vpfunc)(const LayerBase&) = &LayeredViewport::viewport; boost::function(const LayerBase&)> functor = boost::bind(vpfunc, this, _1); - return boost::make_transform_iterator(m_tyler.end(), functor); + return boost::make_transform_iterator(m_tyler->end(), functor); } template auto LayeredViewport::end() const -> const_iterator { const IterableViewport (LayeredViewport::*vpfunc)(const LayerBase&) const = &LayeredViewport::viewport; - return const_iterator(m_tyler.end(), boost::bind(&vpfunc, this, _1)); + return const_iterator(m_tyler->end(), boost::bind(&vpfunc, this, _1)); } template IterableViewport LayeredViewport::viewport (const LayerBase& parLayer) { - return const_cast&>(const_cast*>(this)->viewport(parLayer)); + return const_cast*>(this)->viewport(parLayer); } template const IterableViewport LayeredViewport::viewport (const LayerBase& parLayer) const { - const TileInfo tinfo { parLayer.tile_size(), parLayer.map_size() }; - return IterableViewport(&m_views[tinfo].first, &parLayer); + const TileInfo tinfo(parLayer); + auto it_found = std::find(m_views.begin(), m_views.end(), tinfo); + DK_ASSERT(m_views.end() != it_found); + return IterableViewport(&it_found->viewport, &parLayer); } } //namespace dk diff --git a/include/doorkeeper/implem/viewport.inl b/include/doorkeeper/implem/viewport.inl index efc92e5..b609f7a 100644 --- a/include/doorkeeper/implem/viewport.inl +++ b/include/doorkeeper/implem/viewport.inl @@ -53,46 +53,6 @@ namespace dk { m_tyler->preload(m_view.position(), m_view.position() + this->size()); } - template - template - typename Layer::iterator Viewport::begin (Layer& parLayer) const { - typedef typename Layer::iterator IterType; - return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), m_view.position(), m_view.upper()); - } - - template - template - typename Layer::iterator Viewport::end (Layer& parLayer) const { - typedef typename Layer::iterator IterType; - return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), make_past_end_coords(m_view.upper()), make_past_end_coords(m_view.upper())); - } - - template - template - typename Layer::const_iterator Viewport::begin (const Layer& parLayer) const { - return this->cbegin(parLayer); - } - - template - template - typename Layer::const_iterator Viewport::end (const Layer& parLayer) const { - return this->cend(parLayer); - } - - template - template - typename Layer::const_iterator Viewport::cbegin (const Layer& parLayer) const { - typedef typename Layer::const_iterator IterType; - return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), m_view.position(), m_view.upper()); - } - - template - template - typename Layer::const_iterator Viewport::cend (const Layer& parLayer) const { - typedef typename Layer::const_iterator IterType; - return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), make_past_end_coords(m_view.upper()), make_past_end_coords(m_view.upper())); - } - template void Viewport::setFrom (const coords& parFrom) { DK_ASSERT(this->size() + parFrom <= m_tile_info->map_size); @@ -149,4 +109,14 @@ namespace dk { auto Viewport::pixel_offset() const -> coords { return static_cast(m_pixel_offset); } + + template + auto Viewport::upper() const -> const coords& { + return m_view.upper(); + } + + template + auto Viewport::block_position() const -> const coords& { + return m_view.position(); + } } //namespace dk diff --git a/lib/vectorwrapper/include/vectorwrapper/vectorwrapper.hpp b/lib/vectorwrapper/include/vectorwrapper/vectorwrapper.hpp index 77221dd..fee80e2 100644 --- a/lib/vectorwrapper/include/vectorwrapper/vectorwrapper.hpp +++ b/lib/vectorwrapper/include/vectorwrapper/vectorwrapper.hpp @@ -52,6 +52,8 @@ namespace vwr { Vec& assign ( Vec& parLeft, const Vec& parRight ); template Vec& assign_same_type ( Vec& parLeft, const Vec& parRight ); + template + Vec& move_same_type ( Vec& parLeft, Vec&& parRight ); template struct get_offset_enum_from_index; template struct get_offset_enum_from_index { @@ -141,6 +143,7 @@ namespace vwr { template class VecBase { friend Vec& assign_same_type ( Vec& parLeft, const Vec& parRight ); + friend Vec& move_same_type ( Vec& parLeft, Vec&& parRight ); public: typedef V vector_type; typedef typename VectorWrapperInfo::scalar_type scalar_type; @@ -150,6 +153,8 @@ namespace vwr { }; VecBase ( void ) = default; + VecBase ( const VecBase& ) = default; + VecBase ( VecBase&& ) = default; template explicit VecBase ( const T& parInit, typename std::enable_if::value and not std::is_same::value, bool>::type=false ); explicit VecBase ( const vector_type& parInit ); @@ -314,10 +319,13 @@ namespace vwr { dimensions = S }; - template - Vec ( Args... parArgs ) : implem::VecBase(std::forward(parArgs)...) - { - } + Vec ( void ) = default; + Vec ( const Vec& ) = default; + Vec ( Vec&& ) = default; + using implem::VecBase::VecBase; + + Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); } + Vec& operator= ( Vec&& parOther ) { return implem::move_same_type(*this, std::move(parOther)); } }; template @@ -334,12 +342,14 @@ namespace vwr { Vec ( void ) = default; Vec ( const Vec& ) = default; + Vec ( Vec&& ) = default; explicit Vec ( const vector_type& parIn ) : implem::VecBase(parIn) { } template explicit Vec ( const typename std::enable_if::value and not std::is_same::value, T>::type& parX ) : implem::VecBase(parX) { } template Vec ( const Vec& parOther ) { implem::assign(*this, parOther); } Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); } + Vec& operator= ( Vec&& parOther ) { return implem::move_same_type(*this, std::move(parOther)); } template Vec& operator= ( const Vec& parOther ) { return implem::assign(*this, parOther); } }; @@ -360,12 +370,14 @@ namespace vwr { Vec ( void ) = default; Vec ( const Vec& ) = default; + Vec ( Vec&& ) = default; explicit Vec ( const vector_type& parIn ) : implem::VecBase(parIn) { } explicit Vec ( const scalar_type parX ) : implem::VecBase(parX) { } Vec ( scalar_type parX, scalar_type parY ) : implem::VecBase(parX, parY) { } template Vec ( const Vec& parOther ) { implem::assign(*this, parOther); } Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); } + Vec& operator= ( Vec&& parOther ) { return implem::move_same_type(*this, std::move(parOther)); } template Vec& operator= ( const Vec& parOther ) { return implem::assign(*this, parOther); } Vec& operator= ( const vector_type& parOther ) { this->data() = parOther; return *this; } @@ -388,12 +400,14 @@ namespace vwr { Vec ( void ) = default; Vec ( const Vec& ) = default; + Vec ( Vec&& ) = default; explicit Vec ( const vector_type& parIn ) : implem::VecBase(parIn) { } explicit Vec ( const scalar_type parX ) : implem::VecBase(parX) { } Vec ( scalar_type parX, scalar_type parY, scalar_type parZ ) : implem::VecBase(parX, parY, parZ) { } template Vec ( const Vec& parOther ) { implem::assign(*this, parOther); } Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); } + Vec& operator= ( Vec&& parOther ) { return implem::move_same_type(*this, std::move(parOther)); } template Vec& operator= ( const Vec& parOther ) { return implem::assign(*this, parOther); } Vec& operator= ( const vector_type& parOther ) { this->data() = parOther; return *this; } diff --git a/lib/vectorwrapper/include/vectorwrapper/vectorwrapper.inl b/lib/vectorwrapper/include/vectorwrapper/vectorwrapper.inl index 24212f6..a249315 100644 --- a/lib/vectorwrapper/include/vectorwrapper/vectorwrapper.inl +++ b/lib/vectorwrapper/include/vectorwrapper/vectorwrapper.inl @@ -188,6 +188,12 @@ namespace vwr { return parLeft; } + template + Vec& move_same_type (Vec& parLeft, Vec&& parRight) { + parLeft.m_wrapped = std::move(parRight.m_wrapped); + return parLeft; + } + template auto Vec3Demotion::xy() const -> lower_vector_type { auto& this_vec = *static_cast*>(this);