From 811e04305457108bc32d8895fd9bd274715d02fc Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Tue, 26 Sep 2017 21:58:23 +0200 Subject: Use a modification safe observers list --- src/observers.hh | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/observers.hh (limited to 'src/observers.hh') diff --git a/src/observers.hh b/src/observers.hh new file mode 100644 index 0000000..3e56e6b --- /dev/null +++ b/src/observers.hh @@ -0,0 +1,71 @@ +#ifndef OBSERVERS_HH +#define OBSERVERS_HH + +#include +#include + +template +class Observers { +public: + Observers() + : current_(0), protected_(0), removed_(0) { + } + + void add(T* observer) { + if (!observer) return; + for (auto it = observers_.begin(); it != observers_.end(); ++it) { + if (*it == observer) return; + } + observers_.push_back(observer); + } + + void remove(T* observer) { + if (!observer) return; + size_t index = 0; + for (; index < observers_.size(); ++index) { + if (observers_[index] == observer) { + if (index < protected_) { + observers_[index] = nullptr; + ++removed_; + } else { + observers_.erase(observers_.begin() + index); + } + break; + } + } + } + + T* first() { + if (protected_) return nullptr; + if (observers_.empty()) return nullptr; + protected_ = observers_.size(); + return observers_[current_]; + } + + T* next() { + if (current_ >= protected_) return nullptr; + ++current_; + if (current_ >= protected_) { + if (removed_) { + for (size_t i = protected_; i > 0; --i) { + if (!observers_[i - 1]) { + observers_.erase(observers_.begin() + i - 1); + if (--removed_ == 0) break; + } + } + } + protected_ = current_ = 0; + return nullptr; + } + auto ret = observers_[current_]; + return ret ? ret : next(); + } + +private: + size_t current_; + size_t protected_; + size_t removed_; + std::vector observers_; +}; + +#endif // OBSERVERS_HH -- cgit v1.3