#pragma once

#include <cstdint>
#include <atomic>

namespace extra2d {

class RefCounted {
public:
    RefCounted() : refCount_(0) {}
    virtual ~RefCounted() = default;

    void addRef() const { refCount_.fetch_add(1, std::memory_order_relaxed); }

    void release() const {
        if (refCount_.fetch_sub(1, std::memory_order_acq_rel) == 1) {
            delete this;
        }
    }

    uint32 refCount() const { return refCount_.load(std::memory_order_relaxed); }

protected:
    RefCounted(const RefCounted&) : refCount_(0) {}
    RefCounted& operator=(const RefCounted&) { return *this; }

private:
    mutable std::atomic<uint32> refCount_;
};

} // namespace extra2d
