#pragma once #include #include //! @brief Base class for all waypoint managers. template class Container /*e.g. QVector*/> class GenericPathSlicer { public: typedef Container ContainerType; GenericPathSlicer(); const ContainerType &path () const; // Waypoint editing. void setPath (const ContainerType &path); void push_back (const ElementType &wp); void push_front (const ElementType &wp); void clear (); void insert (int i, const ElementType &wp); uint32_t size(); ElementType &at (unsigned int i); // Slicing. void slice (ContainerType &slice); void next (ContainerType &slice); void previous (ContainerType &slice); void reset (ContainerType &slice); // Slicing parameters. //! @brief Sets the overlap. //! //! @param overlap The number of overlapping vertices //! between on and the next slice. void setOverlap (uint32_t overlap); //! @brief Sets the number of vertices per slice. //! //! @param N The number of vertices per slice. void setN (std::uint32_t N); //! @brief Sets the start index. //! //! @param idxStart The start index. void setStartIndex (int idxStart); //! @return Returns the overlap. uint32_t overlap (); //! @return Returns the number of vertices per slice N. uint32_t N (); //! @return Returns the start index. int startIndex (); //! @return Returns the end index. int endIndex (); //! @return Returns the start index of the next slice. int nextIndex (); private: void _updateIdx(); ContainerType _path; long _idxStart; long _idxEnd; long _idxNext; long _idxPrevious; uint32_t _overlap; uint32_t _N; bool _idxValid; bool _atEnd; }; template class Container /*e.g. QVector*/> GenericPathSlicer::GenericPathSlicer(): _idxValid(false) , _atEnd(false) {} template class Container /*e.g. QVector*/> const Container &GenericPathSlicer::path() const { return _path; } template class Container /*e.g. QVector*/> void GenericPathSlicer::setPath(const ContainerType &waypoints) { _idxValid = false; _path = waypoints; } template class Container /*e.g. QVector*/> void GenericPathSlicer::push_back(const ElementType &wp) { _idxValid = false; _path.push_back(wp); } template class Container /*e.g. QVector*/> void GenericPathSlicer::push_front(const ElementType &wp) { _idxValid = false; _path.push_front(wp); } template class Container /*e.g. QVector*/> void GenericPathSlicer::clear(){ _idxValid = false; _path.clear(); } template class Container /*e.g. QVector*/> void GenericPathSlicer::insert(int i, const ElementType &wp){ _idxValid = false; _path.insert(i, wp); } template class Container /*e.g. QVector*/> std::uint32_t GenericPathSlicer::size() { return std::uint32_t(_path.size()); } template class Container /*e.g. QVector*/> ElementType &GenericPathSlicer::at(unsigned int i) { return _path.at(i); } template class Container /*e.g. QVector*/> void GenericPathSlicer::setOverlap(std::uint32_t overlap) { _idxValid = false; _overlap = overlap; } template class Container /*e.g. QVector*/> void GenericPathSlicer::setN(uint32_t N) { _idxValid = false; _N = N > 0 ? N : 1; } template class Container /*e.g. QVector*/> void GenericPathSlicer::setStartIndex(int idxStart) { _idxValid = false; _idxStart = idxStart; } template class Container /*e.g. QVector*/> uint32_t GenericPathSlicer::overlap() { return _overlap; } template class Container /*e.g. QVector*/> uint32_t GenericPathSlicer::N() { return _N; } template class Container /*e.g. QVector*/> int GenericPathSlicer::startIndex() { if (!_idxValid) _updateIdx(); return _idxStart; } template class Container /*e.g. QVector*/> int GenericPathSlicer::endIndex() { if (!_idxValid) _updateIdx(); return _idxEnd; } template class Container /*e.g. QVector*/> int GenericPathSlicer::nextIndex() { if (!_idxValid) _updateIdx(); return _idxNext; } template class Container /*e.g. QVector*/> void GenericPathSlicer::_updateIdx() { _idxValid = true; _atEnd = false; std::uint64_t size = _path.size(); if ( _idxStart >= size-1 ) { _idxStart = size-1; _idxEnd = _idxStart; _idxNext = _idxStart; _atEnd = true; return; } _idxStart < 0 ? 0 : _idxStart; _idxEnd = _idxStart + _N - 1; _idxEnd = _idxEnd < size ? _idxEnd : size-1; _idxNext = _idxEnd + 1 - _overlap; _idxNext = _idxNext < 0 ? 0 : _idxNext; _idxNext = _idxNext < size ? _idxNext : size-1; _idxPrevious = _idxStart - 1 + _overlap; _idxPrevious = _idxPrevious < 0 ? 0 : _idxPrevious; _idxPrevious = _idxPrevious < size ? _idxPrevious : size-1; } template class Container /*e.g. QVector*/> void GenericPathSlicer::slice(Container &c){ if ( !_idxValid) _updateIdx(); (void)c; assert(false); //ToDo // extract waypoints } template class Container /*e.g. QVector*/> void GenericPathSlicer::next(Container &c){ setStartIndex(_idxNext); slice(c); } template class Container /*e.g. QVector*/> void GenericPathSlicer::previous(Container &c){ setStartIndex(_idxPrevious); slice(c); } template class Container /*e.g. QVector*/> void GenericPathSlicer::reset(Container &c){ setStartIndex(0); slice(c); }