/* OUTPUT-BUFFER-PROXY.hpp - Adaptor to access existing allocation via buffer handling protocol Copyright (C) 2026 Hermann Vosseler   **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 output-buffer-proxy.hpp ** Adapter to expose some buffer memory through a BuffHandle as front-end. ** This implementation building-block allows to integrate the output buffers ** managed by a specific output mechanism with the generic implementation of ** OutputSlote, so that only a BuffHandle needs to be exposed to the client. ** @see output-proxy-provider-test.cpp ** @see output-buffer-proxy.hpp ** @see output-slot.hpp */ #ifndef VAULT_OUT_OUTPUT_BUFFER_PROXY_H #define VAULT_OUT_OUTPUT_BUFFER_PROXY_H #include "lib/error.hpp" #include "lib/nocopy.hpp" #include "lib/symbol.hpp" #include "lib/meta/util.hpp" #include "vault/mem/buffer-provider.hpp" #include "vault/mem/buffer-provider-setup.hpp" #include "vault/mem/heap-mem-buffer-store.hpp" #include "vault/mem/simple-buffer-state-registry.hpp" #include #include namespace vault{ namespace out { using std::move; using lib::Literal; using lib::HashVal; using vault::mem::Buff; using vault::mem::LocalTag; using vault::mem::BuffAlloc; using vault::mem::BuffDescr; using vault::mem::BuffHandle; using vault::mem::TypeHandler; ///////////////////////////OOO Rly? using vault::mem::BufferProviderSetup; /** * Adapter to expose controlled access to some memory resource * through a [»Buffer Type«](\ref BuffDescr) and a BuffHandle as front-end, * in accordance with the BufferProvider protocol. * * This template is an implementation building block and needs to be instantiated * with a policy or configuration to define the flexible parts of the behaviour * - what a Buffer Type means * - is there only one resource or is this setup statefull? * - callback functors for the lifecycle stages related to the client's access * @todo 3/2026 this is prototyping code and was retained for demonstration purposes. */ template class OutputBufferProxy : util::NonCopyable { class ProxyBufferStore : public BufferProviderSetup::Store , private CONF { Buff* asBuffer (LocalTag targetMarker) { void* buffMem{targetMarker}; return static_cast (buffMem); } uint prepareBuffers (HashVal,uint,size_t) override { WARN (engine, "Announce invoked on a Proxy Buffer Provider; " "Implies misuse as generic BufferProvider"); return 1; } BuffAlloc provideBuffer (HashVal,size_t siz,LocalTag targetMarker) override { BuffAlloc storageSlot{asBuffer(targetMarker), siz, targetMarker}; CONF::on_lock (storageSlot); return storageSlot; } void mark_emitted (HashVal, BuffAlloc storageSlot) override { CONF::on_emit (storageSlot); } void detachBuffer (HashVal, BuffAlloc storageSlot) override { CONF::on_release (storageSlot); } public: ProxyBufferStore (CONF policy) : CONF{move(policy)} { } }; struct Setup : CONF { auto buildStage() { return std::make_unique("OutputBufferProxy"); } auto buildStore() { return std::make_unique (move(*this)); } }; // Note: possible since Setup does not use CONF class PassThroughBufferProvider : public BufferProviderSetup { public: PassThroughBufferProvider (Setup setup) : BufferProviderSetup{setup} { } BuffDescr registerBuffer (void* buff, size_t siz) { REQUIRE (siz); REQUIRE (buff); auto& typeKey = bufferStage_->defineBufferType (siz, TypeHandler::RAW, LocalTag(buff)); return buildDescriptor (typeKey); } }; PassThroughBufferProvider proxyProvider_; public: OutputBufferProxy(CONF policy) : proxyProvider_{Setup{move(policy)}} { } template BuffDescr getDescriptorFor (TAR& dataBlock) { return proxyProvider_.registerBuffer(&dataBlock, sizeof(TAR)); } template BuffHandle lockBuffer (TAR& dataBlock) { BuffDescr buffType = getDescriptorFor (dataBlock); ENSURE (buffType.isValid()); return buffType.lockBuffer(); } }; }} // namespace vault::out #endif /*VAULT_OUT_OUTPUT_BUFFER_PROXY_H*/