Invocation: add some test-data manipulation functions

This is the first step towards a »Test Domain Ongology« #1372,
which is a systematic arrangement of test-dummy functionality assumed
to mirror the actual media processing functionality present in external libs.

Each media-processing library not only provides functions to crunch data,
but also establishes a framework of entities and classification to determine
what »media« is an how it is structured and can be generated, transformed
and qualified. Since a essential goal for Lumiera is to be **library agnostic,**
it is important to avoid naïvely to take some popular library's choices
as universal truth regarding structure and nature of »media« as such.
Rather, the architecture of the Lumiera Render Engine must be kept
sufficiently open to accommodate the working style of various libraries,
even ones not known today.

To validate this architectural openness, we use a set of test functions
unrelated to any existing library to validate access to and usage of
rendering functionality — followed by further steps to adopt existing
popular libraries like **FFmpeg** or **Gstreamer**, without tilting
the basic structure of the Render Engine one way or the other.
This commit is contained in:
Fischlurch 2024-11-05 21:23:13 +01:00
parent a84dbd7bfb
commit c04a465134
6 changed files with 213 additions and 63 deletions

View file

@ -44,6 +44,72 @@ namespace test {
const string DUMMY_FUN_ID{"dummyFun(TestFrame)"};
/* ========= Dummy implementation of Media processing ========= */
/**
* @param buff a sufficiently sized allocation to place the result data into
* @param frameNr the frame of the »source feed« to generate (determines actual random data)
* @param flavour a further seed parameter to determine the actual (reproducibly) random data
*/
void
generateFrame (TestFrame* buff, size_t frameNr, uint flavour)
{
REQUIRE (buff);
new(buff) TestFrame{uint(frameNr), flavour};
}
/**
* @param chanCnt size of the array of frames to generate
* @param buffArry pointer to an allocation sufficiently sized to hold `TestFrame[chanCnt]`
* @param frameNr the frame of the »source feed« to use commonly on all those frames in the output
* @param flavour a further seed parameter used as starting offest for the output's `family` parameters
* @remark this is a variation of the [dummy data generator](\ref #generateFrame),
* which immediately generates a planar block of related frames with random data,
* all seeded with the _same_ `frameNr` and _consecutive_ `family` parameters,
* which will be offset commonly by adding the \a flavour parameter.
*/
void
generateMultichan (uint chanCnt, TestFrame* buffArry, size_t frameNr, uint flavour)
{
REQUIRE (buffArry);
for (uint i=0; i<chanCnt; ++i)
new(buffArry+i) TestFrame{uint(frameNr), flavour+i};
}
/**
* @param out existing allocation to place the generated TestFrame into
* @param in allocation holding the input TestFrame data
* @param param parameter to control the data manipulation (to be multiplied into the data)
* @remark this function emulates media data processing: each byte of the input data is multiplied
* with the given \a param, wrapping each result into the corresponding output byte. The
* generated result TestFrame is marked with a valid checksum.
*/
void
manipulateFrame (TestFrame* out, TestFrame* in, int param)
{
REQUIRE (in);
REQUIRE (out);
for (size_t i=0; i < in->data().size(); ++i)
out->data()[i] = char(param * in->data()[i]);
}
/**
* @param out existing allocation to receive the calculated result TestFrame
* @param srcA a buffer holding the input data for feed-A
* @param srcB a buffer holding the input data for feed-B
* @param mix degree of mixing (by integer arithmetics): 100 means 100% feed-B
* @remark this function emulates a mixing or overlaying operation:
* each result byte is the linear interpolation between the corresponding inputs.
*/
void
combineFrames (TestFrame* out, TestFrame* srcA, TestFrame* srcB, int mix)
{
REQUIRE (srcA);
REQUIRE (srcB);
REQUIRE (out);
for (size_t i=0; i < srcA->data().size(); ++i)
out->data()[i] = char((1-mix) * srcA->data()[i] + mix * srcB->data()[i]);
}

View file

@ -30,6 +30,7 @@
#include "lib/error.hpp"
#include "lib/depend.hpp"
#include "steam/engine/testframe.hpp"
#include <array>
@ -41,6 +42,20 @@ namespace engine{
namespace test {
using std::string;
/** produce sequences of frames with (reproducible) random data */
void generateFrame (TestFrame* buff, size_t frameNr, uint flavour);
/** produce planar multi channel output of random data frames */
void generateMultichan (uint chanCnt, TestFrame* buffArry, size_t frameNr, uint flavour);
/** »process« random frame date by multiply-wrapping with a parameter */
void manipulateFrame (TestFrame* out, TestFrame* in, int param);
/** mix two random data frames by a parameter-controlled proportion */
void combineFrames (TestFrame* out, TestFrame* srcA, TestFrame* srcB, int mix);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Dummy / Placeholder
using NoArg = std::array<char*, 0>;

View file

@ -64,7 +64,7 @@ namespace test {
* TestFrame instances can be created right away, without any
* external library dependencies. A test frame is automatically
* filled with random data; multiple frames are arranged in
* sequences and channels, causing the random data to be
* sequences and channels, causing the random data to be
* reproducible yet different in each frame.
*
* To ease writing unit tests, TestFrame provides comparison
@ -77,7 +77,7 @@ namespace test {
{
virtual void
run (Arg)
run (Arg)
{
verifyBasicProperties();
verifyFrameLifecycle();

View file

@ -25,8 +25,8 @@
*/
#include "steam/engine/testframe.hpp"
#include "lib/error.hpp"
#include "steam/engine/testframe.hpp"
#include <boost/random/linear_congruential.hpp>
@ -83,7 +83,7 @@ namespace test {
* Some tests might rely on the actual memory locations, using the
* test frames to simulate a real input frame data stream.
* @param CHA the maximum number of channels to expect
* @param FRA the maximum number of frames to expect per channel
* @param FRA the maximum number of frames to expect per channel
* @warning choose the maximum number parameters wisely.
* We're allocating memory to hold a table of test frames
* e.g. sizeof(TestFrame) * 20channels * 100frames 2 MiB
@ -193,7 +193,7 @@ namespace test {
: distinction_(o.distinction_)
, stage_(CREATED)
{
memcpy (data_, o.data_, BUFFSIZ);
memcpy (buffer_, o.buffer_, BUFFSIZ);
}
TestFrame&
@ -205,7 +205,7 @@ namespace test {
{
distinction_ = o.distinction_;
stage_ = CREATED;
memcpy (data_, o.data_, BUFFSIZ);
memcpy (buffer_, o.buffer_, BUFFSIZ);
}
return *this;
}
@ -245,7 +245,7 @@ namespace test {
TestFrame::contentEquals (TestFrame const& o) const
{
for (uint i=0; i<BUFFSIZ; ++i)
if (data_[i] != o.data_[i])
if (data()[i] != o.data()[i])
return false;
return true;
}
@ -255,7 +255,7 @@ namespace test {
{
PseudoRandom gen(distinction_);
for (uint i=0; i<BUFFSIZ; ++i)
if (data_[i] != char(gen() % CHAR_MAX))
if (data()[i] != char(gen() % CHAR_MAX))
return false;
return true;
}
@ -265,7 +265,7 @@ namespace test {
{
PseudoRandom gen(distinction_);
for (uint i=0; i<BUFFSIZ; ++i)
data_[i] = char(gen() % CHAR_MAX);
data()[i] = char(gen() % CHAR_MAX);
}

View file

@ -29,8 +29,9 @@
#define STEAM_ENGINE_TESTFRAME_H
#include <cstdlib>
#include <stdint.h>
#include "lib/integral.hpp"
#include <array>
namespace steam {
@ -63,12 +64,15 @@ namespace test {
CREATED, EMITTED, DISCARDED
};
static const size_t BUFFSIZ = 1024;
static constexpr size_t BUFFSIZ = 1024;
using _Arr = std::array<char,BUFFSIZ>;
uint64_t distinction_;
StageOfLife stage_;
char data_[BUFFSIZ];
/** inline storage buffer for the payload media data */
alignas(uint64_t)
std::byte buffer_[sizeof(_Arr)];
public:
~TestFrame();
@ -95,6 +99,10 @@ namespace test {
friend bool operator== (TestFrame const& f1, TestFrame const& f2) { return f1.contentEquals(f2); }
friend bool operator!= (TestFrame const& f1, TestFrame const& f2) { return !f1.contentEquals(f2); }
/** Array-style direct access to the payload data */
_Arr& data() { return * std::launder (reinterpret_cast<_Arr* > (&buffer_)); }
_Arr const& data() const { return * std::launder (reinterpret_cast<_Arr const*> (&buffer_)); }
private:
bool contentEquals (TestFrame const& o) const;

View file

@ -13740,9 +13740,7 @@
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...will sagen,
@ -14518,9 +14516,7 @@
<node CREATED="1529018093267" ID="ID_389715312" MODIFIED="1529018099078" TEXT="Hybrid-L&#xf6;sung"/>
<node CREATED="1529018100234" ID="ID_1628139323" MODIFIED="1529018119792">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
als <i>Subklasse</i>&#160;von UICoord
@ -16100,9 +16096,7 @@
<node CREATED="1523224222477" ID="ID_769675431" MODIFIED="1523224258636" TEXT="reinen Pointer liefern?"/>
<node CREATED="1523224259839" ID="ID_1984912464" MODIFIED="1576282358108" TEXT="wer braucht Fehler?">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Zwei F&#228;lle sind hier zu unterscheiden:
@ -18604,9 +18598,7 @@
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1664028546726" ID="ID_1159408504" MODIFIED="1664028775997" TEXT="Enscheidung: &#xbb;pull&#xab;-API">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
In Summe viel eleganter.
@ -46714,9 +46706,7 @@
<icon BUILTIN="help"/>
<node CREATED="1448658692023" ID="ID_888978058" MODIFIED="1576282358013" TEXT="generische Commands">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
die Frage ist, wie generisch ist eigentlich ein Command-Aufruf selber?
@ -47369,9 +47359,7 @@
<node CREATED="1458408895756" ID="ID_1422093195" MODIFIED="1533608413859" TEXT="polymorph">
<node CREATED="1458408909594" ID="ID_447360746" MODIFIED="1458409828754">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Mutator verwendet einen <i>Binder</i>
@ -47859,9 +47847,7 @@
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
this is (probably) the only operation which entirely messes up the mutator state
@ -48076,9 +48062,7 @@
<node CREATED="1456011595024" ID="ID_1268079925" MODIFIED="1456011598819" TEXT="mu&#xdf; konsumieren"/>
<node CREATED="1456011599455" ID="ID_862262812" MODIFIED="1456011634435">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Verb mu&#223; den
@ -48305,9 +48289,7 @@
</node>
<node CREATED="1456424962239" ID="ID_933613304" MODIFIED="1575133328492" TEXT="einseitige Fernsteuerung">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
das ist die schlankeste L&#246;sung, die &#228;sthetisch befriedigt.
@ -57023,9 +57005,29 @@
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786946155" ID="ID_1878547941" MODIFIED="1728787040942" TEXT="Datenlayout und Alignment">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1730835658062" ID="ID_1432722861" MODIFIED="1730835681825" TEXT="festes 64bit-Alingment">
<linktarget COLOR="#5b9aaa" DESTINATION="ID_1432722861" ENDARROW="Default" ENDINCLINATION="63;7;" ID="Arrow_ID_1569718697" SOURCE="ID_1990276915" STARTARROW="None" STARTINCLINATION="61;0;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1728787025826" ID="ID_1972770219" MODIFIED="1730835694593" TEXT="Accessor und Iteration">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1730835574802" ID="ID_244997396" MODIFIED="1730835699892" TEXT="Accessor als std::array">
<icon BUILTIN="yes"/>
</node>
<node COLOR="#435e98" CREATED="1730835595677" ID="ID_1990276915" MODIFIED="1730835687929" TEXT="analog zu uninitialised-storage">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
also per reinterpret-cast mit std::launder, storage als std::byte mit sauberer Alignment-Angabe
</p>
</body>
</html>
</richcontent>
<arrowlink COLOR="#5b9aaa" DESTINATION="ID_1432722861" ENDARROW="Default" ENDINCLINATION="63;7;" ID="Arrow_ID_1569718697" STARTARROW="None" STARTINCLINATION="61;0;"/>
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728787025826" ID="ID_1972770219" MODIFIED="1728787040943" TEXT="Accessor und Iteration">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786962056" ID="ID_231763184" MODIFIED="1728787040943" TEXT="Verifikations-Methoden">
<icon BUILTIN="flag-yellow"/>
@ -80336,7 +80338,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1713793648079" ID="ID_907714892" MODIFIED="1713793672085" TEXT="aber vorhandener Code kann weitgehend mitverwendet werden">
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1713793648079" ID="ID_907714892" MODIFIED="1730829794903" TEXT="vorhandener Code kann auf elementarer Ebene mitverwendet werden">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1713795084878" ID="ID_900623108" MODIFIED="1713795152331" TEXT="das Buffer-Protocol gilt als gesetzt">
@ -85728,6 +85730,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<linktarget COLOR="#873d58" DESTINATION="ID_1876650367" ENDARROW="Default" ENDINCLINATION="-604;-28;" ID="Arrow_ID_1732704985" SOURCE="ID_1857199136" STARTARROW="None" STARTINCLINATION="325;29;"/>
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1730830136938" ID="ID_1277388080" MODIFIED="1730830237210" TEXT="etwas komplexere Testfunktionen aufbauen">
<arrowlink COLOR="#3e56b6" DESTINATION="ID_97803520" ENDARROW="Default" ENDINCLINATION="-355;-656;" ID="Arrow_ID_552101308" STARTARROW="None" STARTINCLINATION="874;55;"/>
<icon BUILTIN="pencil"/>
</node>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1719625243183" ID="ID_1479244509" MODIFIED="1719625248360" TEXT="&#xfc;ber Weiterungen nachdenken">
<icon BUILTIN="hourglass"/>
@ -85735,6 +85741,17 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730830270041" ID="ID_1591571416" MODIFIED="1730830413355" TEXT="parallel zum Prototyping mitf&#xfc;hren">
<icon BUILTIN="yes"/>
<icon BUILTIN="bell"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1730830293781" ID="ID_1464679892" MODIFIED="1730830442239" TEXT="Strukturen der TDO anlegen">
<arrowlink COLOR="#f01c36" DESTINATION="ID_124715076" ENDARROW="Default" ENDINCLINATION="-1234;-110;" ID="Arrow_ID_1508179375" STARTARROW="None" STARTINCLINATION="1159;108;"/>
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1730836421602" ID="ID_592635517" MODIFIED="1730836446025" TEXT="auch TestFrame_test ensprechend erg&#xe4;nzen">
<icon BUILTIN="bell"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1713821694886" ID="ID_1102491970" MODIFIED="1718843733168" TEXT="NodeLinkage_test">
<linktarget COLOR="#fdd3b6" DESTINATION="ID_1102491970" ENDARROW="Default" ENDINCLINATION="-366;-51;" ID="Arrow_ID_1227159439" SOURCE="ID_943908122" STARTARROW="None" STARTINCLINATION="30;255;"/>
@ -87669,7 +87686,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1720455790739" ID="ID_1106442316" MODIFIED="1720455859799" TEXT="jetzt als n&#xe4;chstes einen Port hinzuf&#xfc;gen">
<linktarget COLOR="#605a85" DESTINATION="ID_1106442316" ENDARROW="Default" ENDINCLINATION="-424;27;" ID="Arrow_ID_984551781" SOURCE="ID_1934059766" STARTARROW="None" STARTINCLINATION="630;-46;"/>
<linktarget COLOR="#605a85" DESTINATION="ID_1106442316" ENDARROW="Default" ENDINCLINATION="-424;27;" ID="Arrow_ID_984551781" SOURCE="ID_1934059766" STARTARROW="None" STARTINCLINATION="319;-610;"/>
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1720455899256" ID="ID_5858705" MODIFIED="1720456997827" TEXT="den PortBuilder um den NodeBuilder wickeln">
<icon BUILTIN="button_ok"/>
@ -91410,8 +91427,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...dar&#252;ber hab ich damals viel nachgedacht: eine generische Implementierung der Blatt-Iteration ist nicht so einfach zu realisieren, da man einem Element nicht anhand generischer Eigenschaften ansehen kann, ob es ein Blatt ist oder noch weiter expandiert werden kann. Ein Ausweg w&#228;re, das Element versuchsweise zu expandieren und es selber nur zur&#252;ckzuliefern, wenn die Expansion leer ist. Davon habe ich damals aber Abstand genommen, da es (a) erfordert, den Aufwand f&#252;r die Expansion stets und f&#252;r jedes Element zu leisten und (b) dann irgendwie eine Interaktion mit dem internen Stack stattfinden mu&#223;, und das dann auch noch rekursiv oder repretitiv&#160;&#160;(und das wurde mir dann alles zu kompliziert)
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1730773167011" ID="ID_114695925" MODIFIED="1730773887545" TEXT="aber wir wissen: keine Leads &#x27f9; ist Quell-Node">
<richcontent TYPE="NOTE"><html>
@ -91421,8 +91437,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...und deshalb k&#246;nnen wir erst expandAll() machen, und dann die inneren Blattknoten einfach nachtr&#228;glich wegfiltern, woduch automatisch weiter repetitiv konsumiert wird.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>
@ -91442,8 +91457,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
....aus Sicherheits-Gr&#252;nden: der Container soll irgendwo &#8222;daneben&#8220; in sicherer Storage liegen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1730774040094" ID="ID_361668791" MODIFIED="1730774051846" TEXT="Man k&#xf6;nnte aber den Container in eine &#xbb;state-core&#xab; packen">
<node COLOR="#435e98" CREATED="1730774059450" ID="ID_1347191239" MODIFIED="1730774091567" TEXT="da m&#xfc;&#xdf;te er per move(con) rein">
@ -91466,8 +91480,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Der Trick ist: die Funktion nimmt ein Template-Argument, das aber als Default den forward-deklarierten STL-Container hat. Scheint mit meinem GCC zu klappen .... ich bin da aber sehr skeptisch, denn die Signatur mit den Template-Parametern k&#246;nnte sich in Zukunft schon noch erweitern.....
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1730774727731" ID="ID_150671538" MODIFIED="1730774857648" TEXT="bin erst k&#xfc;rzlich mit Yoshimi und Clang mit etwas &#xe4;hnlichem in Probleme geraten">
@ -91509,6 +91522,52 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730821117360" ID="ID_887734089" MODIFIED="1730821455462" TEXT="komplexere Node-Trees">
<linktarget COLOR="#3e2e67" DESTINATION="ID_887734089" ENDARROW="Default" ENDINCLINATION="-520;56;" ID="Arrow_ID_154039182" SOURCE="ID_1967826855" STARTARROW="None" STARTINCLINATION="91;7;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1730827675866" ID="ID_97803520" MODIFIED="1730830237210" TEXT="Auspr&#xe4;gungen">
<linktarget COLOR="#3e56b6" DESTINATION="ID_97803520" ENDARROW="Default" ENDINCLINATION="-355;-656;" ID="Arrow_ID_552101308" SOURCE="ID_1277388080" STARTARROW="None" STARTINCLINATION="874;55;"/>
<icon BUILTIN="info"/>
<node CREATED="1730821466695" ID="ID_164711242" MODIFIED="1730821477121" TEXT="zwei Ports auf der Quell-Node">
<node CREATED="1730823014064" ID="ID_1197180355" MODIFIED="1730823032551" TEXT="zeigt zwei verschiedene Auspr&#xe4;gungen der Quell-Funktion"/>
</node>
<node CREATED="1730821478483" ID="ID_1211523316" MODIFIED="1730821487688" TEXT="diese als Lead f&#xfc;r eine weitere Node">
<node CREATED="1730823044613" ID="ID_626448746" MODIFIED="1730823071133" TEXT="hier die gleiche Funktion mit 1:1-Durchreichen der Daten"/>
</node>
<node CREATED="1730824876149" ID="ID_850575647" MODIFIED="1730824885470" TEXT="eine dritte Node mit drei Ports dr&#xfc;ber setzen">
<node CREATED="1730824949654" ID="ID_1744737205" MODIFIED="1730824961238" TEXT="sollte eine Funktion mit zwei Quellen enthalten"/>
<node CREATED="1730824943016" ID="ID_1073502139" MODIFIED="1730824948570" TEXT="braucht daneben eine Side-Chain"/>
<node CREATED="1730825075913" ID="ID_265868890" MODIFIED="1730825103541" TEXT="der zweite und dritte Port ist explzit zu verdrahten"/>
</node>
</node>
<node CREATED="1730827694080" ID="ID_124715076" MODIFIED="1730830442239" TEXT="Test-Code bereitstellen">
<linktarget COLOR="#f01c36" DESTINATION="ID_124715076" ENDARROW="Default" ENDINCLINATION="-1234;-110;" ID="Arrow_ID_1508179375" SOURCE="ID_1464679892" STARTARROW="None" STARTINCLINATION="1159;108;"/>
<node CREATED="1730827701591" ID="ID_1382558170" MODIFIED="1730827720498" TEXT="mu&#xdf; nun beginnen, die Test-Processing-Funktionen zu organisieren">
<icon BUILTIN="smily_bad"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1730827749568" ID="ID_607130868" MODIFIED="1730836275467" TEXT="die Basis-Funktionen als free-functions realisieren">
<icon BUILTIN="pencil"/>
<node CREATED="1730828045224" ID="ID_874340553" MODIFIED="1730828060299" TEXT="generateFrame"/>
<node CREATED="1730828224345" ID="ID_1955731193" MODIFIED="1730828238872" TEXT="generateMultichan"/>
<node CREATED="1730828061609" ID="ID_234342122" MODIFIED="1730828068429" TEXT="manipulateFrame">
<node COLOR="#338800" CREATED="1730835481751" ID="ID_936086670" MODIFIED="1730835554245" TEXT="brauche nun direkten Zugang zu den payload-Daten">
<arrowlink COLOR="#77313e" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="381;-48;" ID="Arrow_ID_1047269362" STARTARROW="None" STARTINCLINATION="-36;80;"/>
<icon BUILTIN="yes"/>
</node>
<node COLOR="#338800" CREATED="1730835500032" ID="ID_1746752352" MODIFIED="1730835545446" TEXT="bei der Gelegenheit auch gleich das Alignment reparieren....">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1730828077684" ID="ID_1553228902" MODIFIED="1730828099886" TEXT="combineFrames"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730827961401" ID="ID_927640003" MODIFIED="1730827975594" TEXT="die Test-Ontology als Singleton zug&#xe4;nglich machen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730827998905" ID="ID_1794368282" MODIFIED="1730828011958" TEXT="Adapter-&#x3bb; bereitstellen">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1728786023206" ID="ID_827177241" MODIFIED="1728786051330" TEXT="Node-pull()">
<icon BUILTIN="hourglass"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1728786069167" ID="ID_1584473368" MODIFIED="1728786088974" TEXT="Aufruf-Pfad durchimplementieren">
@ -91548,9 +91607,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786359782" ID="ID_525505656" MODIFIED="1728786374933" TEXT="Spec und Seed generieren und verarbeiten">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786385349" ID="ID_442258905" MODIFIED="1728786701217" TEXT="Umbau TestFrame">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1728786385349" ID="ID_442258905" MODIFIED="1730835558270" TEXT="Umbau TestFrame">
<arrowlink COLOR="#713558" DESTINATION="ID_257931093" ENDARROW="Default" ENDINCLINATION="-2466;135;" ID="Arrow_ID_121875527" STARTARROW="None" STARTINCLINATION="-2154;-229;"/>
<icon BUILTIN="flag-yellow"/>
<linktarget COLOR="#77313e" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="381;-48;" ID="Arrow_ID_1047269362" SOURCE="ID_936086670" STARTARROW="None" STARTINCLINATION="-36;80;"/>
<icon BUILTIN="pencil"/>
</node>
</node>
</node>
@ -92115,11 +92175,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1719181203922" ID="ID_1630163115" MODIFIED="1719182613749" TEXT="Nodes bauen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1719181208787" ID="ID_1934059766" MODIFIED="1720455852460" TEXT="eine Quell-Node mit zwei Ports">
<arrowlink COLOR="#605a85" DESTINATION="ID_1106442316" ENDARROW="Default" ENDINCLINATION="-424;27;" ID="Arrow_ID_984551781" STARTARROW="None" STARTINCLINATION="630;-46;"/>
<node CREATED="1719181208787" ID="ID_1934059766" MODIFIED="1730821354469" TEXT="eine Quell-Node mit zwei Ports">
<arrowlink COLOR="#605a85" DESTINATION="ID_1106442316" ENDARROW="Default" ENDINCLINATION="-424;27;" ID="Arrow_ID_984551781" STARTARROW="None" STARTINCLINATION="319;-610;"/>
<icon BUILTIN="full-1"/>
</node>
<node CREATED="1719181289558" ID="ID_1967826855" MODIFIED="1719182252664" TEXT="Node mit einem Lead und zwei Ports">
<node CREATED="1719181289558" ID="ID_1967826855" MODIFIED="1730821455462" TEXT="Node mit einem Lead und zwei Ports">
<arrowlink COLOR="#3e2e67" DESTINATION="ID_887734089" ENDARROW="Default" ENDINCLINATION="-520;56;" ID="Arrow_ID_154039182" STARTARROW="None" STARTINCLINATION="91;7;"/>
<icon BUILTIN="full-2"/>
</node>
<node CREATED="1719181653608" ID="ID_1478309261" MODIFIED="1719182255048" TEXT="Node mit zwei Leads und drei Ports">
@ -92150,13 +92211,13 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1719185927515" ID="ID_977612187" MODIFIED="1719964762105" TEXT="wie werden Nodes gebaut?">
<linktarget COLOR="#ff002c" DESTINATION="ID_977612187" ENDARROW="Default" ENDINCLINATION="195;18;" ID="Arrow_ID_1597591970" SOURCE="ID_886839618" STARTARROW="None" STARTINCLINATION="-8;-35;"/>
<icon BUILTIN="help"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1719964797735" ID="ID_742525092" MODIFIED="1719964805319" TEXT="minimale Repr&#xe4;sentation">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728785389611" ID="ID_1739123990" MODIFIED="1728785407014" TEXT="durch einen Builder-Term">
<node COLOR="#338800" CREATED="1719964797735" ID="ID_742525092" MODIFIED="1730829487036" TEXT="minimale Repr&#xe4;sentation">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1728785389611" ID="ID_1739123990" MODIFIED="1730829500600" TEXT="durch einen Builder-Term">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728785412252" ID="ID_840817870" MODIFIED="1728785425910" TEXT="mit Binden einer Processing-Function">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1728785412252" ID="ID_840817870" MODIFIED="1730829500601" TEXT="mit Binden einer Processing-Function">
<icon BUILTIN="yes"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728785339793" HGAP="96" ID="ID_1367192130" MODIFIED="1728785358620" TEXT="eine reine Quell-Node" VSHIFT="-13">
@ -92315,7 +92376,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<linktarget COLOR="#5e2f3f" DESTINATION="ID_1199569608" ENDARROW="Default" ENDINCLINATION="-1226;-72;" ID="Arrow_ID_1409703862" SOURCE="ID_495934512" STARTARROW="None" STARTINCLINATION="-302;19;"/>
<linktarget COLOR="#ad4f61" DESTINATION="ID_1199569608" ENDARROW="Default" ENDINCLINATION="16;78;" ID="Arrow_ID_1294596979" SOURCE="ID_510878392" STARTARROW="None" STARTINCLINATION="229;11;"/>
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#5e0646" CREATED="1719964569422" ID="ID_886839618" MODIFIED="1719964767337" STYLE="bubble" TEXT="erst mal irgend eine Node irgendwie bauen">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1719964569422" ID="ID_886839618" MODIFIED="1730829540845" STYLE="bubble" TEXT="erst mal irgend eine Node irgendwie bauen">
<edge COLOR="#fe6f46"/>
<arrowlink COLOR="#ff002c" DESTINATION="ID_977612187" ENDARROW="Default" ENDINCLINATION="195;18;" ID="Arrow_ID_1597591970" STARTARROW="None" STARTINCLINATION="-8;-35;"/>
<icon BUILTIN="full-1"/>