#pragma once
template <class Value_Type, Mutex_Type Mutex, class Observer>
Latest_Real_Time_Data<Value_Type, Mutex, Observer>::Latest_Real_Time_Data(Observer observer)
    : observer_(std::move(observer)), render_state_(&states_[0]), cache_state_(&states_[1]), scratch_state_(&states_[2]) {}
template <class Value_Type, Mutex_Type Mutex, class Observer>
void Latest_Real_Time_Data<Value_Type, Mutex, Observer>::update(Value value) {
    std::lock_guard mutation_lock(mutation_mutex_);
    Real_Time_Data_Observation observation;
    {
        std::lock_guard<Mutex> lock(mutex_);
        *cache_state_ = std::move(value);
        ++revision_;
        ++total_update_count_;
        last_update_time_ns_ = observer_.now_ns();
        observation = {Real_Time_Data_Observation_Event::updated, {this, Real_Time_Data_Retention::latest, revision_, last_update_time_ns_, total_update_count_, 1}};
    }
    observer_.observe(observation);
}
template <class Value_Type, Mutex_Type Mutex, class Observer>
auto Latest_Real_Time_Data<Value_Type, Mutex, Observer>::snapshot() const -> std::optional<Value> {
    std::lock_guard<Mutex> lock(mutex_);
    return *cache_state_;
}
template <class Value_Type, Mutex_Type Mutex, class Observer>
bool Latest_Real_Time_Data<Value_Type, Mutex, Observer>::has_value() const {
    std::lock_guard<Mutex> lock(mutex_);
    return cache_state_->has_value();
}
template <class Value_Type, Mutex_Type Mutex, class Observer>
std::uint64_t Latest_Real_Time_Data<Value_Type, Mutex, Observer>::revision() const {
    std::lock_guard<Mutex> lock(mutex_);
    return revision_;
}
template <class Value_Type, Mutex_Type Mutex, class Observer>
Real_Time_Data_Update_State Latest_Real_Time_Data<Value_Type, Mutex, Observer>::update_state() const {
    std::lock_guard<Mutex> lock(mutex_);
    return {this, Real_Time_Data_Retention::latest, revision_, last_update_time_ns_, total_update_count_, *cache_state_ ? 1U : 0U};
}
template <class Value_Type, Mutex_Type Mutex, class Observer>
void Latest_Real_Time_Data<Value_Type, Mutex, Observer>::publish_render_state() {
    std::lock_guard<Mutex> lock(mutex_);
    if (render_revision_ == revision_)
        return;
    *scratch_state_ = *cache_state_;
    std::swap(render_state_, scratch_state_);
    render_revision_ = revision_;
}
template <class Value_Type, Mutex_Type Mutex, class Observer>
auto Latest_Real_Time_Data<Value_Type, Mutex, Observer>::render_state_value() const noexcept
    -> const std::optional<Value>& {
    return *render_state_;
}

template <class Value_Type, Mutex_Type Mutex, class Observer>
Real_Time_Data_Retention Latest_Real_Time_Data<Value_Type, Mutex, Observer>::retention() const noexcept {
    return Real_Time_Data_Retention::latest;
}
template <class Value_Type, Mutex_Type Mutex, class Observer>
std::size_t Latest_Real_Time_Data<Value_Type, Mutex, Observer>::discard_before_time_ns(std::uint64_t) {
    return 0;
}
