osb/source/core/StarObserverStream.hpp
Kai Blaschke 431a9c00a5
Fixed a huge amount of Clang warnings
On Linux and macOS, using Clang to compile OpenStarbound produces about 400 MB worth of warnings during the build, making the compiler output unreadable and slowing the build down considerably.

99% of the warnings were unqualified uses of std::move and std::forward, which are now all properly qualified.

Fixed a few other minor warnings about non-virtual destructors and some uses of std::move preventing copy elision on temporary objects.

Most remaining warnings are now unused parameters.
2024-02-19 16:55:19 +01:00

99 lines
2.7 KiB
C++

#ifndef STAR_OBSERVER_STREAM_HPP
#define STAR_OBSERVER_STREAM_HPP
#include "StarList.hpp"
namespace Star {
// Holds a stream of values which separate observers can query and track
// occurrences in the stream without pulling them from the stream. Each
// addition to the stream is given an abstract step value, and queries to the
// stream can reference a given step value in order to track events since the
// last query.
template <typename T>
class ObserverStream {
public:
ObserverStream(uint64_t historyLimit = 0);
// If a history limit is set, then any entries with step values older than
// the given limit will be discarded automatically. A historyLimit of 0
// means that no values will be forgotten. The step value increases by one
// with each entry added, or can be increased artificially by a call to
// tickStep.
uint64_t historyLimit() const;
void setHistoryLimit(uint64_t historyLimit = 0);
// Add a value to the end of the stream and increment the step value by 1.
void add(T value);
// Artificially tick the step by the given delta, which can be used to clear
// older values.
void tick(uint64_t delta = 1);
// Query values in the stream since the given step value. Will return the
// values in the stream, and a new since value to pass to query on the next
// call.
pair<List<T>, uint64_t> query(uint64_t since = 0) const;
// Resets the step value to 0 and clears all values.
void reset();
private:
uint64_t m_historyLimit;
uint64_t m_nextStep;
Deque<pair<uint64_t, T>> m_values;
};
template <typename T>
ObserverStream<T>::ObserverStream(uint64_t historyLimit)
: m_historyLimit(historyLimit), m_nextStep(0) {}
template <typename T>
uint64_t ObserverStream<T>::historyLimit() const {
return m_historyLimit;
}
template <typename T>
void ObserverStream<T>::setHistoryLimit(uint64_t historyLimit) {
m_historyLimit = historyLimit;
tick(0);
}
template <typename T>
void ObserverStream<T>::add(T value) {
m_values.append({m_nextStep, std::move(value)});
tick(1);
}
template <typename T>
void ObserverStream<T>::tick(uint64_t delta) {
m_nextStep += delta;
uint64_t removeBefore = m_nextStep - min(m_nextStep, m_historyLimit);
while (!m_values.empty() && m_values.first().first < removeBefore)
m_values.removeFirst();
}
template <typename T>
pair<List<T>, uint64_t> ObserverStream<T>::query(uint64_t since) const {
List<T> res;
auto i = std::lower_bound(m_values.begin(),
m_values.end(),
since,
[](pair<uint64_t, T> const& p, uint64_t step) { return p.first < step; });
while (i != m_values.end()) {
res.append(i->second);
++i;
}
return {res, m_nextStep};
}
template <typename T>
void ObserverStream<T>::reset() {
m_nextStep = 0;
m_values.clear();
}
}
#endif