#pragma once
#include <cstddef>
#include <cstdint>
#include <mutex>
#include "renderive/real_time_data/Observation.hpp"
class Renderable_Base;
class Real_Time_Data_Base;
class Real_Time_Data_Binding {
public:
    Real_Time_Data_Binding(const Real_Time_Data_Binding&) = delete;
    Real_Time_Data_Binding& operator=(const Real_Time_Data_Binding&) = delete;
    Real_Time_Data_Binding(Real_Time_Data_Binding&& other) noexcept;
    Real_Time_Data_Binding& operator=(Real_Time_Data_Binding&&) = delete;
    ~Real_Time_Data_Binding();
private:
    friend class Real_Time_Data_Base;
    Real_Time_Data_Binding(Renderable_Base& renderable, Real_Time_Data_Base& data);
    Renderable_Base* renderable_{};
    Real_Time_Data_Base* data_{};
};
class Real_Time_Data_Base {
public:
    virtual ~Real_Time_Data_Base() = default;
    virtual Real_Time_Data_Retention retention() const noexcept = 0;
    virtual Real_Time_Data_Update_State update_state() const = 0;
    virtual std::size_t discard_before_time_ns(std::uint64_t time_ns) = 0;
protected:
    [[nodiscard]] Real_Time_Data_Binding bind_renderable(Renderable_Base& renderable);
private:
    friend class Real_Time_Data_Binding;
    friend class Renderable_Base;
    void unbind_renderable(Renderable_Base& renderable) noexcept;
    virtual void publish_render_state() = 0;
    std::mutex binding_mutex_;
    Renderable_Base* bound_renderable_{};
};
