diff --git a/libopenage/tube/datatypes.md b/libopenage/tube/datatypes.md index fdc215c391..feade3a0d4 100644 --- a/libopenage/tube/datatypes.md +++ b/libopenage/tube/datatypes.md @@ -43,7 +43,7 @@ This container is useful for example for unit lists ... Set Container ---------------- -The set container stores items, just as a normal array would. It keeps track of the existence of the items, but does not guarentee any particular ordering (similar to std::unordered_set). +The set container stores items, just as a normal array would. It keeps track of the existence of the items, but does not guarentee any particular ordering (similar to std::unordered_set). This Container is useful for any non-indexed data structures, for example projectiles. Queue Container @@ -55,4 +55,3 @@ This container is useful for example for action queues and buildung queues. TUBE FILES ============ - diff --git a/libopenage/tube/map_filter_iterator.h b/libopenage/tube/map_filter_iterator.h index 49753a0598..139253d306 100644 --- a/libopenage/tube/map_filter_iterator.h +++ b/libopenage/tube/map_filter_iterator.h @@ -10,18 +10,6 @@ namespace openage { namespace tube { -template -class TubeIterator { -public: - virtual val_t &value() = 0; -}; - -template -bool valid(const _T &, const tube_time_t &at); - -template -using _valid_function_t = bool (*)(const _T&, const tube_time_t &); - template base = rhs.base; @@ -91,13 +76,11 @@ class TubeMapFilterIterator : } virtual bool operator ==(const TubeMapFilterIterator &rhs) const { - return rhs.now != std::numeric_limits::infinity() - || this->base == rhs.base; + return this->base == rhs.base; } virtual bool operator !=(const TubeMapFilterIterator &rhs) const { - return rhs.now == std::numeric_limits::infinity() - || this->base != rhs.base; + return this->base != rhs.base; } virtual bool valid(const tube_time_t &time) { @@ -113,11 +96,4 @@ class TubeMapFilterIterator : } }; -template -bool valid(const _T &t, - const tube_time_t& time) { - return existent_from(t) <= time && existent_until(t) > time; -} - - }} // openage::tube diff --git a/libopenage/tube/queue_filter_iterator.h b/libopenage/tube/queue_filter_iterator.h new file mode 100644 index 0000000000..f2b047eaae --- /dev/null +++ b/libopenage/tube/queue_filter_iterator.h @@ -0,0 +1,100 @@ +// Copyright 2017-2017 the openage authors. See copying.md for legal info. + +#pragma once + +#include +#include + +#include "tube.h" + +namespace openage { +namespace tube { + +template +class Queue; + +template +class TubeQueueFilterIterator : + virtual public std::iterator, + public TubeIterator +{ + friend class Queue; +protected: + typedef typename container_t::iterator iterator_t; + iterator_t base; + iterator_t container_end; + + tube_time_t from; + tube_time_t to; + +public: + TubeQueueFilterIterator(const iterator_t &base, + const iterator_t &container_end, + const tube_time_t &from, + const tube_time_t &to) : + base{base}, + container_end{container_end}, + from{from}, + to{to} {} + + TubeQueueFilterIterator(const TubeQueueFilterIterator &rhs) : + base{rhs.base}, + container_end{rhs.container_end}, + from{rhs.from}, + to{rhs.to} {} + + TubeQueueFilterIterator &operator =(const TubeQueueFilterIterator &rhs) { + this->base = rhs.base; + this->container_end = rhs.container_end; + this->from = rhs.from; + this->to = rhs.to; + return *this; + } + + TubeQueueFilterIterator &operator ++() { + do { + ++this->base; + } while (this->base != this->container_end && + (this->base->time() < from || + this->base->time() > to)); + return *this; + } + + //We only want to Iterate forward - so maybe delete this? + //timed_iterator &operator --() + //{ + // --base; + // return *this; + //} + + val_t &operator *() const { + return this->base->value; + } + + val_t *operator ->() const { + return &**this; + } + + virtual bool operator ==(const TubeQueueFilterIterator &rhs) const { + return this->base == rhs.base; + } + + virtual bool operator !=(const TubeQueueFilterIterator &rhs) const { + return this->base != rhs.base; + } + + virtual bool valid() const { + + if (this->base != this->container_end) { + return this->base->time() >= from && this->base->time() < to; + } + return false; + } + + val_t &value() override { + return this->base->value; + } +}; + +}} // openage::tube diff --git a/libopenage/tube/test/test_container.cpp b/libopenage/tube/test/test_container.cpp index c2918b560f..e5b5aca0c6 100644 --- a/libopenage/tube/test/test_container.cpp +++ b/libopenage/tube/test/test_container.cpp @@ -5,8 +5,10 @@ #include "../tube.h" #include "../tube_continuous.h" #include "../tube_discrete.h" +#include "../tube_queue.h" #include +#include namespace openage { namespace tube { @@ -140,6 +142,62 @@ void test_list() { } void test_queue() { + Queue q; + q.insert(0, 1); + q.insert(2, 2); + q.insert(4, 3); + q.insert(10, 4); + q.dump(); + TESTEQUALS(*q.begin(0), 1); + TESTEQUALS(*q.begin(1), 1); + TESTEQUALS(*q.begin(2), 2); + TESTEQUALS(*q.begin(3), 2); + TESTEQUALS(*q.begin(4), 3); + TESTEQUALS(*q.begin(5), 3); + TESTEQUALS(*q.begin(10), 4); + TESTEQUALS(*q.begin(12), 4); + TESTEQUALS(*q.begin(100000), 4); + + { + std::set reference = {1,2,3}; + for (auto it = q.between(0,6); it != q.end(); ++it) { + auto ri = reference.find(it.value()); + if (ri != reference.end()) { + reference.erase(ri); + } + } + TESTEQUALS(reference.empty(), true); + } + { + std::set reference = {2,3,4}; + for (auto it = q.between(1,40); it != q.end(); ++it) { + auto ri = reference.find(it.value()); + if (ri != reference.end()) { + reference.erase(ri); + } + } + TESTEQUALS(reference.empty(), true); + } + { + std::set reference = {}; + for (auto it = q.between(30,40); it != q.end(); ++it) { + auto ri = reference.find(it.value()); + if (ri != reference.end()) { + reference.erase(ri); + } + } + TESTEQUALS(reference.empty(), true); + } + { + std::set reference = {1,2,3,4}; + for (auto it = q.between(0,40); it != q.end(); ++it) { + auto ri = reference.find(it.value()); + if (ri != reference.end()) { + reference.erase(ri); + } + } + TESTEQUALS(reference.empty(), true); + } } diff --git a/libopenage/tube/tube.h b/libopenage/tube/tube.h index b25723621a..71089b2446 100644 --- a/libopenage/tube/tube.h +++ b/libopenage/tube/tube.h @@ -22,4 +22,24 @@ tube_time_t existent_until (const _T &t) { return t.existent_until(); } +template +class TubeIterator { +public: + virtual val_t &value() = 0; +}; + +template +bool valid(const _T &, const tube_time_t &at); + +template +using _valid_function_t = bool (*)(const _T&, const tube_time_t &); + +template +bool valid(const _T &t, + const tube_time_t& time) { + return existent_from(t) <= time && existent_until(t) > time; +} + + + }} // openage::tube diff --git a/libopenage/tube/tube_queue.h b/libopenage/tube/tube_queue.h index 13dab6700e..0b007db82f 100644 --- a/libopenage/tube/tube_queue.h +++ b/libopenage/tube/tube_queue.h @@ -4,27 +4,118 @@ #include "tube.h" -// #include "tube_filter_iterator.h" +#include "queue_filter_iterator.h" #include +#include namespace openage { namespace tube { template class Queue { + struct queue_wrapper { + tube_time_t _time; + _T value; + + queue_wrapper(const tube_time_t &time, const _T &value) : + _time{time}, + value{value} {} + + tube_time_t time() { + return _time; + } + }; public: + typedef typename std::deque container_t; + typedef typename container_t::iterator iterator; // Reading Access - const _T &front(const tube_time_t &) const; -// TODO define the TubeQueueIterator -// tube_filter_iterator<_T, Queue> begin(const tube_time_t &); -// tube_filter_iterator<_T, Queue> end(const tube_time_t &); + const _T &front(const tube_time_t &) const { + return container.front(); + } // Modifying access - void pop(const tube_time_t &); + TubeQueueFilterIterator<_T, Queue<_T>> begin( + const tube_time_t &t = -std::numeric_limits::infinity()) + { + return TubeQueueFilterIterator<_T, Queue<_T>>( + container.begin(), + container.end(), + t, + std::numeric_limits::infinity()); + } + + TubeQueueFilterIterator<_T, Queue<_T>> end( + const tube_time_t &t = std::numeric_limits::infinity()) + { + return TubeQueueFilterIterator<_T, Queue<_T>>(container.end(), + container.end(), + t, + std::numeric_limits::infinity()); + } + + TubeQueueFilterIterator<_T, Queue<_T>> between( + const tube_time_t &begin = std::numeric_limits::infinity(), + const tube_time_t &end = std::numeric_limits::infinity()) + { + auto it = TubeQueueFilterIterator<_T, Queue<_T>>( + container.begin(), + container.end(), + begin, + end); + if (!it.valid()) { + ++it; + } + return it; + } + + TubeQueueFilterIterator<_T, Queue<_T>> erase(const TubeQueueFilterIterator<_T, Queue<_T>> &t) { + auto it = container.erase(t.base); + auto ct = TubeQueueFilterIterator<_T, Queue<_T>>( + it, + container.end(), + t.from, + t.to); + + if (!ct.valid(t.from)) { + ++ct; + } + return ct; + } + + TubeQueueFilterIterator<_T, Queue<_T>> insert(const tube_time_t & time, const _T &e) { + iterator insertion_point = this->container.end(); + for (auto it = this->container.begin(); it != this->container.end(); ++it) { + if (time < it->time()) { + insertion_point = this->container + .insert(it, queue_wrapper(time, e)); + break; + } + } + if (insertion_point == this->container.end()) { + insertion_point = this->container.insert(this->container.end(), + queue_wrapper(time, e)); + } + + auto ct = TubeQueueFilterIterator<_T, Queue<_T>>( + insertion_point, + container.end(), + time, std::numeric_limits::infinity()); + + if (!ct.valid()) { + ++ct; + } + return ct; + } + + void __attribute__((noinline)) dump() { + for (auto i : container) { + std::cout << i.value << " at " << i.time() << std::endl; + } + } private: - std::deque<_T> container; + container_t container; }; }} // openage::tube diff --git a/openage/cabextract/cab.py b/openage/cabextract/cab.py index fa2f3500f5..22a9e2c551 100644 --- a/openage/cabextract/cab.py +++ b/openage/cabextract/cab.py @@ -336,9 +336,7 @@ def read_folder_headers(self, cab): compressed_data_stream, window_bits=window_bits, reset_interval=0) - - folder.plain_stream = StreamSeekBuffer(unseekable_plain_stream) - + folder.plain_stream = StreamSeekBuffer(unseekable_plain_stream) # pylint: disable=redefined-variable-type,locally-enabled else: raise Exception("Unknown compression type %d" % compression_type) diff --git a/openage/testing/main.py b/openage/testing/main.py index 14a7852c11..e8040bd014 100644 --- a/openage/testing/main.py +++ b/openage/testing/main.py @@ -45,6 +45,7 @@ def init_subparser(cli): cli.add_argument("test", nargs='*', help="run this test") +# pylint: disable=too-many-branches def process_args(args, error): """ Processes the given args, detecting errors. """ if not args.run_all_tests and not args.demo and not args.test: