44#ifndef STEAM_ENGINE_BUFFR_METADATA_H
45#define STEAM_ENGINE_BUFFR_METADATA_H
58#include <unordered_map>
121 template<
typename VAL>
125 boost::hash_combine (accumulatedHash, changedValue);
126 return accumulatedHash;
169 Key (
Key const& parent,
size_t differingStorageSize)
217 throw error::Logic{
"Implementation defined local key should not be overridden. "
218 "Underlying buffer type already defines a nontrivial LocalTag"};
219 newKey.
parent_ = HashVal(parent);
220 newKey.hashID_ = chainedHash(newKey.hashID_,
localTag);
225 newKey.parent_ = HashVal(parent);
226 newKey.hashID_ = chainedHash(newKey.hashID_, bufferAddr);
234 if (nontrivial(this->instanceFunc_))
235 throw error::Logic (
"unable to supersede an already attached TypeHandler"
271 ,
Buff* bufferPtr =
nullptr
335 if (newState ==
FREE)
343 throw error::Fatal (
"Invalid buffer state transition.");
394 throw error::Fatal (
"Buffer metadata entry with state==NIL encountered."
395 "State transition logic broken (programming error)"
403 throw error::Logic (
"Buffer is inaccessible (marked as free). "
404 "Need a new buffer pointer in order to lock an entry. "
405 "You should invoke markLocked(buffer) prior to access."
415 REQUIRE (!
buffer_,
"Buffer marked as free, "
416 "but buffer pointer is set.");
423 throw error::Fatal (
"Need concrete buffer for any further operations");
454 MetadataStore::iterator pos =
entries_.find (hashID);
456 return &(pos->second);
464 MetadataStore::const_iterator pos =
entries_.find (hashID);
466 return &(pos->second);
482 REQUIRE (!
fetch (newEntry),
"duplicate buffer metadata entry");
483 MetadataStore::iterator pos =
entries_.emplace (HashVal(newEntry), newEntry)
494 ENSURE (cnt,
"entry to remove didn't exist");
509 WARN_IF (e.second.isLocked(), engine,
510 "Buffer still in use while shutting down BufferProvider? ");
556 :
id_(implementationID)
575 REQUIRE (storageSize);
578 if (nontrivial(instanceFunc))
579 typeKey =
trackKey (typeKey, instanceFunc);
581 if (nontrivial(specifics))
582 typeKey =
trackKey (typeKey, specifics);
591 return trackKey (parentKey, instanceFunc);
599 return trackKey (parentKey, specifics);
612 return existing? *existing
613 :
markLocked (parentKey,concreteBuffer,specifics);
644 ,
bool onlyNew =
false)
648 ,
LERR_(BOTTOM_VALUE)};
650 Entry newEntry{parentKey, concreteBuffer, specifics};
653 if (existing and onlyNew)
654 throw error::Logic{
"Attempt to lock a slot for a new buffer, "
655 "while actually the old buffer is still locked"
657 if (existing and existing->
isLocked())
658 throw error::Logic{
"Attempt to re-lock a buffer still in use"
664 return existing->
lock (concreteBuffer);
680 throw error::Invalid (
"Attempt to access an unknown buffer metadata entry");
696 and entry->isLocked();
717 throw error::Fatal{
"Attempt to lock for a NULL buffer. Allocation floundered?"
718 ,
LERR_(BOTTOM_VALUE)};
720 return this->
lock (parentKey, buffer, specifics,
true);
732 ASSERT (entry and (
key == HashVal(*entry)));
739 if (
FREE != entry.state())
740 throw error::Logic{
"Attempt to release a buffer still in use"
750 template<
typename PAR,
typename DEF>
754 Key newKey{parent, specialisation};
782 ENSURE (newEntry.
access());
A marker data type used in metadata / buffer management of the render engine.
Derived specific exceptions within Lumiera's exception hierarchy.
placeholder type for the contents of a data buffer.
an opaque mark to be used by the BufferProvider implementation.
static const LocalTag UNKNOWN
Marker when no distinct local key is given.
A complete metadata Entry, based on a Key.
void __must_not_be_FREE() const
bool isTypeKey() const
is this Entry just an (abstract) placeholder for a type?
void invokeEmbeddedCtor()
BufferState state() const
Entry & mark(BufferState newState)
Buffer state machine.
bool isLocked() const
is this Entry currently associated to a concrete buffer? Is this buffer in use?
void __must_not_be_NIL() const
void invokeEmbeddedDtor_and_clear()
Entry(Key const &parent, Buff *bufferPtr=nullptr, LocalTag const &specialTag=LocalTag::UNKNOWN)
Entry & invalidate(bool invokeDtor=true)
void __must_be_FREE() const
void __buffer_required() const
Entry & lock(Buff *newBuffer)
Any copy and copy construction prohibited.
Lumiera error handling (C++ interface).
#define ERROR_LOG_AND_IGNORE(_FLAG_, _OP_DESCR_)
convenience shortcut for a sequence of catch blocks just logging and consuming an error.
Hash value types and utilities.
This header is for including and configuring NoBug.
size_t HashVal
a STL compatible hash value
LumieraError< LERR_(FATAL), Logic > Fatal
LumieraError< LERR_(LOGIC)> Logic
LumieraError< LERR_(INVALID)> Invalid
BufferState
Buffer states usable within BufferProvider and stored within the metadata.
@ BLOCKED
allocated buffer blocked by protocol failure
@ NIL
abstract entry, not yet allocated
@ LOCKED
allocated buffer actively in use
@ FREE
allocated buffer, no longer in use
@ EMITTED
allocated buffer, returned from client
Steam-Layer implementation namespace root.
disable_if< can_IterForEach< Container >, FUN > for_each(Container const &coll, FUN doIt)
operate on all elements of a STL container.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Framework for classification of media streams.
A pair of functors to maintain a datastructure within a buffer.
DoInBuffer destroyAttached
DoInBuffer createAttached
static const TypeHandler RAW
Marker for the default case: raw buffer without type handling.
Marker types to indicate a literal string and a Symbol.
Helper holding a pair of type-build-up and destruction functors.
Perform operations "for each element" of a collection.