diff options
| author | Joel Klinghed <the_jk@yahoo.com> | 2017-09-26 21:58:23 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@yahoo.com> | 2017-09-26 21:58:23 +0200 |
| commit | 811e04305457108bc32d8895fd9bd274715d02fc (patch) | |
| tree | 4bf4e89448ce3be4858404a7ea81c166ab2b8d37 /src/observers.hh | |
| parent | 37e7c66d65e00b9543003aba1f0f9b13a8dc151b (diff) | |
Use a modification safe observers list
Diffstat (limited to 'src/observers.hh')
| -rw-r--r-- | src/observers.hh | 71 |
1 files changed, 71 insertions, 0 deletions
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 <memory> +#include <vector> + +template<typename T> +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<T*> observers_; +}; + +#endif // OBSERVERS_HH |
