Diligent Engine
Loading...
Searching...
No Matches
Diligent::ObjectsRegistry< KeyType, StrongPtrType, KeyHasher, KeyEqual > Class Template Reference

#include <ObjectsRegistry.hpp>

Public Member Functions

template<typename CreateObjectType>
StrongPtrType Get (const KeyType &Key, CreateObjectType &&CreateObject) noexcept(false)
StrongPtrType Get (const KeyType &Key)
void Purge ()
 Removes all expired pointers from the cache.
template<typename HandlerType>
void ProcessElements (HandlerType &&Handler)
 Processes each element in the cache with the specified handler.
void Clear ()

Detailed Description

template<typename KeyType, typename StrongPtrType, typename KeyHasher = std::hash<KeyType>, typename KeyEqual = std::equal_to<KeyType>>
class Diligent::ObjectsRegistry< KeyType, StrongPtrType, KeyHasher, KeyEqual >

A thread-safe and exception-safe object registry that works with std::shared_ptr or RefCntAutoPtr. The registry keeps weak pointers to the objects and returns strong pointers if the requested object exits. An application should keep strong pointers to the objects to keep them alive.

Usage example for RefCntAutoPtr:

ObjectsRegistry<std::string, RefCntAutoPtr<IObject>> Registry;

auto pObj = Registry.Get("Key",
                         []()
                         {
                             RefCntAutoPtr<IObject> pObj;
                             // Create object
                             return pObj;
                         });

Usage example for shared_ptr:

struct RegistryData
{
    // ...
};
ObjectsRegistry<std::string, std::shared_ptr<RegistryData>> Registry;

auto pObj = Registry.Get("Key",
                         []()
                         {
                             return std::make_shared<RegistryData>();
                         });

If the object is not found in the registry, it is atomically created by the provided initializer function. If the object is found, the initializer function is not called.

It is guaranteed, that the Object will only be initialized once, even if multiple threads call Get() simultaneously. This guarantee does not apply to Get() calls that overlap with Clear(): such calls are safe, but an in-flight Get() may still return an object removed from the cache, and another Get() may initialize a different object for the same key after Clear(). CreateObject may re-enter the registry for independent keys. Recursive creation of the same key, or cyclic creation dependencies between keys, may deadlock because each key is protected by a non-recursive mutex.

Member Function Documentation

◆ Clear()

template<typename KeyType, typename StrongPtrType, typename KeyHasher = std::hash<KeyType>, typename KeyEqual = std::equal_to<KeyType>>
void Diligent::ObjectsRegistry< KeyType, StrongPtrType, KeyHasher, KeyEqual >::Clear ( )
inline

Removes all objects from the cache. This method is safe to call concurrently with Get(), but it does not synchronize with in-flight object creation. The create-once guarantee does not apply to Get() calls that overlap with Clear().

◆ Get() [1/2]

template<typename KeyType, typename StrongPtrType, typename KeyHasher = std::hash<KeyType>, typename KeyEqual = std::equal_to<KeyType>>
StrongPtrType Diligent::ObjectsRegistry< KeyType, StrongPtrType, KeyHasher, KeyEqual >::Get ( const KeyType & Key)
inline

Finds the object in the registry and returns a strong pointer to it (std::shared_ptr or RefCntAutoPtr). If the object is not found, returns empty pointer.

Parameters
[in]Key- The object key.

Strong pointer to the object with the specified key, if the object is found in the registry, or empty pointer otherwise.

◆ Get() [2/2]

template<typename KeyType, typename StrongPtrType, typename KeyHasher = std::hash<KeyType>, typename KeyEqual = std::equal_to<KeyType>>
template<typename CreateObjectType>
StrongPtrType Diligent::ObjectsRegistry< KeyType, StrongPtrType, KeyHasher, KeyEqual >::Get ( const KeyType & Key,
CreateObjectType && CreateObject )
inline

Finds the object in the registry and returns strong pointer to it (std::shared_ptr or RefCntAutoPtr). If the object is not found, it is atomically created using the provided initializer.

Parameters
[in]Key- The object key.
[in]CreateObject- Initializer function that is called if the object is not found in the registry.
Returns
Strong pointer to the object with the specified key, either retrieved from the registry or initialized with the CreateObject function.

CreateObject function may throw in case of an error.

It is guaranteed, that the Object will only be initialized once, even if multiple threads call Get() simultaneously. CreateObject may re-enter the registry for independent keys, but must not recursively request the same key or form a cyclic dependency with another thread creating a different key.