Resource (advanced)

shared_resource<T> and weak_resource<T> are the RAII wrappers underlying all micro handle types (window, renderer, texture, image, font). You rarely need to use them directly, but understanding them explains ownership semantics across the library.

shared_resource

A reference-counted owner of an SDL handle. Behaves like a std::shared_ptr<T> with a type-erased custom deleter.

template <typename T>
class shared_resource {
public:
    T*   get()       const noexcept; // raw pointer
    bool is_ready()  const noexcept; // non-null?
    long use_count() const noexcept; // number of owners

    weak_resource<T> weak() const noexcept; // get a non-owning handle
};

All major types inherit from shared_resource:

class window   : public shared_resource<SDL_Window>   { ... };
class renderer : public shared_resource<SDL_Renderer> { ... };
class texture  : public shared_resource<SDL_Texture>  { ... };
class image    : public shared_resource<SDL_Surface>  { ... };

Shared ownership

Copying any resource type shares the underlying handle. The handle is destroyed only when the last owner is gone:

micro::texture a = micro::texture::load_png(rend, "hero.png");
micro::texture b = a;    // both a and b point to the same GPU texture

assert(a.use_count() == 2);

weak_resource

A non-owning reference. Does not extend the lifetime of the resource. Useful for caches or back-references where you want to observe without owning.

template <typename T>
class weak_resource {
public:
    std::shared_ptr<T> lock()  const noexcept; // try to acquire ownership
    bool               valid() const noexcept; // still alive?
};
auto weak = tex.weak();

if (auto ptr = weak.lock()) {
    // resource is still alive, ptr is a shared_ptr<SDL_Texture>
}

The window uses weak_resource internally to track attached input devices, which is why devices are automatically unregistered when destroyed.

Null state

All resource types are default-constructible to a null (empty) state. Check is_ready() before use if the resource may not have been initialized:

micro::texture tex;        // null
assert(!tex.is_ready());

tex = micro::texture::load_png(rend, "hero.png");
assert(tex.is_ready());