BufferProvider: document the new design and use it for the prototype

Explored further aspects of this new design;
as an aside, I tried to build a Concept to describe the policy,
which howerer turned out to be much more challenging than expected.

Lastly, I could now complete the prototype of `BufferProxyAdaptor`
This commit is contained in:
Fischlurch 2026-02-26 23:25:07 +01:00
parent 8437710232
commit ea627c1c7a
5 changed files with 293 additions and 77 deletions

View file

@ -14,6 +14,58 @@
/** @file prop-builder.hpp
** A builder for compile-time generation of data records with arbitrary named fields.
** Generally speaking, a "record" in this context means just a struct or class with some
** data fields, and can be easily defined to suit any needs. However, such a class definition
** always incurs some _syntactical overhead_ — which is fine for spelling out some type in
** general, but can be problematic when the data record is only used once, locally and
** is without further significance beyond that single usage. Such a situation often
** arises in the context of _policy based design_ and flexible configuration of
** some generic facility, especially when part of this configuration involves
** the definition of _callback functions._
**
** A common requirement that lends itself well to policy based design arises when such callbacks
** establish a deeply interwoven link into local implementation details; this kind of interconnected
** implementation can be expressed succinctly through Lambda functions with contextual capture, and
** allows to setup a tight interconnection between implementation back-ends, without exposing any
** of these implementation details at the interface / dependency-injection level. However, the task
** to package several such specific callbacks into a policy instance and pass this configured policy
** for creation of service instances, can be surprisingly complex, verbose, confusing and leads
** to code that is hard to maintain. The reasons for this challenge are manifold:
** - contextual capture works only well from directly within an implementation function
** - such a setup can not be expressed well through types and interfaces, since the
** generated closure is _essentially a value_ and its type can not be spelled out.
** - a policy with several callbacks thus turns into a template with several type parameters,
** and must be initialised through a likewise template based constructor; the resulting code
** tends to become very technical, verbose, surprisingly tricky and hard to decipher for
** any reader not familiar with all the intricate details of the implementation.
**
** The root of these difficulties of proper formulation seems to be related to the nature
** of cohesive, closely interwoven implementation code. As long as this kind of structure
** can be kept close together, it works surprisingly well and expresses intent clearly.
** Yet as soon as it must be taken apart, expressed in names, types and interfaces,
** a high conceptual burden is added, which leads to the danger of generalisation
** and re-use beyond the very specific case, to which the original formulation
** of the problem was well adapted and adequate.
**
** The solution promoted here thus aims to remove the need to define any type and interface
** explicitly; a builder-expression is created rather, which allows to bind all callbacks
** and further parameters directly inline, within a single constructor invocation.
** Such a setup becomes possibly through a combination of some C++20 features, linked
** together by lambda expressions generated from a _macro_.
** - the PropBuilder acts as base class for the generated records, and is used to
** initiate the build-up of the definition expression.
** - several »layers« of derived classes are added step by step, where each such
** layer adds one further _property_ attribute, that is initialised by a given value.
** - the _junctor_ to combine those layer is provided by the template function
** `PropBuilder::define(builder-λ, value)`. It uses the new _explicit object_
** syntax introduced with C++20, to pick up the "self type" as template argument.
** - by invoking this builder function, the current "this"-object is _moved_ into
** the builder, where it is used to create and initialise a derived class.
** - for each »layer« a specific lambda is generated by a macro — and it is this
** technique that allows to accept a lexical token form the program text and
** use this token as field name in the next derived class to generate.
** @see PropBuilder_test for detailed explanation
** @see OutputProxyProvider_test for a usage example
*/
@ -35,13 +87,19 @@ namespace meta{
/**
* Anchor record and builder mechanics for generating data records.
* - start a builder expression by constructing an anonymous `PropBulder()`
* - invoke PropBuilder::define() for each further property to add
* - pass a builder-λ as first argument, and the data value as second
* - generate a suitable builder-λ with the macro `PROP_FIELD(fieldname)`
* - overall, the builder expression generates a RValue, that will usually
* be passed directly to the constructor of another class.
* @see PropBuilder_test::simpleUsage
*/
struct PropBuilder
{
/**
* Core builder operation: invoke a builder-λ to extend »this«
* @param layerBilder a specially crafted invokable, that takes _this object_
* @param layerBuilder a specially crafted invokable, that takes _this object_
* and the given property value and creates an instance of a derived class.
* @note the macro \ref PROP_FIELD below will generate a suitable argument.
* @param val an arbitrary (movable) data element to be stored as property.

View file

@ -96,7 +96,7 @@ namespace engine {
operator HashVal() const { return subClassification_; }
/** convenience shortcut to start a buffer handling cycle */
/** callback to engage buffer handling cycle */
uint announce (uint count);
BuffHandle lockBuffer();
};

View file

@ -21,6 +21,7 @@
//#include "steam/play/diagnostic-output-slot.hpp"
#include "steam/engine/buffer-proxy-adaptor.hpp"
#include "steam/engine/test-rand-ontology.hpp"
#include "lib/meta/prop-builder.hpp"
#include "lib/test/diagnostic-output.hpp"
@ -28,6 +29,7 @@ namespace steam {
namespace engine{
namespace test {
using lib::meta::PropBuilder;
@ -42,38 +44,44 @@ namespace test {
virtual void
run (Arg)
{
struct Callback
{
void on_lock() { cout << "LOCK" << endl; }
void on_emit() { cout << "EMIT" << endl; }
void on_release() { cout << "RELEASE" << endl; }
};
BufferState state{NIL};
// setup with notification callback
BufferProxyAdaptor proxPro{Callback()};
BufferProxyAdaptor proxPro{PropBuilder()
.define (PROP_FIELD(on_lock), [&]{ state = LOCKED; })
.define (PROP_FIELD(on_emit), [&]{ state = EMITTED;})
.define (PROP_FIELD(on_release),[&]{ state = FREE; })
};
// Assuming some data block is »given«
seedRand();
size_t frameNr = defaultGen.u64();
TestFrame dataBlock (frameNr);
CHECK ( dataBlock.isPristine());
CHECK (dataBlock.isPristine());
CHECK (state == NIL);
BuffHandle handle = proxPro.lockBuffer (dataBlock);
CHECK (state == LOCKED);
// Now a »client« can do awful things to the buffer...
CHECK (handle.isValid());
auto& data = handle.accessAs<TestFrame>();
uint64_t param = defaultGen.u64();
ont::manipulateFrame (&data, &data, param);
HashVal check = data.getChecksum();
// »client« is done...
handle.emit();
CHECK (state == EMITTED);
// end usage cycle
handle.release();
CHECK (state == FREE);
CHECK (not handle.isValid());
CHECK (not dataBlock.isPristine());
CHECK ( dataBlock.isValid());
CHECK (check == dataBlock.getChecksum());
}
};

View file

@ -21,38 +21,20 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/meta/prop-builder.hpp"
//#include "lib/meta/tuple-helper.hpp"
//#include "meta/typelist-diagnostics.hpp"
//#include "meta/tuple-diagnostics.hpp"
//#include "lib/format-string.hpp"
//#include "lib/format-cout.hpp"
//#include "lib/hetero-data.hpp"
#include "lib/test/diagnostic-output.hpp"////////////////TODO
#include "lib/format-string.hpp"
#include <string>
using std::string;
using lib::test::showType;
//using lib::test::showSizeof;
//using util::toString;
//using util::_Fmt;
//using std::is_same_v;
//using std::make_tuple;
//using std::get;
using util::_Fmt;
namespace lib {
namespace meta {
namespace test {
namespace { // test data
} // (End) test data
using lib::test::showType;
#define TYPE(_TY_) showType<decltype(_TY_)>()
/*********************************************************************//**
@ -73,6 +55,9 @@ namespace test {
/** @test show syntax and usage
* - create from the PropBuilder
* - add named fields with values as desired
* - the result is a record holding the data values
*/
void
simpleUsage()
@ -115,7 +100,8 @@ namespace test {
/** @test demonstrate and verify the language features
* used to generate arbitrary record data types.
* - capture self-type with C++20 _explicit object member function_
* - use generic-λ to generate a derived class with a property field
* - use generic-λ to generate a derived class with a property field
* - chain-up further layers with named fields by extending self-type
*/
void
explain_building_blocks()
@ -139,12 +125,12 @@ namespace test {
// local type can be _referred to_ only locally, within this function,
// it is _not a hidden type_. Data elements using such a local type
// can be returned by-value — which allows us to "drop off" such
// a data record, and this also implicitly its type.
// a data record, and thus also implicitly export its type.
// While this seems rather pointless in itself, it can be leveraged
// with the help of C++20 explicit lambda template parameters: we can
// move an instance of a base class into a function, thereby pick up
// its type, and define a new derived class, and even move the given
// its type, then define a new derived class, and even move the given
// base class instance into the embedded base class sub-object:
auto dropperLambda = []<class BAS, typename VAL>(BAS&& bas, VAL&& val)
@ -176,53 +162,106 @@ namespace test {
ushort evil = 55;
auto compoundRecord = dropperLambda (SomeRecord{0.13}, evil);
// here SomeRecord was created transiently, moved into the dropper-λ,
// used there as base for a derived struct DataLayer_something, which
// features an additional property `something`, initialised with an
// arbitrary value (and type) also passed on invocation.
// arbitrary value (and type), also passed directly on invocation.
// The result is a record object, which incorporates the base, together
// with an additional "Layer" holding the new property, stored efficiently.
CHECK (compoundRecord.something == evil);
CHECK (compoundRecord.someData == 0.13f);
using Compound = decltype(compoundRecord);
SHOW_TYPE(decltype(compoundRecord))
SHOW_EXPR(TYPE(compoundRecord))
SHOW_EXPR(sizeof(SomeRecord))
CHECK (sizeof(SomeRecord) == sizeof(float));
SHOW_EXPR(sizeof(Compound))
CHECK (sizeof(Compound) >= sizeof(float)+sizeof(ushort));
SHOW_EXPR(alignof(SomeRecord))
SHOW_EXPR(alignof(Compound))
CHECK (alignof(Compound) == alignof(SomeRecord));
CHECK (sizeof(Compound) == 2 * alignof(float));
SHOW_EXPR(std::is_class_v<Compound>)
SHOW_EXPR(std::is_trivial_v<Compound>)
SHOW_EXPR(std::is_trivial_v<SomeRecord>)
SHOW_EXPR(std::is_trivially_copyable_v<SomeRecord>)
SHOW_EXPR(std::is_trivially_copyable_v<Compound>)
SHOW_EXPR(std::is_standard_layout_v<Compound>)
CHECK (std::is_class_v<Compound>);
CHECK (std::is_trivial_v<Compound>);
CHECK (std::is_trivial_v<SomeRecord>);
CHECK (std::is_trivially_copyable_v<Compound>);
CHECK (std::is_trivially_copyable_v<SomeRecord>);
// Yet obviously it is not a POD,
// Yet obviously the generated record is not a POD,
// since non-static members reside at several levels
CHECK (not std::is_standard_layout_v<Compound>);
SHOW_EXPR((is_Subclass_v<Compound, SomeRecord>))
CHECK ((is_Subclass_v<Compound, SomeRecord>));
// Lastly, a chain of such »property layers« can be built gradually,
// with the help of a hook-method, that grabs the _current record_
// and passes it to the next extension-layer-λ. As first example,
// the dropper-λ defined above can be used here too...
auto record1 = PropBuilder()
.define (dropperLambda, 0.23)
;
using Rec1 = decltype(record1);
CHECK ((is_Subclass_v<Rec1, PropBuilder>));
CHECK (sizeof(Rec1) == sizeof(double));
CHECK (TYPE(record1.something) == "double"_expect);
CHECK (record1.something == 0.23);
// Note that the name of the property field, here `something`,
// needs to be hard wired into the builder-λ, due to the nature of C++.
// Yet this hurdle can be overcome by generating the builder-λ from a *macro*
auto record2 = record1
.define (PROP_FIELD(anything)
,[&](auto val){ return val + evil; } // ◁———————————— can pass a Lambda as "value"
);
using Rec2 = decltype(record2);
CHECK ((is_Subclass_v<Rec2, Rec1>));
CHECK ((is_Subclass_v<Rec2, PropBuilder>));
CHECK (record2.something == 0.23);
CHECK (record2.anything(11) == 66);
evil = 13;
CHECK (record2.anything(42) == 55);
// note the anything-λ is _generic_
CHECK (record2.anything(7.77f) == 20.77f);
// Warning: record1 has been moved-away into record2,
// so its content is now »undefined«
}
/** @test show how to use generated records to implement a policy.
/** Example for demonstration of possible use-case */
template<class POL>
class Producer
: POL
{
public:
Producer (POL policy)
: POL{move(policy)}
{ }
decltype(auto)
doIt()
{
return POL::wrap (POL::feed());
}
};
/** @test show a didactical example how generated records
* can be used to support policy-based design.
* - the Producer template defined above can be configured
* with appropriate actions and operations that fit together
* - the test features a special context-bound producer.
*/
void
demonstrate_usage_scenario()
{
uint current{21};
_Fmt putIt{"%s tralala"};
auto doer = Producer{PropBuilder()
.define (PROP_FIELD(feed), [&]{ return current++; })
.define (PROP_FIELD(wrap), [&](auto it)->string { return putIt % it; })
};
CHECK (doer.doIt() == "21 tralala"_expect);
CHECK (22 == current);
}
};

View file

@ -58600,9 +58600,9 @@
</node>
</node>
<node CREATED="1772066411633" ID="ID_50275437" MODIFIED="1772066416949" TEXT="Code-Generierung">
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1772066190351" ID="ID_940571255" MODIFIED="1772066239070" TEXT="PropBuilder : Record mit benannten Feldern generieren">
<node BACKGROUND_COLOR="#c5ebda" COLOR="#2f6877" CREATED="1772066190351" FOLDED="true" ID="ID_940571255" MODIFIED="1772157213950" TEXT="PropBuilder : Record mit benannten Feldern generieren">
<icon BUILTIN="yes"/>
<node CREATED="1772066253767" ID="ID_1072763198" MODIFIED="1772067242722" TEXT="Neue Metaprgramming-Technik &#x27f8; f&#xfc;r Policy-based Design">
<node COLOR="#12109f" CREATED="1772066253767" ID="ID_1072763198" MODIFIED="1772157175603" TEXT="Neue Metaprgramming-Technik &#x27f8; f&#xfc;r Policy-based Design">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -58620,7 +58620,8 @@
<linktarget COLOR="#2b57f9" DESTINATION="ID_1072763198" ENDARROW="Default" ENDINCLINATION="2965;140;" ID="Arrow_ID_198810341" SOURCE="ID_1029922863" STARTARROW="None" STARTINCLINATION="-2090;136;"/>
<icon BUILTIN="info"/>
</node>
<node CREATED="1772067250896" ID="ID_1640694078" MODIFIED="1772067306544" TEXT="Aufgabe: einen &#xbb;ma&#xdf;geschneiderten&#xab; Daten-Record...">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#434698" CREATED="1772067250896" ID="ID_1640694078" MODIFIED="1772074391901" TEXT="Aufgabe: einen &#xbb;ma&#xdf;geschneiderten&#xab; Daten-Record...">
<icon BUILTIN="yes"/>
<node CREATED="1772067307899" ID="ID_919196456" MODIFIED="1772067410868" TEXT="kompakt und lesbar &#xbb;inline&#xab; definieren">
<richcontent TYPE="NOTE"><html>
<head/>
@ -58633,7 +58634,8 @@
</node>
<node CREATED="1772067418044" ID="ID_1314882599" MODIFIED="1772067438651" TEXT="und gleich mit inline-&#x3bb; und Kontext-capture initialisieren"/>
</node>
<node CREATED="1772068221512" ID="ID_774607578" MODIFIED="1772070444439" TEXT="Bau-Technik">
<node COLOR="#435e98" CREATED="1772068221512" ID="ID_774607578" MODIFIED="1772074416160" TEXT="Bau-Technik">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="forward"/>
<node COLOR="#435e98" CREATED="1772068227431" ID="ID_361097452" MODIFIED="1772070455630" TEXT="ein Builder-Ausdruck"/>
<node COLOR="#435e98" CREATED="1772068233846" ID="ID_1873632379" MODIFIED="1772070455630" TEXT="ein Lambda, das einen abgeleiteten Typ definiert">
@ -58644,20 +58646,48 @@
<node COLOR="#435e98" CREATED="1772068303510" ID="ID_142658280" MODIFIED="1772070460038" TEXT="Definition und Aufruf dieses Lambdas kann man in einen einzigen Ausdruck packen">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#435e98" CREATED="1772068327705" ID="ID_782344387" MODIFIED="1772070455629" TEXT="und diesen Ausdruck kann man dann mit einem Macro generieren">
<node COLOR="#435e98" CREATED="1772068327705" ID="ID_782344387" MODIFIED="1772074438775" TEXT="und diesen Ausdruck wiederum kann man dann mit einem Macro generieren">
<icon BUILTIN="idea"/>
<node CREATED="1772068339947" ID="ID_721460446" MODIFIED="1772068350577" TEXT="damit werden neue Feldnamen m&#xf6;glich"/>
<node CREATED="1772068351334" ID="ID_302440640" MODIFIED="1772068360385" TEXT="und man kann auch den generierten Typ dekorieren"/>
</node>
</node>
<node CREATED="1772068366233" ID="ID_858655013" MODIFIED="1772068376142" TEXT="Implementierung">
<node COLOR="#338800" CREATED="1772068366233" ID="ID_858655013" MODIFIED="1772156709954" TEXT="Implementierung">
<icon BUILTIN="button_ok"/>
<node CREATED="1772068377138" ID="ID_160543739" MODIFIED="1772068386687" TEXT="lib/meta/prop-builder.hpp"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1772068387673" ID="ID_999468145" MODIFIED="1772068449713" TEXT="PropBuilder_test">
<icon BUILTIN="pencil"/>
<node CREATED="1772068394858" ID="ID_1256049272" MODIFIED="1772068407518" TEXT="Aufruf-Syntax zeigen"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1772068408103" ID="ID_452419709" MODIFIED="1772068442634" TEXT="die verwendeten Programmiertechniken dokumentieren">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1772068387673" ID="ID_999468145" MODIFIED="1772156707171" TEXT="PropBuilder_test">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1772068394858" ID="ID_1256049272" MODIFIED="1772156702859" TEXT="Aufruf-Syntax zeigen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1772068408103" ID="ID_452419709" MODIFIED="1772156704705" TEXT="die verwendeten Programmiertechniken dokumentieren">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1772068421596" ID="ID_1602327531" MODIFIED="1772156705875" TEXT="Beispiel f&#xfc;r ein Policy-based Design darststellen">
<icon BUILTIN="button_ok"/>
<node COLOR="#5b280f" CREATED="1772156780733" ID="ID_960855659" LINK="https://quuxplusone.github.io/blog/2020/08/10/concepts-cant-do-quantifiers/" MODIFIED="1772157138692" TEXT="auch gleich ein Concept zeigen?">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Nehme davon Abstand.
</p>
<p>
Da ich als Beispiel eine Struktur wie in einer Factory zeigen m&#246;chte, erweist es sich als ausgesprochen schwierig, die erwartete Struktur sauber als Concept zu repr&#228;sentieren. Das liegt darin, da&#223; eine solche generische Factory oft implizit auf eine &#8704;-Quantisierung hinausl&#228;uft; d.h. man m&#246;chte etwas bauen, das <i>&#187;f&#252;r beliebige Typen funktioniert&#171;. </i>Wenngleich auch klar ist, da&#223; man niemals v&#246;llgig allgemeing&#252;ltigen, generischen Code schreiben kann, baut man die Struktur doch dieser Idee entsprechend auf. So etwas l&#228;&#223;t sich jedoch nicht als einfacher, formal pr&#252;fbarerer Constraint formulieren, denn das w&#252;rde eine formalisierte Spezifikations-Sprache und einen Theorem-Beweis erfordern.
</p>
<p>
</p>
<p>
Die Concepts in C++ k&#246;nnen jedoch nur <i>f&#252;r einen konkret gegebenen, einzelnen Typ</i>&#160;jeweils pr&#252;fen, ob sich ein valider Ausdruck ergibt; &#187;valide&#171; w&#252;rde sich in diesem Fall auf reine Syntax beschr&#228;nken, und das rechtfertigt nicht den syntaktischen Overhead f&#252;r ein Concept
</p>
</body>
</html></richcontent>
<font NAME="SansSerif" SIZE="11"/>
<icon BUILTIN="help"/>
<icon BUILTIN="button_cancel"/>
</node>
</node>
<node CREATED="1772068421596" ID="ID_1602327531" MODIFIED="1772068435958" TEXT="Beispiel f&#xfc;r ein Policy-based Design darststellen"/>
</node>
</node>
</node>
@ -114207,6 +114237,36 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1772129298282" ID="ID_1032607524" MODIFIED="1772129491113" TEXT="Implementierungs-API konsistenter gestalten">
<linktarget COLOR="#71434f" DESTINATION="ID_1032607524" ENDARROW="Default" ENDINCLINATION="-1142;72;" ID="Arrow_ID_1327695220" SOURCE="ID_1927667326" STARTARROW="None" STARTINCLINATION="-295;-14;"/>
<icon BUILTIN="yes"/>
<node CREATED="1772129494743" ID="ID_797224940" MODIFIED="1772129626006" TEXT="aufgefallen beim OutputSlot / BufferProxyAdaptor">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...denn dort kommt es zu der Anforderung, bei den State-Transitions jeweils einen Callback aufzurufen; das wirft die Frage nach den Namen und den jeweils &#252;bergebenen Daten auf; die Daten w&#228;ren <i>im Grunde genommen jeweils gleich.</i>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1772129627997" ID="ID_1533127720" MODIFIED="1772129874152" TEXT="weitere Analyse zeigt: die konkrtete Storage-Size weicht ab (kann gr&#xf6;&#xdf;er sein)">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Das ist eine Konsequenz aus der Einsicht, da&#223; der metadata::Entry nicht nur der internen Verwaltung dient, sondern die dort aufgezeichneten Informationen auch essentiell sind f&#252;r die Implementierung eines Storage-Backends. Das ist ein weithin bekanntes Pattern (und Problem) f&#252;r Allokatoren: man mu&#223; die Storage-Size kennen, speziell auch zur <i>De-</i>Allokation. Wenn man diese Einsicht verbindet mit &#220;berlegungen zum globalen Speicherblock-Management in der Engine, dann wird schnell klar, da&#223; man bisweilen durchaus einen zu-gro&#223;en-Speicherblock verwenden m&#246;chte; das bedeutet dann, da&#223; die Size-Eintrag f&#252;r den state-Key entsprechend pr&#228;zise ausgef&#252;llt sein mu&#223;.
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1772129891226" ID="ID_1405915409" MODIFIED="1772129902229" TEXT="&#xdc;berlegungen zum BuffeStore-API">
<node CREATED="1772129905244" ID="ID_545569208" MODIFIED="1772129929698" TEXT="eigentlich tritt ein charakteristisches Tupel bei jeder Transition auf"/>
<node CREATED="1772129931304" ID="ID_1142410309" MODIFIED="1772129958147" TEXT="&#x27f9; man k&#xf6;nnte den &#xbb;Slot&#xab;-Datentyp erweitern...">
<node CREATED="1772129959849" ID="ID_1378157373" MODIFIED="1772130000767" TEXT="(storage, size, localTag)"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1771538366852" ID="ID_1595544111" MODIFIED="1771538575391" TEXT="saubere Fehlermeldung wenn keine Allokation m&#xf6;glich ist">
<linktarget COLOR="#744d8b" DESTINATION="ID_1595544111" ENDARROW="Default" ENDINCLINATION="628;31;" ID="Arrow_ID_378933605" SOURCE="ID_27406270" STARTARROW="None" STARTINCLINATION="221;-288;"/>
<icon BUILTIN="flag-yellow"/>
@ -114348,8 +114408,8 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1771539807853" ID="ID_1455262817" MODIFIED="1771539852207" TEXT="Prototyping : OutputProxyProvider_test als Experimentierfeld">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1771616038792" ID="ID_1389235656" MODIFIED="1771809186526" TEXT="Forschung: Policy konfigurieren">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1771616038792" FOLDED="true" ID="ID_1389235656" MODIFIED="1772157520866" TEXT="Forschung: Policy konfigurieren">
<icon BUILTIN="button_ok"/>
<node CREATED="1771616054739" ID="ID_297187964" MODIFIED="1771616315207" TEXT="hab die dunkle Erinnerung da&#xdf; in so was &#xc4;hnliches schon zig mal vergeblich versucht habe">
<richcontent TYPE="NOTE"><html>
<head/>
@ -114549,17 +114609,17 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1771893568172" ID="ID_465309080" MODIFIED="1771893720003" TEXT="Zweiter Teil der Aufgabe: named-Lambda-Tupel ">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1771893568172" ID="ID_465309080" MODIFIED="1772157313295" TEXT="Zweiter Teil der Aufgabe: named-Lambda-Tupel ">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1771893733865" ID="ID_60984394" MODIFIED="1771893764443" TEXT="ich m&#xf6;chte ALLES">
<icon BUILTIN="yes"/>
<node CREATED="1771893742904" ID="ID_921712765" MODIFIED="1771893750874" TEXT="einen meta-konfigurierbaren Builder"/>
<node CREATED="1771893769036" ID="ID_434009909" MODIFIED="1771893878715" TEXT="einzelne Layer mit einem &#x3bb;-Attribut von generischem Typ &#x27f9; MACRO"/>
<node CREATED="1771893845362" ID="ID_112946042" MODIFIED="1771893872082" TEXT="UND das &#x3bb; soll aber noch lokal gegeben werden k&#xf6;nnen &#x27f9; Kontext-Binding"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1771893896510" ID="ID_771196335" MODIFIED="1771895013673" TEXT="Ideen sammeln">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1771893896510" ID="ID_771196335" MODIFIED="1772157452614" TEXT="Ideen sammeln">
<icon BUILTIN="idea"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1771893905186" ID="ID_1241420221" MODIFIED="1771893946302" TEXT="nicht klar ob es geht .... die Teile passen noch nicht recht zusammen (in meinem Kopf)">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1771893905186" ID="ID_1241420221" MODIFIED="1772157446312" TEXT="nicht klar ob es geht .... die Teile passen noch nicht recht zusammen (in meinem Kopf)">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1771893948001" ID="ID_898834553" MODIFIED="1771894995111" TEXT="einen Builder, der per Macro generierte nested-Classes zusammenh&#xe4;ngt">
@ -114572,11 +114632,11 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<icon BUILTIN="full-3"/>
</node>
</node>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1772064586741" ID="ID_1333957843" MODIFIED="1772064712945" TEXT="das Problem ist vor allem syntaktischer Natur">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1772064586741" ID="ID_1333957843" MODIFIED="1772157307555" TEXT="das Problem ist vor allem syntaktischer Natur">
<icon BUILTIN="broken-line"/>
<node CREATED="1772064634844" ID="ID_1613330952" MODIFIED="1772064634844" TEXT="Typen m&#xfc;ssen deklariert werden"/>
<node CREATED="1772064649488" ID="ID_806205089" MODIFIED="1772064649488" TEXT="Instanzen m&#xfc;ssen definiert werden"/>
<node CREATED="1772064692061" ID="ID_1021370131" MODIFIED="1772064692061" TEXT="Ich will aber nur EIN Macro pro &#xbb;Layer&#xab;">
<node BACKGROUND_COLOR="#cbcff9" COLOR="#1d0194" CREATED="1772064692061" ID="ID_1021370131" MODIFIED="1772157493399" TEXT="Ich will aber nur EIN Macro pro &#xbb;Layer&#xab;">
<icon BUILTIN="yes"/>
<node CREATED="1772064787000" ID="ID_1407594054" MODIFIED="1772064921190" TEXT="eigentlich kann man in C++ keine Typen &#x201e;inline&#x201c; (in einem Ausdruck) deklarieren">
<richcontent TYPE="NOTE"><html>
@ -114627,15 +114687,25 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<icon BUILTIN="smiley-neutral"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1772065498436" ID="ID_1029922863" MODIFIED="1772066452619" TEXT="Neues generisches Feature: PropBuilder">
<node COLOR="#338800" CREATED="1772065498436" ID="ID_1029922863" MODIFIED="1772157233364" TEXT="Neues generisches Feature: PropBuilder">
<arrowlink COLOR="#2b57f9" DESTINATION="ID_1072763198" ENDARROW="Default" ENDINCLINATION="2965;140;" ID="Arrow_ID_198810341" STARTARROW="None" STARTINCLINATION="-2090;136;"/>
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1772066464826" ID="ID_534123438" MODIFIED="1772066473089" TEXT="dokumentiert in PropBuilder_test">
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="idea"/>
<node COLOR="#338800" CREATED="1772066464826" ID="ID_534123438" MODIFIED="1772157242501" TEXT="dokumentiert in PropBuilder_test">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1772066474417" ID="ID_1404760011" MODIFIED="1772066498094" TEXT="dort auch direkt diesen use-Case demonstrieren">
<node COLOR="#435e98" CREATED="1772066474417" ID="ID_1404760011" MODIFIED="1772157245259" TEXT="dort auch direkt diesen use-Case demonstrieren">
<icon BUILTIN="yes"/>
<node COLOR="#3a109f" CREATED="1772157247895" ID="ID_1241263989" MODIFIED="1772157288387" TEXT="zeige ein einfaches policy-pased-Design">
<font NAME="SansSerif" SIZE="8"/>
</node>
<node COLOR="#3a109f" CREATED="1772157258547" ID="ID_577340727" MODIFIED="1772157288388" TEXT="eine Factory, die ihr Produkt auch gleich noch &#xbb;verpackt&#xab;">
<font NAME="SansSerif" SIZE="8"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1772157327329" ID="ID_54487483" MODIFIED="1772157434174" TEXT="erfolgreich in den Prototyp f&#xfc;r den OutputProxyProvider integriert">
<arrowlink COLOR="#1d8abd" DESTINATION="ID_946959732" ENDARROW="Default" ENDINCLINATION="85;-99;" ID="Arrow_ID_1405310375" STARTARROW="None" STARTINCLINATION="189;8;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
@ -114909,6 +114979,43 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
</node>
</node>
<node CREATED="1771719247697" ID="ID_1277905446" MODIFIED="1771719262138" TEXT="biete also f&#xfc;r diese Skizze erst mal nur ein Spezial-API"/>
<node CREATED="1772128789402" ID="ID_858761125" MODIFIED="1772128800353" TEXT="Interface: Callback-Funktionen">
<node CREATED="1772128802215" ID="ID_258480503" MODIFIED="1772128808917" TEXT="werden per Policy konfiguriert"/>
<node CREATED="1772128810953" ID="ID_1904023092" MODIFIED="1772128829194" TEXT="f&#xfc;r jede State-Transition eine andere Funktion">
<node CREATED="1772128834199" ID="ID_1497809945" MODIFIED="1772128839049" TEXT="on_lock"/>
<node CREATED="1772128840151" ID="ID_430684409" MODIFIED="1772128843792" TEXT="on_emit"/>
<node CREATED="1772128844960" ID="ID_502402565" MODIFIED="1772129182182" TEXT="on_release">
<arrowlink COLOR="#86858e" DESTINATION="ID_373327393" ENDARROW="Default" ENDINCLINATION="-28;-43;" ID="Arrow_ID_1002798807" STARTARROW="None" STARTINCLINATION="47;11;"/>
</node>
</node>
<node CREATED="1772129024726" ID="ID_1695408974" MODIFIED="1772129042551" TEXT="weitergegebene Detail-Info">
<node CREATED="1772129044383" ID="ID_1927667326" MODIFIED="1772129473327" TEXT="das interne Interface ist noch inkonsistent">
<arrowlink COLOR="#71434f" DESTINATION="ID_1032607524" ENDARROW="Default" ENDINCLINATION="-1142;72;" ID="Arrow_ID_1327695220" STARTARROW="None" STARTINCLINATION="-295;-14;"/>
<node CREATED="1772129080302" ID="ID_373327393" MODIFIED="1772129287183" TEXT="Namensgebung">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
leichte Uneinheitlichkeit bzgl. der jeweils erreichten States, und auch die implizite Perspektive betreffend (wer sagt wem was); &#187;release&#171; k&#246;nnte auch &#187;free&#171; hei&#223;en
</p>
</body>
</html></richcontent>
<linktarget COLOR="#86858e" DESTINATION="ID_373327393" ENDARROW="Default" ENDINCLINATION="-28;-43;" ID="Arrow_ID_1002798807" SOURCE="ID_502402565" STARTARROW="None" STARTINCLINATION="47;11;"/>
</node>
<node CREATED="1772129084894" ID="ID_598702937" MODIFIED="1772129147835" TEXT="jeweils bereitgestellt Daten">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
<i>effektiv</i>&#160;sind es jeweils die gleichen Infos f&#252;r jeden Transition, aber sie sind nicht eindeutig angeordnet
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1772129100438" ID="ID_255962416" MODIFIED="1772129106895" TEXT="Umgang mit der Storage-Size"/>
</node>
</node>
</node>
</node>
<node CREATED="1771719274535" ID="ID_1815060462" MODIFIED="1771719385960" TEXT="Implementierung zusammenschalten...">
<node CREATED="1771719283904" ID="ID_270233023" MODIFIED="1771719295702" TEXT="es gibt schon einen bestehenden Test, der sogar was verifiziert"/>
@ -114974,6 +115081,10 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<arrowlink COLOR="#4198b7" DESTINATION="ID_251025614" ENDARROW="Default" ENDINCLINATION="280;452;" ID="Arrow_ID_1811648927" STARTARROW="None" STARTINCLINATION="230;-772;"/>
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1772157371762" ID="ID_946959732" MODIFIED="1772157434175" TEXT="...und mit &#x3bb;-gebundener Policy!">
<linktarget COLOR="#1d8abd" DESTINATION="ID_946959732" ENDARROW="Default" ENDINCLINATION="85;-99;" ID="Arrow_ID_1405310375" SOURCE="ID_54487483" STARTARROW="None" STARTINCLINATION="189;8;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
</node>