BufferProvider: rearrange types to prepare for a BufferStage interface

...still in pursuit of the plan to split the implementation
of the `BufferProvider` in a ''state tracking'' part and a
''storage managment'' part...
This commit is contained in:
Fischlurch 2026-02-14 16:55:06 +01:00
parent 9b66818bda
commit 5518030a7d
8 changed files with 89 additions and 29 deletions

View file

@ -80,8 +80,6 @@ namespace engine {
class Store
: public BufferStore
{
protected:
using Buff = BufferProvider::Buff;
};

View file

@ -147,9 +147,8 @@ namespace engine {
void
BufferProvider::emitBuffer (BuffHandle const& handle)
{
metadata::Entry& metaEntry = bufferStage_->get (handle.entryID());
size_t buffSiz = metaEntry.storageSize();
bufferStore_->mark_emitted (buffSiz, metaEntry.parentKey(), metaEntry.localTag());
metadata::Entry& metaEntry = bufferStage_->get (handle);
bufferStore_->mark_emitted (metaEntry.storageSize(), metaEntry.parentKey(), metaEntry.localTag());
metaEntry.mark(EMITTED);
}
@ -165,7 +164,7 @@ namespace engine {
void
BufferProvider::releaseBuffer (BuffHandle const& handle)
try {
metadata::Entry& metaEntry = bufferStage_->get (handle.entryID());
metadata::Entry& metaEntry = bufferStage_->get (handle);
size_t buffSiz = metaEntry.storageSize();
metaEntry.mark(FREE); // might invoke embedded dtor function
bufferStore_->detachBuffer (buffSiz, metaEntry.parentKey()
@ -183,13 +182,13 @@ namespace engine {
* @note EX_FREE
*/
void
BufferProvider::emergencyCleanup (BuffHandle const& target, bool invokeDtor)
BufferProvider::emergencyCleanup (BuffHandle const& handle, bool invokeDtor)
try {
metadata::Entry& metaEntry = bufferStage_->get (target.entryID());
metadata::Entry& metaEntry = bufferStage_->get (handle);
size_t buffSiz = metaEntry.storageSize();
metaEntry.invalidate (invokeDtor);
bufferStore_->detachBuffer (buffSiz, metaEntry.parentKey()
,std::make_tuple (target.rawStorage(), metaEntry.localTag()));
,std::make_tuple (handle.rawStorage(), metaEntry.localTag()));
bufferStage_->release (metaEntry);
}
ERROR_LOG_AND_IGNORE (engine, "cleanup of buffer metadata while handling an error")
@ -217,7 +216,7 @@ namespace engine {
size_t
BuffDescr::determineBufferSize() const
BuffDescr::buffSize() const
{
ENSURE (provider_);
return provider_->getBufferSize (*this);

View file

@ -121,8 +121,10 @@ namespace engine {
using std::unique_ptr;
using std::forward;
class BufferMetadata;
namespace metadata {
class Key;
}
LUMIERA_ERROR_DECLARE (BUFFER_MANAGEMENT); ///< Problem providing working buffers
@ -177,15 +179,14 @@ namespace engine {
size_t getBufferSize (HashVal typeID) const;
protected:
/// placeholder marker type for an actual data buffer
using Buff = StreamType::ImplFacade::DataBuffer;
bool was_created_by_this_provider (BuffDescr const&) const;
class BufferStage
: public BufferMetadata /////////////////////////////////////////////////////////////////////TICKET #1410 : mix-in exiting old implementation -- for sake of refactoring only!
{
protected:
using Key = metadata::Key;
public:
virtual ~BufferStage() { } ///< this is an interface
@ -196,6 +197,7 @@ namespace engine {
: util::NonCopyable
{
protected:
using Buff = StreamType::ImplFacade::DataBuffer; ///< marker type for an actual data buffer
using Slot = std::tuple<Buff*,LocalTag>;
public:
virtual ~BufferStore() { } ///< this is an interface

View file

@ -92,7 +92,7 @@ namespace engine {
// using standard copy operations
bool verifyValidity() const;
size_t determineBufferSize() const;
size_t buffSize() const;
operator HashVal() const { return subClassification_; }
@ -117,13 +117,11 @@ namespace engine {
public:
using PBuff = Buff*;
/** @internal a buffer handle may be obtained by "locking"
* a buffer from the corresponding BufferProvider */
BuffHandle(BuffDescr const& typeInfo, void* storage = 0)
: descriptor_(typeInfo)
, pBuffer_(static_cast<PBuff>(storage))
, pBuffer_(static_cast<Buff*>(storage))
{ }
// using standard copy operations
@ -157,16 +155,10 @@ namespace engine {
and descriptor_.verifyValidity();
}
HashVal
entryID() const ///////////////////////TICKET 1410 : why can't we just expose operator HashVal() ??
{
return HashVal(descriptor_);
}
size_t
size() const
{
return descriptor_.determineBufferSize();
return descriptor_.buffSize();
}
private:

View file

@ -12,7 +12,7 @@
*/
/** @file heap-mem-provider.hpp
** Dummy implementation engine::BufferProvider storage, for sake of conceptual
** Dummy engine::BufferProvider storage implementation, for sake of conceptual
** demonstration and unit testing. This BufferProvider implementation is notably straight forward,
** if not outright silly: it happily claims more and more heap blocks and never releases any memory
** dynamically. This both demonstrates the simplest possible implementation of storage handling, and

View file

@ -31,6 +31,7 @@
#include "lib/error.hpp"
#include "steam/engine/buffer-provider-setup.hpp"
#include "steam/engine/heap-mem-buffer-store.hpp"
#include "steam/engine/simple-buffer-state-registry.hpp"
#include <memory>
@ -58,7 +59,7 @@ namespace engine {
: BufferProviderSetup{*this}
{ }
auto buildStage() { return std::make_unique<Stage> ("Naive_HeapAllocated"); }
auto buildStage() { return std::make_unique<SimpleBufferStateRegistry> ("Naive_HeapAllocated"); }
auto buildStore() { return std::make_unique<HeapMemBufferStore>(); } /////////////////////////////////TICKET #1410 : turn into a subclass of BufferSetup::Store and push down implementation
};

View file

@ -0,0 +1,67 @@
/*
SIMPLE-BUFFER-STATE-REGISTRY.hpp - naively tracking buffer states in a central hash table
Copyright (C)
2026 Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
*/
/** @file simple-buffer-state-registry.hpp
** Demo implementation of engine::BufferProvider state coordination, suitable for unit tests.
** Based on a shared metadata table, accessed directly, disregarding concurrency.
**
** @see buffer-provider.hpp
** @see buffer-provider-protocol-test.cpp
** @see naive-buffer-setup.hpp
*/
#ifndef STEAM_ENGINE_SIMPLE_BUFFER_STATE_REGISTRY_H
#define STEAM_ENGINE_SIMPLE_BUFFER_STATE_REGISTRY_H
#include "lib/error.hpp"
//#include "lib/hash-value.h"
#include "steam/engine/buffer-provider-setup.hpp"
#include "steam/engine/buffer-metadata.hpp"
#include <memory>
namespace steam {
namespace engine {
namespace error = lumiera::error;
// using std::unique_ptr;
// using lib::HashVal;
/**
* Simple Buffer type and state tracking registry, for test and demonstration.
* Relies on a central hashtable, without considering any concurrency concerns.
*/
class SimpleBufferStateRegistry
: public BufferProviderSetup::Stage
{
///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 1410 : rather hold BufferMetatdata object here
public:
/* === BufferStage interface === */
public:
SimpleBufferStateRegistry (Literal implementationID)
: BufferProviderSetup::Stage{implementationID} //////////////////////////////////////////////////TICKET 1410 : rather init BufferMetatdata
{ }
private:
};
}} // namespace steam::engine
#endif /*STEAM_ENGINE_SIMPLE_BUFFER_STATE_REGISTRY_H*/

View file

@ -50,6 +50,7 @@ namespace play {
//using std::string;
using lib::Symbol;
using lib::HashVal;
using util::unConst;
using util::contains;
using lib::time::FrameRate;
@ -106,7 +107,7 @@ namespace play {
trackFrame (FrameID frameNr, BuffHandle const& newBuffer)
{
TRACE (test, "Con=%p : track buffer %zu for frame-#%lu"
, this, newBuffer.entryID(), frameNr);
, this, HashVal(newBuffer), frameNr);
REQUIRE (!contains (frameTrackingIndex_,frameNr),
"attempt to lock already used frame %lu", frameNr);
@ -154,7 +155,7 @@ namespace play {
transfer (BuffHandle const& filledBuffer)
{
TRACE (test, "Con=%p : transfer buffer %zu"
, this, filledBuffer.entryID());
, this, HashVal(filledBuffer));
REQUIRE (!closed_);
pushout (filledBuffer);