BufferProvider: bold solution for setup of the policy-baseclass
The idea is to use a "transient" Setup helper class, which lives only during the invocation of the BufferProviderSetup-constructor. This transient frame allows to accept a policy class from the client, and move it through this transient Setup helper and finally into the BufferStore backend implementation, where it is actually needed.
This commit is contained in:
parent
02ba977c61
commit
77217d9785
2 changed files with 81 additions and 27 deletions
|
|
@ -71,19 +71,10 @@ namespace engine {
|
|||
: util::NonCopyable
|
||||
{
|
||||
|
||||
class PreRiggedBufferStage
|
||||
: public SimpleBufferStateRegistry
|
||||
{
|
||||
public:
|
||||
PreRiggedBufferStage()
|
||||
: SimpleBufferStateRegistry{"ResourceProxy"}
|
||||
{ }
|
||||
};
|
||||
|
||||
class ProxyBufferStore
|
||||
: public BufferProviderSetup::Store
|
||||
, private CONF
|
||||
{
|
||||
CONF& callback_;
|
||||
|
||||
Buff*
|
||||
asBuffer (LocalTag targetMarker)
|
||||
|
|
@ -103,35 +94,41 @@ namespace engine {
|
|||
Slot
|
||||
provideBuffer (size_t,HashVal, LocalTag targetMarker) override
|
||||
{
|
||||
callback_.on_lock();
|
||||
CONF::on_lock();
|
||||
return {asBuffer(targetMarker), targetMarker};
|
||||
}
|
||||
|
||||
void
|
||||
mark_emitted (size_t,HashVal, LocalTag const&) override
|
||||
{
|
||||
callback_.on_emit();
|
||||
CONF::on_emit();
|
||||
}
|
||||
|
||||
void
|
||||
detachBuffer (size_t,HashVal,Slot) override
|
||||
{
|
||||
callback_.on_release();
|
||||
CONF::on_release();
|
||||
}
|
||||
|
||||
public:
|
||||
ProxyBufferStore (CONF& policy)
|
||||
: callback_{policy}
|
||||
ProxyBufferStore (CONF policy)
|
||||
: CONF{move(policy)}
|
||||
{ }
|
||||
};
|
||||
|
||||
struct Setup
|
||||
: CONF
|
||||
{
|
||||
auto buildStage() { return std::make_unique<SimpleBufferStateRegistry>("ResourceProxy"); }
|
||||
auto buildStore() { return std::make_unique<ProxyBufferStore> (move(*this)); }
|
||||
}; // Note: possible since Setup does not use CONF
|
||||
|
||||
class PassThroughBufferProvider
|
||||
: public BufferProviderSetup
|
||||
{
|
||||
|
||||
public:
|
||||
template<class SETUP>
|
||||
PassThroughBufferProvider (SETUP& setup)
|
||||
PassThroughBufferProvider (Setup setup)
|
||||
: BufferProviderSetup{setup}
|
||||
{ }
|
||||
|
||||
|
|
@ -145,21 +142,12 @@ namespace engine {
|
|||
}
|
||||
};
|
||||
|
||||
struct Setup
|
||||
: CONF
|
||||
{
|
||||
auto buildStage() { return std::make_unique<PreRiggedBufferStage>(); }
|
||||
auto buildStore() { return std::make_unique<ProxyBufferStore>(*this); }
|
||||
};
|
||||
Setup setup_;
|
||||
|
||||
PassThroughBufferProvider proxyProvider_;
|
||||
|
||||
|
||||
public:
|
||||
BufferProxyAdaptor(CONF policy)
|
||||
: setup_{move(policy)}
|
||||
, proxyProvider_{setup_}
|
||||
: proxyProvider_{Setup{move(policy)}}
|
||||
{ }
|
||||
|
||||
template<typename TAR>
|
||||
|
|
|
|||
|
|
@ -114431,6 +114431,72 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1771857651995" ID="ID_1588748645" MODIFIED="1771857677972" TEXT="das geht noch dreister: »schwebwende Config«">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1771857680890" ID="ID_1386032779" MODIFIED="1771857785144" TEXT="wir brauchen eine Setup-Hilfsklasse, um die Backend-Implementierungen zu erzeugen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Das ist so vorgegeben durch das Design von BufferProviderSetup (weil ich damit die konkreten Backend-Klassen komplett aus dem Basis-Interface BufferProvider heraushalte)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1771857787371" ID="ID_1223489355" MODIFIED="1771857849302" TEXT="diese brauchen tatsächlich nur während der Dauer des Konstruktur-Aufrufs">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
BufferProviderSetup ruft aus dem Rumpf ihres Konstruktors zwei Setup-Methoden auf; das wars dann, danach wird die Setup-Klasse nicht mehr gebraucht
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1771857855938" ID="ID_468915370" MODIFIED="1771857872747" TEXT="diese Setup-Klasse kann ein Dekorator über die Policy sein">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1771857897007" ID="ID_1909591340" MODIFIED="1771857918626" TEXT="für die restliche Lebensdauer brauchen wir die Policy nur im Store-Backend">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1771857921329" ID="ID_233147109" MODIFIED="1771857966470" TEXT="⟹ also kann die Policy letztlich dorthin geschoben werden, als Mix-in (private Basisklasse)"/>
|
||||
<node CREATED="1771857999246" ID="ID_142868114" MODIFIED="1771858675941">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<b><u>Hier wird's dreist</u></b>: Policy-Base per move aus der Setup-Hilfsklasse herausschieben !!!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Und zwar, noch dreister, <i>während</i> diese Setup-Klasse grade aufgerufen wird, um die Backends zu konfigurieren. Effektiv führt dieser Aufruf dazu, daß die Setup-Klasse ihre eigenen »Eingeweide« ausweidet und weitergibt. <i><font color="#770d2c">Kein Problem, sie stirbt ja sowiso am Ende des Aufrufts. </font></i>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Noch genauer betrachtet: eine RValue-Referenz ist ja erst mal nur ein »Angebot«: sie macht etwas für move-Konstukrion (oder Zuweisung) zugänglich. <i>Was konkret beim »move« passiert</i>, legt der Konsument fest. Hier ist der Konsument aber tatsächlich nur an der Basis-Klasse interessiert, d.h. er konstruiert eine Kopie der Basisklasse per move-Konstruktur. Und wiederum, was dabei passiert, bestimmen die Member in dieser Policy. Erwartungsgemäß sind das Lambdas, und die könnten obtional tatsächlich etwas binden, was dann per Move-Konstruktion verschoben wird (z.B. einenen unique-PImpl). Sehr schön, denn Lambdas werden erst aktiv, wenn sie aufgerufen werden. Werden sie aber nicht, während der Konstruktion. Zusammengefaßt: <i>solange nicht der Konstruktionsvorgang selbst die Callbacks aufruft,</i> ist das alles wasserdicht. Die einzige (langfristige) Gefahr besteht darin, daß ein übereifriger Linter/Compiler in Zukunft hier einen use-after-delete markiert, ohne tatsächlich zu belegen, daß der use auftritt.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue