Invocation: further rearrange and rework FeedManifold

What I'm about to do amounts to a massive generalisation, which is tricky.
Instead of having a fixed array-style layout, we want to accept arbitrary and mixed arguments.
Notably, we want to give the ''actual Library Plug-in'' a lot of leeway for binding:
- optionally, the library might want to require **Parameters** (which is the reason for this change)
- moreover, accepting input-buffers shall now be optional, since many generation functions do not need them
- and on top of all this, we want to accept an arbitrary mix of types for each kind.

So conceptually we are switching from C-style arrays to tuples with full type safety

''this going to become quite nasty and technical, I'm afraid...''
This commit is contained in:
Fischlurch 2024-12-15 18:53:50 +01:00
parent 40d088c62f
commit 1f265044e5
7 changed files with 361 additions and 373 deletions

View file

@ -57,7 +57,7 @@ namespace engine {
* to use a single contiguous memory area and just layer the object structure on top
* (by using placement new). Yet the idea of an stack-like organisation should be retained
*/
struct FeedManifold ///////////////////////////////////OOO rename into FeedManifold
struct FeedManifold_BuffTable_OBSOLETE ///////////////////////////////////OOO this is obliterated by the new implementation of FeedManifold_BuffTable_OBSOLETE
{
typedef BuffHandle * PHa;
typedef BuffHandle::PBuff * PBu;
@ -109,7 +109,7 @@ namespace engine {
* starting at current level to be used
* by the newly created BuffTableChunk
*/
FeedManifold::Chunk
FeedManifold_BuffTable_OBSOLETE::Chunk
claim (uint slots)
{
ASSERT (pTab_.size() == hTab_.size());
@ -132,7 +132,7 @@ namespace engine {
}
bool
level_check (FeedManifold::Chunk& prev_level)
level_check (FeedManifold_BuffTable_OBSOLETE::Chunk& prev_level)
{
return prev_level.first == &hTab_[level_]
&& prev_level.second == &pTab_[level_];
@ -148,11 +148,11 @@ namespace engine {
* object's lifecycle.
*/
class BuffTableChunk
: public FeedManifold,
: public FeedManifold_BuffTable_OBSOLETE,
util::NonCopyable
{
const uint siz_;
FeedManifold::Chunk tab_;
FeedManifold_BuffTable_OBSOLETE::Chunk tab_;
BuffTableStorage& sto_;
public:

View file

@ -14,9 +14,54 @@
/** @file feed-manifold.hpp
** Adapter to connect parameters and data buffers to an external processing function.
** The Lumiera Render Engine relies on a »working substrate« of _Render Nodes,_ interconnected
** in accordance to the structure of foreseeable computations. Yet the actual media processing
** functionality is provided by external libraries while the engine is arranged in a way to
** remain _agnostic_ regarding any details of actual computation. Those external libraries are
** attached into the system by means of a _library plugin,_ which cares to translate the external
** capabilities into a representation as _Processing Assets._ These can be picked up and used in
** the Session, and will eventually be visited by the _Builder_ as part of the effort to establish
** the aforementioned »network of Render Nodes.« At this point, external functionality must actually
** be connected to internal structures: this purpose is served by the FeedManifold.
**
** This amounts to an tow-stage adaptation process. Firstly, the plug-in for an external library
** has to wrap-up and package the library functions into an _invocation functor_ which thereby
** creates a _low-level Specification_ of the functionality to invoke. This functor is picked up
** and stored as a prototype within the associated render node. More specifically, each node can
** offer several [ports for computation](\ref steam::engine::Port). This interface is typically
** implemented by a [Turnout](\ref turnout.hpp), which in turn is based on some »weaving pattern«
** performed around and on top of a FeedManifold instance, which is created anew on the stack for
** each invocation. This invocation scheme implies that the FeedManifold is tailored specifically
** for a given functor, matching the expectations indicated by the invocation functor's signature:
** - A proper invocation functor may accept _one to three arguments;_
** - in _must accept_ one or several **output** buffers,
** - optionally it _can accept_ one or several **input** buffers,
** - optionally it _can accept_ also one or several **parameters** to control specifics.
** - the order of these arguments is fixed to the sequence: _parameters, inputs, outputs._
** - Parameters are assumed to have _value semantics._ They must be copyable and default-constructible.
** - Buffers are always passed _by pointer._ The type of the pointee is picked up and passed-through.
** - such a pointee or buffer-type is assumed to be default constructible, since the engine will have
** to construct result buffers within its internal memory management scheme. The library-plugin
** might have to create a wrapper type in cases where the external library requires to use a
** specific constructor function for buffers (if this requirement turns out as problematic,
** there is leeway to pass constructor arguments to such a wrapper yet Lumiera will insist
** on managing the memory, so frameworks insisting on their own memory management will have
** to be broken up and side-stepped, in order to be usable with Lumiera).
** - when several and even mixed types of a kind must be given, e.g. several buffers or
** several parameters, then the processing functor should be written such as to
** accept a std::tuple or a std::array.
**
** \par Implementation remarks
** A suitable storage layout is chosen at compile type, based on the given functor type.
** - essentially, FeedManifold is structured storage with some default-wiring.
** - the trait functions #hasInput() and #hasParam() should be used by downstream code
** to find out if some part of the storage is present and branch accordingly
** @todo 12/2024 figure out how constructor-arguments can be passed flexibly
** @todo staled since 2009, picked up in 2024 in an attempt to finish the node invocation.
** @todo WIP-WIP 2024 rename and re-interpret as a connection system
** @see nodeinvocation.hpp
** @see NodeBase_test
** @see weaving-pattern-builder.hpp
*/
@ -29,6 +74,7 @@
//#include "steam/engine/proc-node.hpp"
#include "steam/engine/buffhandle.hpp"
#include "lib/uninitialised-storage.hpp"
#include "lib/meta/function.hpp"
//#include "lib/several.hpp"
//#include <utility>
@ -43,25 +89,83 @@ namespace engine {
// using std::pair;
// using std::vector;
namespace {// Introspection helpers....
using lib::meta::_Fun;
using lib::meta::is_BinaryFun;
using std::remove_reference_t;
/** Helper to pick up the parameter dimensions from the processing function
* @remark this is the rather simple yet common case that media processing
* is done by a function, which takes an array of input and output
* buffer pointers with a common type; this simple case is used
* 7/2024 for prototyping and validate the design.
* @tparam FUN a _function-like_ object, expected to accept two arguments,
* which both are arrays of buffer pointers (input, output).
*/
template<class FUN>
struct _ProcFun
{
static_assert(_Fun<FUN>() , "something funktion-like required");
static_assert(is_BinaryFun<FUN>() , "function with two arguments expected");
using Sig = typename _Fun<FUN>::Sig;
template<class ARG>
struct MatchBuffArray
{
static_assert(not sizeof(ARG), "processing function expected to take array-of-buffer-pointers");
};
template<class BUF, size_t N>
struct MatchBuffArray<std::array<BUF*,N>>
{
using Buff = BUF;
enum{ SIZ = N };
};
using SigI = remove_reference_t<typename _Fun<FUN>::Args::List::Head>;
using SigO = remove_reference_t<typename _Fun<FUN>::Args::List::Tail::Head>;
using BuffI = typename MatchBuffArray<SigI>::Buff;
using BuffO = typename MatchBuffArray<SigO>::Buff;
enum{ FAN_I = MatchBuffArray<SigI>::SIZ
, FAN_O = MatchBuffArray<SigO>::SIZ
, SLOT_I = 0
, SLOT_O = 1
, MAXSZ = std::max (uint(FAN_I), uint(FAN_O)) /////////////////////OOO required temporarily until the switch to tuples
};
static constexpr bool hasInput() { return SLOT_I != SLOT_O; }
static constexpr bool hasParam() { return 0 < SLOT_I; }
};
}//(End)Introspection helpers.
template<class FUN>
struct FeedManifold_StorageSetup
: util::NonCopyable
{
};
/**
* Obsolete, to be rewritten /////TICKET #826
*
* Tables of buffer handles and corresponding dereferenced buffer pointers.
* Used within the invocation of a processing node to calculate data.
* The tables are further differentiated into input data buffers and output
* data buffers. The tables are supposed to be implemented as bare "C" arrays,
* thus the array of real buffer pointers can be fed directly to the
* processing function of the respective node.
* Adapter to connect input/output buffers to a processing functor backed by an external library.
* Essentially, this is structured storage tailored specifically to a given functor signature.
* Tables of buffer handles are provided for the downstream code to store results received from
* preceding odes or to pick up calculated data after the invocation. From these BuffHandle entries,
* buffer pointers are retrieved and packaged suitably for use by the wrapped invocation functor.
* This setup is used by a »weaving pattern« within the invocation of a processing node for the
* purpose of media processing or data calculation.
*
* @todo WIP-WIP-WIP 7/24 now reworking the old design in the light of actual render engine requirements...
*/
template<uint N>
template<class FUN>
struct FeedManifold
: util::NonCopyable
: FeedManifold_StorageSetup<FUN>
{
using BuffS = lib::UninitialisedStorage<BuffHandle,N>;
enum{ STORAGE_SIZ = N };
enum{ STORAGE_SIZ = _ProcFun<FUN>::MAXSZ };
using BuffS = lib::UninitialisedStorage<BuffHandle,STORAGE_SIZ>;
BuffS inBuff;
BuffS outBuff;
@ -69,6 +173,63 @@ namespace engine {
/**
* Adapter to handle a simple yet common setup for media processing
* - somehow we can invoke processing as a simple function
* - this function takes two arrays: the input- and output buffers
* @remark this setup is useful for testing, and as documentation example;
* actually the FeedManifold is mixed in as baseclass, and the
* buffer pointers are retrieved from the BuffHandles.
* @tparam MAN a FeedManifold, providing arrays of BuffHandles
* @tparam FUN the processing function
*/
template<class MAN, class FUN>
struct SimpleFunctionInvocationAdapter
: MAN
{
using BuffI = typename _ProcFun<FUN>::BuffI;
using BuffO = typename _ProcFun<FUN>::BuffO;
enum{ N = MAN::STORAGE_SIZ
, FAN_I = _ProcFun<FUN>::FAN_I
, FAN_O = _ProcFun<FUN>::FAN_O
};
static_assert(FAN_I <= N and FAN_O <= N);
using ArrayI = typename _ProcFun<FUN>::SigI;
using ArrayO = typename _ProcFun<FUN>::SigO;
FUN process;
ArrayI inParam;
ArrayO outParam;
template<typename...INIT>
SimpleFunctionInvocationAdapter (INIT&& ...funSetup)
: process{forward<INIT> (funSetup)...}
{ }
void
connect (uint fanIn, uint fanOut)
{
REQUIRE (fanIn == FAN_I and fanOut == FAN_O); //////////////////////////OOO this distinction is a left-over from the idea of fixed block sizes
for (uint i=0; i<FAN_I; ++i)
inParam[i] = & MAN::inBuff[i].template accessAs<BuffI>();
for (uint i=0; i<FAN_O; ++i)
outParam[i] = & MAN::outBuff[i].template accessAs<BuffO>();
}
void
invoke()
{
process (inParam, outParam);
}
};
}} // namespace steam::engine
#endif /*ENGINE_FEED_MANIFOLD_H*/

View file

@ -39,7 +39,7 @@
** @todo relies still on an [obsoleted implementation draft](\ref bufftable-obsolete.hpp)
** @see engine::ProcNode
** @see engine::StateProxy
** @see engine::FeedManifold
** @see engine::FeedManifold_BuffTable_OBSOLETE
** @see nodewiring.hpp interface for building/wiring the nodes
**
*/
@ -110,7 +110,7 @@ namespace engine {
* access the context via the references in this struct, while also using the inherited
* public State interface. The object instance actually used as Invocation is created
* on the stack and parametrised according to the necessities of the invocation sequence
* actually configured. Initially, this real instance is configured without FeedManifold,
* actually configured. Initially, this real instance is configured without FeedManifold_BuffTable_OBSOLETE,
* because the invocation may be short-circuited due to Cache hit. Otherwise, when
* the invocation sequence actually prepares to call the process function of this
* ProcNode, a buffer table chunk is allocated by the StateProxy and wired in.
@ -121,10 +121,10 @@ namespace engine {
Connectivity const& wiring;
const uint outNr;
FeedManifold* feedManifold;
FeedManifold_BuffTable_OBSOLETE* feedManifold;
protected:
/** creates a new invocation context state, without FeedManifold */
/** creates a new invocation context state, without FeedManifold_BuffTable_OBSOLETE */
Invocation (StateClosure_OBSOLETE& callingProcess, Connectivity const& w, uint o)
: StateAdapter(callingProcess),
wiring(w), outNr(o),
@ -137,7 +137,7 @@ namespace engine {
uint buffTabSize() const { return nrO()+nrI(); }
/** setup the link to an externally allocated buffer table */
void setBuffTab (FeedManifold* b) { this->feedManifold = b; }
void setBuffTab (FeedManifold_BuffTable_OBSOLETE* b) { this->feedManifold = b; }
bool
buffTab_isConsistent ()

View file

@ -122,114 +122,13 @@ namespace engine {
using StrView = std::string_view;
using std::forward;
using lib::Literal;
// using lib::Literal;
using lib::Several;
using lib::Depend;
using util::_Fmt;
using util::max;
namespace {// Introspection helpers....
using lib::meta::_Fun;
using lib::meta::is_BinaryFun;
using std::remove_reference_t;
/** Helper to pick up the parameter dimensions from the processing function
* @remark this is the rather simple yet common case that media processing
* is done by a function, which takes an array of input and output
* buffer pointers with a common type; this simple case is used
* 7/2024 for prototyping and validate the design.
* @tparam FUN a _function-like_ object, expected to accept two arguments,
* which both are arrays of buffer pointers (input, output).
*/
template<class FUN>
struct _ProcFun
{
static_assert(_Fun<FUN>() , "something funktion-like required");
static_assert(is_BinaryFun<FUN>() , "function with two arguments expected");
using SigI = remove_reference_t<typename _Fun<FUN>::Args::List::Head>;
using SigO = remove_reference_t<typename _Fun<FUN>::Args::List::Tail::Head>;
template<class ARG>
struct MatchBuffArray
{
static_assert(not sizeof(ARG), "processing function expected to take array-of-buffer-pointers");
};
template<class BUF, size_t N>
struct MatchBuffArray<std::array<BUF*,N>>
{
using Buff = BUF;
enum{ SIZ = N };
};
using BuffI = typename MatchBuffArray<SigI>::Buff;
using BuffO = typename MatchBuffArray<SigO>::Buff;
enum{ FAN_I = MatchBuffArray<SigI>::SIZ
, FAN_O = MatchBuffArray<SigO>::SIZ
, MAXSZ = std::max (uint(FAN_I), uint(FAN_O)) /////////////////////OOO required temporarily until the switch to tuples
};
};
}//(End)Introspection helpers.
/**
* Adapter to handle a simple yet common setup for media processing
* - somehow we can invoke processing as a simple function
* - this function takes two arrays: the input- and output buffers
* @remark this setup is useful for testing, and as documentation example;
* actually the FeedManifold is mixed in as baseclass, and the
* buffer pointers are retrieved from the BuffHandles.
* @tparam MAN a FeedManifold, providing arrays of BuffHandles
* @tparam FUN the processing function
*/
template<class MAN, class FUN>
struct SimpleFunctionInvocationAdapter
: MAN
{
using BuffI = typename _ProcFun<FUN>::BuffI;
using BuffO = typename _ProcFun<FUN>::BuffO;
enum{ N = MAN::STORAGE_SIZ
, FAN_I = _ProcFun<FUN>::FAN_I
, FAN_O = _ProcFun<FUN>::FAN_O
};
static_assert(FAN_I <= N and FAN_O <= N);
using ArrayI = typename _ProcFun<FUN>::SigI;
using ArrayO = typename _ProcFun<FUN>::SigO;
FUN process;
ArrayI inParam;
ArrayO outParam;
template<typename...INIT>
SimpleFunctionInvocationAdapter (INIT&& ...funSetup)
: process{forward<INIT> (funSetup)...}
{ }
void
connect (uint fanIn, uint fanOut)
{
REQUIRE (fanIn == FAN_I and fanOut == FAN_O); //////////////////////////OOO this distinction is a left-over from the idea of fixed block sizes
for (uint i=0; i<FAN_I; ++i)
inParam[i] = & MAN::inBuff[i].template accessAs<BuffI>();
for (uint i=0; i<FAN_O; ++i)
outParam[i] = & MAN::outBuff[i].template accessAs<BuffO>();
}
void
invoke()
{
process (inParam, outParam);
}
};
/**
* Typical base configuration for a Weaving-Pattern chain:
@ -246,7 +145,7 @@ namespace engine {
: util::MoveOnly
{
enum{ MAX_SIZ = _ProcFun<FUN>::MAXSZ };
using Manifold = FeedManifold<MAX_SIZ>;
using Manifold = FeedManifold<FUN>;
using Feed = SimpleFunctionInvocationAdapter<Manifold, FUN>;
std::function<Feed()> buildFeed;
@ -279,7 +178,7 @@ namespace engine {
* for each port, as specified by preceding builder-API invocations.
* @tparam PAR recursive layering for preceding entries
* @tparam BUILD a builder functor to emplace one Turnout instance,
* opaquely embedding all specific data typing.
* thereby opaquely embedding all specific data typing.
* @tparam siz storage in bytes to hold data produced by \a BUILD
*/
template<class PAR, class BUILD, uint siz>

View file

@ -27,11 +27,6 @@ return: 0
END
PLANNED "feed manifold" FeedManifold_test <<END
return: 0
END
PLANNED "Engine Interface basics" EngineInterface_test <<END
END

View file

@ -1,182 +0,0 @@
/*
FeedManifold(Test) - check consistency of buffer table chunk allocation
Copyright (C)
2008, 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 feed-manifold-test.cpp
** unit test \ref FeedManifold_test
*/
#include "lib/test/run.hpp"
#include "lib/error.hpp"
#include "steam/engine/proc-node.hpp"
#include "steam/engine/feed-manifold.hpp"
#include "lib/format-cout.hpp" ////////////////TODO
#include <memory>
using test::Test;
namespace steam {
namespace engine{
namespace test {
namespace { // used internally
const uint TABLE_SIZ = 100000;
const uint CHUNK_MAX = 8000;
const uint WIDTH_MAX = 3;
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation
/** just some crap to pass in as ctor argument... */
template<class E>
struct DummyArray : lib::RefArray<E>
{
E decoy;
E const& operator[] (size_t) const { return decoy; }
size_t size() const { return CHUNK_MAX;}
};
DummyArray<ChannelDescriptor> dummy1;
DummyArray<InChanDescriptor> dummy2;
/** a "hijacked" Connectivity descriptor requesting
* a random number of inputs and outputs */
struct MockSizeRequest
: Connectivity
{
uint ii,oo;
MockSizeRequest()
: Connectivity(dummy1,dummy2,0,NodeID()),
ii(rani (CHUNK_MAX)),
oo(rani (CHUNK_MAX))
{ }
virtual uint getNrI() const { return ii; }
virtual uint getNrO() const { return oo; }
virtual BuffHandle callDown (StateClosure_OBSOLETE&, uint) const
{ throw lumiera::Error("not intended to be called"); }
};
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
void*
detect_start_level (BuffTableStorage& sto)
{
return BuffTableChunk(MockSizeRequest(), sto ).outHandle;
} // address of first available storage element
inline void*
first_behind (BuffTable const& thisChunk, const uint nrI)
{
return &thisChunk.inHandle[nrI];
}
inline bool
not_within(void* candidate, void* lower, void* upper)
{
return (candidate < lower) || (upper <= candidate);
}
bool
consistencyCheck (BuffTable const& b, Connectivity const& num, void* lastLevel)
{
return (b.outHandle == lastLevel ) // storage is allocated continuously
&& (b.outBuff <= b.inBuff ) // input slots are behind the output slots
&& (b.outHandle <= b.inHandle)
&& (b.inBuff == &b.outBuff [num.nrO])
&& (b.inHandle == &b.outHandle[num.nrO])
&& (not_within(b.outBuff, b.outHandle, &b.inHandle[num.nrO])) // storage doesn't overlap
&& (not_within(b.inBuff, b.outHandle, &b.inHandle[num.nrO]))
&& (not_within(b.outHandle, b.outBuff, &b.inBuff[num.nrO]))
&& (not_within(b.inHandle, b.outBuff, &b.inBuff[num.nrO]))
;
}
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
} // (End) internal defs
/***************************************************************//**
* @test create a random pattern of recursive invocations, each
* allocating a chunk out of a global buffer table storage.
* After returning, each allocation should be cleanly
* deallocated and the internal level in the storage vector
* should have doped to zero again.
*/
class FeedManifold_test : public Test
{
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
using PSto = std::unique_ptr<BuffTableStorage>;
PSto pStorage;
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
ulong counter;
void
run(Arg) override
{
seedRand(); ////////////////TODO RLY?
counter = 0;
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
// allocate storage block to be used chunk wise
pStorage.reset (new BuffTableStorage (TABLE_SIZ));
invocation (0, detect_start_level(*pStorage));
pStorage.reset(0); // dtor throws assertion error if corrupted
cout << "BuffTable chunks allocated: "<<counter<< "\n";
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
}
/** recurse down randomly
* until exhausting storage
*/
void invocation (uint consumed, void* lastLevel)
{
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #833
MockSizeRequest numbers;
consumed += numbers.getNrI()+numbers.getNrO();
if (TABLE_SIZ <= consumed)
return; // end recursion
++counter;
BuffTableChunk thisChunk (numbers, *pStorage);
CHECK (consistencyCheck (thisChunk, numbers, lastLevel));
uint nrBranches ( 1 + rani(WIDTH_MAX));
while (nrBranches--)
invocation (consumed, first_behind (thisChunk,numbers.getNrI()));
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #833
}
};
/** Register this test class... */
LAUNCHER (FeedManifold_test, "unit engine");
}}} // namespace steam::engine::test

View file

@ -23453,9 +23453,7 @@
<node CREATED="1666889225532" ID="ID_176130370" MODIFIED="1666889244156" TEXT="direkt eingelagert in die DisplayMetric-Implementierung (mix-in)">
<node CREATED="1666889610112" ID="ID_326538083" MODIFIED="1666902539317">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Name: <b>ZoomMetric</b>
@ -24135,9 +24133,7 @@
<node CREATED="1582992031648" ID="ID_752229981" MODIFIED="1582992037387" TEXT="Maximum + Padding"/>
<node CREATED="1582992060135" ID="ID_446948891" MODIFIED="1582992233901">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
dieses speichern als <font color="#5d1843">TrackBody::<b>contentHeight_</b></font>
@ -24689,9 +24685,7 @@
<node CREATED="1583677385064" ID="ID_822192050" MODIFIED="1583677399994" TEXT="indirekte Hoffnung: die Rekursion wird das l&#xf6;sen">
<node CREATED="1583677461566" ID="ID_786603239" MODIFIED="1583677485360" TEXT="insofern diese auch die Gr&#xf6;&#xdf;e des Canvas &#xe4;ndert">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...und damit eine Rekursion triggert
@ -25577,9 +25571,7 @@
</node>
<node CREATED="1540512410629" ID="ID_1212514016" MODIFIED="1576282358072" TEXT="generisch">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
der ctor des DisplayFrame nimmt einen generischen Typ (Template),
@ -26914,9 +26906,7 @@
</node>
<node CREATED="1677167818898" ID="ID_1345692974" MODIFIED="1677190343808">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
mein Display: <b>90</b>dpi
@ -28693,9 +28683,7 @@
</node>
<node CREATED="1555247377809" ID="ID_281745763" MODIFIED="1576282358064" TEXT="Erwartete Anforderungen...">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<ul>
<li>
@ -30114,9 +30102,7 @@
<node CREATED="1674506772895" ID="ID_1636893876" MODIFIED="1674506790641" TEXT="da sind wir noch am N&#xe4;chsten an den Layout-Berechnungen dran..."/>
<node CREATED="1674506791397" ID="ID_1813341539" MODIFIED="1674506879645" TEXT="und TrackBody kann durch einen Kniff &#x201e;erraten&#x201c; ob er Root-Track ist">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
dann ist n&#228;mlich die startLine = 0;
@ -32476,9 +32462,7 @@
<node CREATED="1563831422209" ID="ID_79374511" MODIFIED="1563831422209" TEXT="/home/hiv/.local/share/themes/PanRosewoodHIV/gtk-3.0/gtk-contained.css"/>
<node CREATED="1563831443895" ID="ID_1181589291" MODIFIED="1563831674186" TEXT="frames: werden flach gezeichnet">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
frame &gt; border,
@ -34129,9 +34113,7 @@
<node CREATED="1584201671057" ID="ID_1545904786" MODIFIED="1584201682507" TEXT="der aber mit dem des Presenters zusammenf&#xe4;llt..."/>
<node CREATED="1584201683192" ID="ID_1482356055" MODIFIED="1584201718557" TEXT="weil man keine aufgedoppelte Referenz auf den ViewHook m&#xf6;chte">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
*) die Referenz steckt n&#228;mlich schon im ViewHookable
@ -36303,9 +36285,7 @@
<node CREATED="1533252737995" ID="ID_763153536" MODIFIED="1533252745030" TEXT="application.cc Zeile 160"/>
<node CREATED="1533252758840" ID="ID_346690959" MODIFIED="1576282358031" TEXT="signal_activate()">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
&#160;&#160;//We cannot add and show the window until the GApplication::activate signal
@ -37431,9 +37411,7 @@
</node>
<node CREATED="1615558696844" ID="ID_1299483978" MODIFIED="1615558784590" TEXT="Ende der Geste mu&#xdf; zuverl&#xe4;ssig erkannt werden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...sonst bleibt ein inkonsistender Zustand irgendwo &quot;h&#228;ngen&quot;.<br />Leider ist das nun das bekannterma&#223;en unl&#246;sbare Problem eines sicheren Verbindungsabbaus, und wir m&#252;ssen uns deshalb mit einem Timeout, oder re-check-Mechanismus behelfen
@ -38031,9 +38009,7 @@
</node>
<node CREATED="1617569148000" ID="ID_1188278692" MODIFIED="1617569598605" TEXT="Widget vor&#xfc;bergehend verlassen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Wenig problematisch ist dieser Fall, wenn der Button gedr&#252;ckt bleibt und wir irgendwann zur&#252;ckkommen; dann setzt sich das Dragging eben an der Stelle fort. Wenn dagegen der Button au&#223;erhalb released wurde, handelt es sich tats&#228;chlich um den 3.Fall &#8213; wenn aber eine normale Maus-Bewegung sp&#228;ter wieder &#252;ber das Widget f&#228;hrt, wird das Dragging fortgesetzt, f&#228;lschlicherweise.
@ -38760,9 +38736,7 @@
<icon BUILTIN="stop-sign"/>
<node CREATED="1619893616079" ID="ID_1820351141" MODIFIED="1619894138543" TEXT="ehr nicht....">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...sobald irgendwo eine Abstraktionsbarriere errichtet wird, mu&#223; mindestens ein Call indirekt oder virtuell sein....
@ -38944,9 +38918,7 @@
</node>
<node COLOR="#435e98" CREATED="1620565871398" ID="ID_574697565" MODIFIED="1620565887201">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Name: <b>GestureObserver</b>
@ -87558,7 +87530,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="yes"/>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1733766910569" ID="ID_462136727" MODIFIED="1734041957415" TEXT="&#x27f9; gebraucht wird">
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1733766910569" ID="ID_462136727" MODIFIED="1734041986220" TEXT="&#x27f9; gebraucht wird">
<linktarget COLOR="#4c74b0" DESTINATION="ID_462136727" ENDARROW="Default" ENDINCLINATION="19;2576;" ID="Arrow_ID_402192560" SOURCE="ID_303076243" STARTARROW="None" STARTINCLINATION="-818;-116;"/>
<icon BUILTIN="yes"/>
<node COLOR="#435e98" CREATED="1733766926415" FOLDED="true" ID="ID_1686613162" MODIFIED="1734041954497" TEXT="Library f&#xfc;r heterogene verkn&#xfc;pfte Storage-Bl&#xf6;cke">
<icon BUILTIN="yes"/>
@ -91402,15 +91375,14 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...weil wir SLOT_I &#8788; SLOT_O setzen (wichtig!), wenn es keinen Input gibt; es gibt nur zwei F&#228;lle ohne Parameter, und die lsassen sich damit in diesen Test zusammenfassen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734197949703" ID="ID_614756914" MODIFIED="1734197958950" TEXT="in zwei Schritten umstellen">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1734197960677" ID="ID_928664533" MODIFIED="1734198014600" TEXT="Schritt-1 : neues Interface">
<node CREATED="1734198655392" ID="ID_1607922853" MODIFIED="1734198689626" TEXT="kann ArgI|O sofort umbenennen &#x27fc; SigI|O">
<node COLOR="#338800" CREATED="1734198655392" ID="ID_1607922853" MODIFIED="1734213039477" TEXT="kann ArgI|O sofort umbenennen &#x27fc; SigI|O">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -91419,13 +91391,15 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#5b280f" CREATED="1734210007691" ID="ID_824110488" MODIFIED="1734210121348" TEXT="dann ArrayI|O ebenfalls auf SigI|O zur&#xfc;ckf&#xfc;hren">
<icon BUILTIN="button_cancel"/>
<node CREATED="1734210123451" ID="ID_1200047403" MODIFIED="1734210132804" TEXT="besser sp&#xe4;ter gleich ganz zur&#xfc;ckbauen"/>
<node CREATED="1734210134329" ID="ID_601691761" MODIFIED="1734210146556" TEXT="denn das einheitliche BuffI / BuffO f&#xe4;llt weg"/>
</node>
<node CREATED="1734210231821" ID="ID_1763909056" MODIFIED="1734210238791" TEXT="Parameter N zur&#xfc;ckbauen">
<node COLOR="#338800" CREATED="1734210231821" ID="ID_1763909056" MODIFIED="1734213037095" TEXT="Parameter N zur&#xfc;ckbauen">
<icon BUILTIN="button_ok"/>
<node CREATED="1734210771451" ID="ID_577304307" MODIFIED="1734210825368" TEXT="etwas kniffelig...">
<richcontent TYPE="NOTE"><html>
<head/>
@ -91444,8 +91418,11 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1734211213967" ID="ID_700968343" MODIFIED="1734211234769" TEXT="das wird in terminaler BuilderOp ohnehin so sichergestellt"/>
</node>
</node>
<node CREATED="1734213045001" ID="ID_787577161" MODIFIED="1734213055524" TEXT="sonstige Signatur bereits anlegen"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734197971763" ID="ID_1977596531" MODIFIED="1734197997067" TEXT="Schritt-2 : tats&#xe4;chliche Flexibilit&#xe4;t">
<node CREATED="1734214199422" ID="ID_525858909" MODIFIED="1734214224775" TEXT="stellt sich wieder (zum x-ten Mal) die Frage nach dem Layout der FeedManifold"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734197971763" ID="ID_1977596531" MODIFIED="1734197997067" TEXT="Schritt-2 : tats&#xe4;chliche Flexibilit&#xe4;t"/>
</node>
</node>
<node CREATED="1734191257640" ID="ID_1241232500" MODIFIED="1734191262543" TEXT="_ParamFun"/>
@ -91489,8 +91466,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<b><font color="#840c28">Jede m&#246;gliche Funktions-Signatur erzeugt eine separate Turnout-Instanz</font></b>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#d1aea3" COLOR="#523d5f" CREATED="1734193627969" ID="ID_1410642266" MODIFIED="1734193725381">
<richcontent TYPE="NODE"><html>
@ -91500,8 +91476,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
das Media-Lib-Plugin is Problemzone und Ansatzpunkt bzgl <b>Template-Bloat</b>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="bell"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1734194266853" HGAP="31" ID="ID_17132445" MODIFIED="1734194303269" TEXT="aber: auch Param-Funktor spielt nun eine Rolle..." VSHIFT="-6">
<icon BUILTIN="idea"/>
@ -91524,6 +91499,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<edge COLOR="#ff5d00" STYLE="sharp_linear"/>
<arrowlink COLOR="#fe512a" DESTINATION="ID_1353514662" ENDARROW="Default" ENDINCLINATION="1101;-48;" ID="Arrow_ID_1188578396" STARTARROW="None" STARTINCLINATION="-832;60;"/>
<arrowlink COLOR="#f94771" DESTINATION="ID_320753034" ENDARROW="None" ENDINCLINATION="1267;-43;" ID="Arrow_ID_735039883" STARTARROW="None" STARTINCLINATION="-749;52;"/>
<linktarget COLOR="#ec4160" DESTINATION="ID_1378608706" ENDARROW="Default" ENDINCLINATION="-191;526;" ID="Arrow_ID_1877600264" SOURCE="ID_193479960" STARTARROW="None" STARTINCLINATION="-161;11;"/>
<icon BUILTIN="bell"/>
<node CREATED="1721239003353" HGAP="17" ID="ID_611651911" MODIFIED="1734194192181" STYLE="fork" TEXT="Struktur des Mapping im konkreten Media-Lib-Plugin" VSHIFT="6">
<font NAME="SansSerif" SIZE="8"/>
@ -91554,8 +91530,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...denn exakt an dieser Stelle ist das Prototyping bis jetzt gescheitert ... wir konnten bisher nur eine &#8222;d&#228;mliche&#8220; Dummy-Funktion binden; sobald eine <i>echte Dummy-Funktion</i>&#160;eingebunden werden sollte, bin ich darauf aufmerksam geworden, das eine solche Funktion zwangsl&#228;ufig auch weitere Parameter brauchen wird, und nach einer weiteren, langen &#8222;Denk-Schleife&#8220; bin ich hier wo ich grad bin
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1734199504590" ID="ID_1634729169" MODIFIED="1734199538866" TEXT="das &#x201e;riecht&#x201c; nach einem Bug.....">
@ -91577,13 +91552,149 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734214260094" ID="ID_1731140529" MODIFIED="1734214303534" TEXT="mu&#xdf; die Storage neu bestimmen">
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734214271580" ID="ID_1045815708" MODIFIED="1734214294015" TEXT="Nochmal &#xfc;ber die Rolle der FeedManifold nachdenken">
<icon BUILTIN="yes"/>
<node CREATED="1734214319422" ID="ID_405803529" MODIFIED="1734214333944" TEXT="sie ist und bleibt die dynamische Invocation-Storage"/>
<node CREATED="1734214355412" ID="ID_920827020" MODIFIED="1734214364155" TEXT="und zwar f&#xfc;r eine Port-Aktivierung">
<node CREATED="1734214366543" ID="ID_1929288087" MODIFIED="1734214382617" TEXT="(nicht insgesamt, daf&#xfc;r haben wir jetzt HeteroData)">
<font NAME="SansSerif" SIZE="10"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734196584853" ID="ID_1949228582" MODIFIED="1734196598973" TEXT="Anordnung des Parameters f&#xfc;r den Typ-Funktor bedenken">
<node CREATED="1734214495098" ID="ID_732806441" MODIFIED="1734214505029" TEXT="sammelt die konkreten BuffHandles"/>
<node COLOR="#5b280f" CREATED="1734214523864" ID="ID_1778758115" MODIFIED="1734214559724" TEXT="sammelt auch das Mapping auf Buffer-Pointer-Array">
<icon BUILTIN="button_cancel"/>
<node CREATED="1734214564230" ID="ID_1649326795" MODIFIED="1734214572735" TEXT="das hat sich mehr oder weniger aufgel&#xf6;st"/>
<node CREATED="1734214574266" ID="ID_1114540743" MODIFIED="1734214587710" TEXT="hier gibt es nun stets reiness 1:1 Mapping"/>
</node>
<node CREATED="1734214675415" ID="ID_409809945" MODIFIED="1734214688617" TEXT="ist &#xbb;Sammeln&#xab; weiterhin sinnvoll?">
<node CREATED="1734214690837" ID="ID_1960272178" MODIFIED="1734214702194" TEXT="Frage betrifft vor allem die Parameter"/>
<node CREATED="1734214703539" ID="ID_680406365" MODIFIED="1734214725244" TEXT="wenn man ParamFunktor zu Beginn auswertet &#x27f9; Param-Tupel mu&#xdf; irgendwo liegen"/>
<node CREATED="1734214727869" ID="ID_1046636764" MODIFIED="1734224345261" TEXT="wenn man sowohl Buffer*, alsauch ParamFunktor sp&#xe4;t auswertet &#x27f9; direkt in invoke()"/>
<node CREATED="1734214826314" ID="ID_1212520344" MODIFIED="1734214835509" TEXT="schwer zu entscheiden &#x27f9; ist ein Freiheitsgrad"/>
<node CREATED="1734214838441" ID="ID_1382984783" MODIFIED="1734214854714" TEXT="k&#xf6;nnte durch das WeavingPattern gesteuert werden"/>
</node>
</node>
<node CREATED="1734221531913" ID="ID_403160908" MODIFIED="1734221552785" TEXT="verschmelzen mit dem InvocationAdapter">
<node CREATED="1734221555701" ID="ID_1326995703" MODIFIED="1734224314109" TEXT="im Grund war sie das doch schon immer">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Der Name und die Vorstellung hat nun mehrfach gewechselt, aber es ging doch letztlich immer darum, eine unbekannte Library-Funktion so aufzur&#252;sten, da&#223; man sie mit einem generischen Schema zu fassen bekommt. Auch die Idee, die Buffer-Pointer in ein Array zu packen, geh&#246;rt letztlich zu diesem Ansatz. Der dar&#252;ber hinausgehende Teil der urspr&#252;nglichen Idee, dieses Strukur auch zu &#187;bespielen&#171; ist jetzt in der &#187;weaving&#171;-Metapher aufgegangen &#8212; und dieses fortschreitende Wechselspiel in der Speicherbelegung findet dar&#252;ber ja nun tats&#228;chlich statt.
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1734224433562" ID="ID_1575355082" MODIFIED="1734224522138" TEXT="dem zufolge &#x27f9; auch die Storage f&#xfc;r den Funktionsaufruf geh&#xf6;rt hierher"/>
<node CREATED="1734224528900" ID="ID_623526235" MODIFIED="1734224541463" TEXT="und die Storage f&#xfc;r die zwei Funktoren"/>
<node CREATED="1734224597611" ID="ID_1784914864" MODIFIED="1734224787262" TEXT="viel davon k&#xf6;nnte man verstecken &#x2014; halte aber Klarheit f&#xfc;r wichtiger hier">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
beispielsweise k&#246;nnte man den Parameter-Funktor im allgemeinen Funktor verstecken, und dann auch gleich noch den Scope, in dem der eigentliche Aufruf-Adapter gebaut wird. Man w&#252;rde sich damit ein paar Bytes pro Node-Level sparen, um den Preis eines trickreichen Konstrukts ineinander geschachtelter Funktoren. Da gef&#228;llt es mir doch besser, die Funktoren und die Storage in einem Objekt nebeneinander abzulegen, zusammen mit Methoden, die von einem jeweiligen Weaving-Pattern genutzt werden k&#246;nnten
</p>
</body>
</html></richcontent>
<icon BUILTIN="yes"/>
</node>
<node CREATED="1734225883763" ID="ID_774927726" MODIFIED="1734225898717" TEXT="w&#xe4;re demnach allein durch die Funktions-Signatur typisiert">
<node CREATED="1734225912880" ID="ID_1175387920" MODIFIED="1734225931289" TEXT="diese ist selber die essentielle &#xbb;Setup-Spec&#xab;"/>
<node CREATED="1734225942383" ID="ID_1049595713" MODIFIED="1734225949486" TEXT="hinzu kommt noch der konkrete Funktor"/>
<node CREATED="1734226007275" ID="ID_193479960" MODIFIED="1734226139339" TEXT="den k&#xf6;nnte man einkapseln &#x2014; oder nicht">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
hier zeigt sich immer wieder der gleiche Trade-off: zus&#228;tzliche Indirektion vs. Template-Bloat
</p>
</body>
</html>
</richcontent>
<arrowlink COLOR="#ec4160" DESTINATION="ID_1378608706" ENDARROW="Default" ENDINCLINATION="-191;526;" ID="Arrow_ID_1877600264" STARTARROW="None" STARTINCLINATION="-161;11;"/>
</node>
</node>
</node>
</node>
<node CREATED="1734226154995" ID="ID_1824135693" MODIFIED="1734226165663" TEXT="Konsequenzen">
<node CREATED="1734226167432" ID="ID_152918477" MODIFIED="1734226177431" TEXT="FeedManifold ist der InvocationAdapter"/>
<node CREATED="1734226179091" ID="ID_656635473" MODIFIED="1734226192693" TEXT="Parametrisiert wird mit dem konkreten Funktor"/>
<node CREATED="1734226218750" ID="ID_1815522792" MODIFIED="1734226239453" TEXT="daraus mu&#xdf; sich FeedManifold komplett selbst konfigurieren"/>
<node CREATED="1734226245002" ID="ID_1729798414" MODIFIED="1734226264004" TEXT="so wie praktisch bereits implementiert &#x2014; per Traits-Template"/>
<node CREATED="1734276290111" ID="ID_1748820043" MODIFIED="1734276341934" TEXT="&#xfc;bernimmt damit auch die Rolle der Typ-Steuerung">
<arrowlink COLOR="#3f4fb7" DESTINATION="ID_814254927" ENDARROW="Default" ENDINCLINATION="48;-164;" ID="Arrow_ID_584314736" STARTARROW="None" STARTINCLINATION="-244;14;"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734226596427" ID="ID_1730595360" MODIFIED="1734226615270" TEXT="Struktur neu aufbauen">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734226295084" ID="ID_43554059" MODIFIED="1734226617257" TEXT="FeedManifold wird aus mehreren Layern zusammengesetzt">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1734226447447" ID="ID_1121321956" MODIFIED="1734226473215" TEXT="Param-Storage (optional)"/>
<node CREATED="1734226474754" ID="ID_334989563" MODIFIED="1734226483630" TEXT="Input-Storage (optional)"/>
<node CREATED="1734226485049" ID="ID_1102989908" MODIFIED="1734226491735" TEXT="Output-Storage (mandatory)"/>
<node CREATED="1734226511062" ID="ID_1899717504" MODIFIED="1734226537968" TEXT="ProcFunctor (mandatory)"/>
<node CREATED="1734226564932" ID="ID_696691756" MODIFIED="1734226570322" TEXT="Constructor (static)"/>
</node>
<node CREATED="1734226618888" ID="ID_758716189" MODIFIED="1734226624083" TEXT="Operationen">
<node CREATED="1734226624933" ID="ID_1270095402" MODIFIED="1734282238319" TEXT="buildFeed(TurnoutSystem&amp;) &#x2014; statisch"/>
<node CREATED="1734226650379" ID="ID_1952959461" MODIFIED="1734226679547" TEXT="connect() &#x2014; bef&#xfc;llt Aufruf-Struktur"/>
<node CREATED="1734226680799" ID="ID_435218687" MODIFIED="1734226694521" TEXT="invoke() &#x2014; f&#xfc;hrt ProcFun aus"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734276259404" ID="ID_814254927" MODIFIED="1734276322192" TEXT="Typ-Steuerung geht in die FeedManifold">
<linktarget COLOR="#3f4fb7" DESTINATION="ID_814254927" ENDARROW="Default" ENDINCLINATION="48;-164;" ID="Arrow_ID_584314736" SOURCE="ID_1748820043" STARTARROW="None" STARTINCLINATION="-244;14;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1734282520970" ID="ID_1381423523" MODIFIED="1734282533060" TEXT="Aufgabe: flexible Storage-Struktur bereitstellen">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734282535179" ID="ID_1723358537" MODIFIED="1734282603738" TEXT="l&#xe4;uft wohl hinaus auf ein compile-time conditional mix-in">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734282677568" ID="ID_1599850203" MODIFIED="1734282692157" TEXT="Konfigurations-Basis-Klasse dazwischen schalten">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1734282698342" ID="ID_1166367446" MODIFIED="1734283404476" TEXT="Aufgabe: Konstruktor-Parameter h&#xe4;ngen von der Konfiguration ab">
<linktarget COLOR="#fd0e40" DESTINATION="ID_1166367446" ENDARROW="Default" ENDINCLINATION="-134;6;" ID="Arrow_ID_1369831225" SOURCE="ID_151535815" STARTARROW="None" STARTINCLINATION="-270;14;"/>
<icon BUILTIN="clanbomber"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734196584853" ID="ID_1949228582" MODIFIED="1734283386060" TEXT="Anordnung des Parameters f&#xfc;r den Param-Funktor bedenken">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1734196602500" ID="ID_1286582916" MODIFIED="1734196617685" TEXT="er sollte von der Funktion separierbar sein"/>
<node CREATED="1734196618969" ID="ID_640106632" MODIFIED="1734196896465" TEXT="oder alternativ komplett von der Funktion abgeleitet">
<linktarget COLOR="#7d7fd1" DESTINATION="ID_640106632" ENDARROW="Default" ENDINCLINATION="126;7;" ID="Arrow_ID_1055059428" SOURCE="ID_1457253482" STARTARROW="None" STARTINCLINATION="131;7;"/>
</node>
<node CREATED="1734282773559" ID="ID_1670731285" MODIFIED="1734282794445" TEXT="FeedManifold braucht ebenfalls einen Konstruktor-Funktor"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1734282817701" ID="ID_856985880" MODIFIED="1734283524688" TEXT="beide k&#xf6;nnten automatisch zusammengelegt werden">
<icon BUILTIN="forward"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734282837578" ID="ID_151535815" MODIFIED="1734283498358" TEXT="Problem mit den Konstruktor-Argumenten w&#xe4;re zu l&#xf6;sen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Dahinter verbirgt sich ein <i>architektonisches Problem:</i>&#160;die FeedManifold ist ein Bindeglied, und daher bewirkt jeder Konstruktor-Parameter eine Einbindung in Detail-Strukturen &#8212; <i>problematisch</i>&#160;dabei bleibt, da&#223; die Einbindung nach beiden Seiten erfolgen kann. Konkret bedeutet dies....
</p>
<ul>
<li>
von der usage-site her, also dem WeavingPattern mu&#223; die FeedManifold mit einer <font color="#1c0c8e" face="Monospaced">TurnoutSystem&amp;</font>&#160;versorgt werden
</li>
<li>
wohingegen von der Definitions-Seite her ggfs. Funktor-Objekte mit eingepackten Detail-Bindings &#252;bernommen werden m&#252;ssen
</li>
<li>
und hier ist auch noch Variabilit&#228;t gegeben: ein Funktor f&#252;r Parameter ist optional, aber <i>wenn er gegeben ist,</i>&#160;dann <i>kann (nicht mu&#223;)</i>&#160;es sein, da&#223; er ebenfalls Init-Argumente braucht, <i>die dann aber ziemlich sicher aus einem anderen Struktur-Kontext stammen, </i>n&#228;mlich aus der <font color="#9c0542">internen Logik des Builders</font>, nicht aus dem <font color="#9c0542">Library-Plug-in</font>
</li>
</ul>
</body>
</html>
</richcontent>
<arrowlink COLOR="#fd0e40" DESTINATION="ID_1166367446" ENDARROW="Default" ENDINCLINATION="-134;6;" ID="Arrow_ID_1369831225" STARTARROW="None" STARTINCLINATION="-270;14;"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1734132967020" ID="ID_1354544776" MODIFIED="1734133516984" TEXT="Param-Tuple in FeedManifold aufnehmen">
@ -91602,8 +91713,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...insofern dann alle F&#228;lle mit gleicher Signatur zusammenfallen; f&#252;r die h&#228;ufigsten F&#228;lle (wie z.B. ein einziger int-Parameter) erwarte ich einen starken Hebel
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1734196763636" ID="ID_1457253482" MODIFIED="1734196896465" TEXT="tats&#xe4;chliche Wirksamkeit h&#xe4;ngt von realem Nutzen ab">
<arrowlink COLOR="#7d7fd1" DESTINATION="ID_640106632" ENDARROW="Default" ENDINCLINATION="126;7;" ID="Arrow_ID_1055059428" STARTARROW="None" STARTINCLINATION="131;7;"/>
@ -94563,7 +94673,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733429229455" ID="ID_1168009537" MODIFIED="1733429237190" TEXT="Implementierung">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733429241884" ID="ID_303076243" MODIFIED="1733429265121" TEXT="Daten-Zugriff">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733429241884" ID="ID_303076243" MODIFIED="1734041986220" TEXT="Daten-Zugriff">
<arrowlink COLOR="#4c74b0" DESTINATION="ID_462136727" ENDARROW="Default" ENDINCLINATION="19;2576;" ID="Arrow_ID_402192560" STARTARROW="None" STARTINCLINATION="-818;-116;"/>
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733429249083" ID="ID_1856105582" MODIFIED="1733429265122" TEXT="Daten-Registrierung">
@ -96035,9 +96146,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1733106602966" ID="ID_526542488" MODIFIED="1733423899516" TEXT="Gedankenspiel: die Idee vom Visitor adaptieren?">
<node COLOR="#5b280f" CREATED="1733106602966" ID="ID_526542488" MODIFIED="1734220796177" TEXT="Gedankenspiel: die Idee vom Visitor adaptieren?">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="help"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1733106669525" ID="ID_111473197" MODIFIED="1733423899516">
<richcontent TYPE="NODE"><html>
<head/>
@ -96054,6 +96166,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1733107165507" ID="ID_460554715" MODIFIED="1733423899516" TEXT="generischer Turnout verwendet spezielles TurnoutSystem in generischer Weise"/>
<node CREATED="1733107202581" ID="ID_1812738775" MODIFIED="1733423899517" TEXT="spezieller Turnout verwendet spezielles TurnoutSystem typsicher und speziell"/>
</node>
<node COLOR="#5b280f" CREATED="1734220806748" ID="ID_1300564808" MODIFIED="1734220834709" TEXT="nicht weiter verfolgt, erscheint unattraktiv...">
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
</node>
</node>
</node>
<node CREATED="1733352649521" ID="ID_1778037852" MODIFIED="1733423899517" TEXT="wie Parameter berechnet werden ist flexibel">