rework
This commit is contained in:
32 files changed
+75060
-630
No files matched your search
@@ -0,0 +1,79 @@
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
namespace autoopt {
|
||||
|
||||
template <typename T>
|
||||
struct source {
|
||||
T _value;
|
||||
std::uint64_t _version = 0;
|
||||
|
||||
source() = default;
|
||||
explicit source(T value) : _value(std::move(value)) {}
|
||||
|
||||
virtual T& get() { return _value; };
|
||||
|
||||
bool set(T value) {
|
||||
if (value == _value) return false;
|
||||
_value = std::move(value);
|
||||
++_version;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename O, typename... Is>
|
||||
struct transform : source<O> {
|
||||
std::function<O(Is&...)> _func;
|
||||
std::tuple<source<Is>&...> _sources;
|
||||
std::array<std::uint64_t, sizeof...(Is)> _versions{};
|
||||
|
||||
transform(std::function<O(Is&...)> func, source<Is>&... sources)
|
||||
: _func(func), _sources(sources...) {
|
||||
this->_value = std::apply([&](source<Is>&... sources) {
|
||||
return _func(sources.get()...);
|
||||
}, _sources);
|
||||
this->_versions = current_versions();
|
||||
}
|
||||
|
||||
virtual O& get() override {
|
||||
auto cur_versions = current_versions();
|
||||
if (_versions == cur_versions) return this->_value;
|
||||
|
||||
O next = std::apply([&](source<Is>&... sources) {
|
||||
return _func(sources.get()...);
|
||||
}, _sources);
|
||||
|
||||
if (next != this->_value) {
|
||||
this->_value = next;
|
||||
++this->_version;
|
||||
}
|
||||
return this->_value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<std::uint64_t, sizeof...(Is)> current_versions() {
|
||||
return std::apply([&](source<Is>&... sources){
|
||||
|
||||
return std::array<std::uint64_t, sizeof...(Is)>{sources._version...};
|
||||
}, _sources);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct sink {
|
||||
source<T>& _upstream;
|
||||
std::uint64_t _version;
|
||||
std::function<void(T&)> _cb;
|
||||
|
||||
void maybe_update() {
|
||||
if (_version != _upstream._version) {
|
||||
_cb(_upstream.get());
|
||||
_version = _upstream._version;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace autoopt
|
||||
Reference in new issue
Block a user