Magnum::Ui::AbstractStorage class new in Git master

Base for DataLayer storage implementations.

Types derived from this class are used as non-owning proxies that allocate arbitrarily typed storage memory in DataLayer and maintain access to it.

As this class is just a proxy with the storage being elsewhere, subclasses are expected to be trivially copyable without any additional member variables — all state is meant to be placed in the storage memory itself.

Public types

enum (anonymous): std::size_t { MaxInPlaceSize = Implementation::DataLayerStorageMaxInPlaceSize }

Constructors, destructors, conversion operators

operator StorageHandle() const
Storage handle.
AbstractStorage(DataLayer& layer, StorageFlags flags = {}) protected explicit
Create a single-item storage.
AbstractStorage(DataLayer& layer, std::size_t size, StorageFlags flags = {}) protected explicit
Create a 1D storage.
AbstractStorage(DataLayer& layer, const Containers::Size2D& size, StorageFlags flags = {}) protected explicit
Create a 2D storage.
AbstractStorage(DataLayer& layer, const Containers::Size3D& size, StorageFlags flags = {}) protected explicit
Create a 3D storage.

Public functions

auto layer() const -> DataLayer&
Data layer reference.
auto handle() const -> StorageHandle
Storage handle.
auto isAllocated() const -> bool
Whether the storage is allocated.
auto isDirty() const -> bool
Whether the storage is dirty.
void setDirty() const
Mark the storage as dirty.
auto flags() const -> StorageFlags
Storage flags.
auto size() const -> Containers::Size3D
Storage size.
auto referenceCount() const -> std::size_t
Storage reference count.

Protected functions

template<class T>
auto createInPlace() -> T*
Create a storage in-place.
void createAllocated(void* data, std::size_t size, void(*)(void*, std::size_t) deleter)
Create an allocated storage.
template<class T>
auto data() const -> T*
Storage data.

Enum documentation

enum Magnum::Ui::AbstractStorage::(anonymous): std::size_t

Enumerators
MaxInPlaceSize

Maximal size that can be stored in-place. Storages larger than this size have to be allocated. See createInPlace() and createAllocated() for more information.

Function documentation

Magnum::Ui::AbstractStorage::operator StorageHandle() const

Storage handle.

Same as handle().

Magnum::Ui::AbstractStorage::AbstractStorage(DataLayer& layer, StorageFlags flags = {}) explicit protected

Create a single-item storage.

Parameters
layer Data layer reference
flags Storage flags

Equivalent to calling AbstractStorage(DataLayer&, const Containers::Size3D&, StorageFlags) with size being {1, 1, 1}. See its documentation for a detailed description of all constraints.

Magnum::Ui::AbstractStorage::AbstractStorage(DataLayer& layer, std::size_t size, StorageFlags flags = {}) explicit protected

Create a 1D storage.

Parameters
layer Data layer reference
size Storage size
flags Storage flags

Equivalent to calling AbstractStorage(DataLayer&, const Containers::Size3D&, StorageFlags) with size being {1, 1, size}. See its documentation for a detailed description of all constraints.

Magnum::Ui::AbstractStorage::AbstractStorage(DataLayer& layer, const Containers::Size2D& size, StorageFlags flags = {}) explicit protected

Create a 2D storage.

Parameters
layer Data layer reference
size Storage size
flags Storage flags

Equivalent to calling AbstractStorage(DataLayer&, const Containers::Size3D&, StorageFlags) with size being {1, size[0], size[1]}. See its documentation for a detailed description of all constraints.

Magnum::Ui::AbstractStorage::AbstractStorage(DataLayer& layer, const Containers::Size3D& size, StorageFlags flags = {}) explicit protected

Create a 3D storage.

Parameters
layer Data layer reference
size Storage size
flags Storage flags

Allocates a new StorageHandle in a free slot in the internal DataLayer storage storage or grows the storage if there's no free slots left. Expects that there's at most 1048576 storages. The AbstractStorage instance doesn't own the storage on and thus doesn't remove it on destruction, instead either the handle() can be removed again with DataLayer::remove() or can be marked as StorageFlag::ReferenceCounted, which causes it to be removed at the next AbstractUserInterface::update() or draw() if its referenceCount() is zero.

The size is expected to not be 0 in any dimension and its product to be less or equal to 1ull << 43. The subclass is meant to subsequently call createInPlace() or createAllocated() to actually initialize the storage. Calling neither is equivalent to calling createInPlace() and not initializing the memory it returns in any way. If StorageFlag::ReferenceCounted is present in flags, the storage has to get used by at least one data before the next call to AbstractUserInterface::update() to prevent it from being removed again.

Upon creation, isDirty() const returns false. Including StorageFlag::ReferenceCounted in flags causes LayerState::NeedsCommonDataUpdate to be set on the layer, otherwise no state flags are set.

StorageHandle Magnum::Ui::AbstractStorage::handle() const

Storage handle.

Guaranteed to be associated with layer() and never StorageHandle::Null.

bool Magnum::Ui::AbstractStorage::isAllocated() const

Whether the storage is allocated.

Same as calling DataLayer::isStorageAllocated() with handle(), see its documentation for more information.

bool Magnum::Ui::AbstractStorage::isDirty() const

Whether the storage is dirty.

Same as calling DataLayer::isStorageDirty() with handle(), see its documentation for more information.

void Magnum::Ui::AbstractStorage::setDirty() const

Mark the storage as dirty.

Same as calling DataLayer::setStorageDirty() with handle(), see its documentation for more information.

StorageFlags Magnum::Ui::AbstractStorage::flags() const

Storage flags.

Same as calling DataLayer::storageFlags() with handle(), see its documentation for more information.

Containers::Size3D Magnum::Ui::AbstractStorage::size() const

Storage size.

Same as calling DataLayer::storageSize() with handle(), see its documentation for more information.

std::size_t Magnum::Ui::AbstractStorage::referenceCount() const

Storage reference count.

Same as calling DataLayer::storageReferenceCount() with handle(), see its documentation for more information.

template<class T>
T* Magnum::Ui::AbstractStorage::createInPlace() protected

Create a storage in-place.

Contrary to what Doxygen shows, returns reference to a one-dimensional fixed-size array of elements, i.e. T(&)[MaxInPlaceSize/sizeof(T)]. There the caller is expected to initialize a storage of a size specified in the AbstractStorage() constructor. Expects that T is a trivially copyable type not larger than MaxInPlaceSize and with alignment of at most 8. If it's larger, overaligned or not trivial, use createAllocated() instead. If the in-place storage can stay being uninitialized memory, this function doesn't need to be called at all.

void Magnum::Ui::AbstractStorage::createAllocated(void* data, std::size_t size, void(*)(void*, std::size_t) deleter) protected

Create an allocated storage.

Parameters
data Pointer to the allocated data
size Size of the allocated data in bytes
deleter Deleter

When the storage is removed, deleter gets called with data and size passed to it. The data and deleter are expected to not be nullptr, size can be zero if the deleter doesn't require it. If the type is trivially copyable, aligned to at most 8 bytes and not larger than MaxInPlaceSize, you can store it in place using createInPlace() and avoid the allocation. It's not a requirement however.

template<class T>
T* Magnum::Ui::AbstractStorage::data() const protected

Storage data.

Returns a pointer to either the storage passed to createAllocated() or to the in-place storage returned by createInPlace(). It's the subclass responsibility to ensure T matches the actually stored type.

In order to have updates properly reflected to all data referencing the storage, the subclass implementation should call setDirty() if it modifies anything in the storage. There's no way for the AbstractStorage implementation to detect this on its own, especially considering the storage may be just a view on memory managed elsewhere.