Registry
Generated from engine/core/registry.h at 862e08b. The text under each declaration is the header's own comment, word for word. About the reference says how these pages are made.
#include "engine/core/registry.h" · namespace labrador
struct RegistryStorage
Section titled “struct RegistryStorage”How a resource is reached through the smart pointer that owns it. The primary template covers everything spelling it get() - unique_ptr, shared_ptr - and COM's ComPtr spells it Get(), so the D3D-facing code specialises this where COM is already in scope rather than dragging <wrl/client.h> in here.
pointer
Section titled “pointer”static auto pointer(const Storage& storage);class Registry
Section titled “class Registry”A store of named resources, and one lookup contract for every kind of resource: whichever way you ask, you get something live or a throw naming what was missing. It never returns nullptr and never inserts on a miss, so a misspelt name fails where it is written rather than null-dereferencing a frame later somewhere else.
There are two ways to ask, and the difference between them is the point:
resolve(name) -> Handle once, at loadget(handle) -> Resource* per frame - no string, no map, no comparePer-frame code touches no string-keyed map (PHILOSOPHY T7, T8), so per-frame code never sees a name. get(name) remains for load-time callers that have one and want the resource immediately.
A name owns its slot for the registry's lifetime. Releasing a resource - what a device loss does to textures and fonts - empties the slot but keeps the mapping, so a handle resolved before the loss still names the right resource once the reload refills it. That is the whole reason a handle is a slot index and not a pointer: the pointer changes across a device restore and the slot does not.
The registry holds names, not meanings. What a name refers to is the caller's business - which is what lets a game keep its own resource types in one of these without the engine having to learn their vocabulary.
handle
Section titled “handle”Registry
Section titled “Registry”kind names the resource type in error messages: "Texture", "SpriteFont". It is stored, not copied, so it must outlive the registry - pass a literal.
void add(const std::string& name, Storage resource);Fills the name's slot, claiming one if the name is new. Re-adding a name reuses its slot rather than appending, which is what keeps handles valid across a reload.
resolve
Section titled “resolve”handle resolve(const std::string& name) const;The load-time half. Throws std::out_of_range if nothing ever added the name: resolving a name no loader produced is a content bug, and this is the line that should report it.
Resolving is deliberately separate from reading, so a name can be turned into a handle once and the handle kept for the object's lifetime.
Resource* get(handle resource_handle) const;The per-frame half: a bounds check and an indexed load. Never returns nullptr - an unresolved handle, or one whose slot has been released, throws instead.
Resource* get(const std::string& name) const;contains
Section titled “contains”bool contains(const std::string& name) const;True only if the name is loaded now. A name whose slot has been released reads as absent, because a released resource is indistinguishable from a loaded one at every call site that only checks for presence.
release_all
Section titled “release_all”void release_all();Empties every slot and keeps every name, so handles survive the round trip through a device loss. Until the reload refills them, get() on any of these throws saying the resource was released - which is the honest answer and the one that names itself (T6).
Related types
Section titled “Related types”Named in the public declarations above: Handle.
In the samples and tests
Section titled “In the samples and tests”The files that include this header directly. A file can also reach it through another header.
tests/core/registry_tests.cpp
Development documentation (unreleased). Built from Labrador 862e08b of 2026-10-08.