Library: code the DataSource template

...turns out challenging, since our intention here
is borderline to the intended design of the Lumiera ETD.
It ''should work'' though, when combined with a Variant-visitor...
This commit is contained in:
Fischlurch 2024-03-27 02:07:32 +01:00
parent 64f60356b7
commit 597d8191c7
7 changed files with 349 additions and 21 deletions

View file

@ -157,7 +157,7 @@ namespace diff{
DataCap::matchDbl (double d) const
{
class MatchDouble
: public Variant<DataValues>::Predicate
: public Variant<DataValues>::Predicate //////////////////////////////////TICKET #1360 floating-point precision
{
double num_;

View file

@ -75,7 +75,7 @@ namespace test{
{
REQUIRE (0 < limit);
return abs (val/target - F(1)) < limit;
}
} //////////////////////////////////////////////////////////////////////////TICKET #1360 looks like this problem was solved several times
template<typename F>

View file

@ -0,0 +1,183 @@
/*
TEXT-TEMPLATE-GEN-NODE-BINDING.hpp - data binding adapter for ETD
Copyright (C) Lumiera.org
2024, Hermann Vosseler <Ichthyostega@web.de>
This program 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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file text-template-gen-node-binding.hpp
** A complement to allow instantiation of a TextTemplate with ETD data.
** Instead of requiring a specific data source type, the text template engine relies
** on an extension point through a data-binding template, which can be (partially) specialised
** to implement data access for any suitable kind of structured data. The Lumiera [ETD] is
** a recursive data type comprised of lib::diff::GenNode elements, which in turn can hold
** a small selection of binary data elements. This scheme for structured data is widely used
** for internal communication between the components of the Lumiera application; it offers
** all the structural elements to provide a full featured backing data structure for the
** text template engine.
**
** # Intricacies
**
** Since the ETD is based on _binary data,_ we need to invoke a string rendering during
** data access, in the end relying on util::toString(). This limits the precision of floating-pont
** and time data (assuming this is adequate for the purpose of instantiating placeholders in a
** text template). A further challenge arises from the openness of the ETD format, which is
** intended for loose coupling between subsystems, and deliberately imposes not much structural
** constraints, while also offering only very limited introspection capabilities (to prevent
** a »programming by inspection« style). Some further conventions are thus necessary
** - a _Scope_ is assumed to be a _Record-Node._ (»object structure«)
** - _Keys_ are translated into _Attribute access._
** - _Iteration_ is assumed to pick a _loop-control Node_ and descend into this node's child scope.
** - if such iterated children _happen to be simple values_, then a pseudo-scope is synthesised,
** containing a single virtual attribute with the KeyID "value" (which implies that TextTemplate
** can expand a `${value}` placeholder in that scope.
** - Attributes of enclosing scopes are also visible unless shadowed.
** [ETD]: https://lumiera.org/documentation/design/architecture/ETD.html
** @todo WIP-WIP-WIP 3/2024
** @see TextTemplate_test
*/
#ifndef LIB_TEXT_TEMPLATE_GEN_NODE_BINDING_H
#define LIB_TEXT_TEMPLATE_GEN_NODE_BINDING_H
#include "lib/diff/gen-node.hpp"
#include "lib/text-template.hpp"
//#include "lib/format-string.hpp"
//#include "lib/format-util.hpp"
//#include "lib/regex.hpp"
//#include "lib/util.hpp"
//#include <memory>
#include <string>
//#include <vector>
//#include <stack>
//#include <map>
namespace lib {
using std::string;
// using StrView = std::string_view;
//
// using util::_Fmt;
// using util::isnil;
// using util::unConst;
namespace {
}
/* ======= Data binding for GenNode (ETD) ======= */
/**
* Data-binding for a tree of GenNode data (ETD).
* Attributes are accessible as keys, while iteration descends
* into the child scope of the attribute indicated in the ${for <key>}` tag.
* @see TextTemplate_test::verify_ETD_binding()
*/
template<>
struct TextTemplate::DataSource<diff::GenNode>
{
using Node = diff::GenNode;
using Rec = diff::Rec;
Node const* data_;
DataSource* parScope_;
bool isSubScope() { return bool(parScope_); }
DataSource(Node const& root)
: data_{&root}
, parScope_{nullptr}
{ }
using Value = std::string;
using Iter = Rec::scopeIter;
Node const*
findNode (string key)
{
if (data_->isNested())
{// standard case: Attribute lookup
Rec const& record = data_->data.get<Rec>();
if (record.hasAttribute (key))
return & record.get (key);
}
else
if ("value" == key) // special treatment for a »pseudo context«
return data_; // comprised only of a single value node
else
if (isSubScope())
return parScope_->findNode (key);
return nullptr;
}
bool
contains (string key)
{
return bool(findNode (key));
}
Value
retrieveContent (string key)
{
return Value(findNode(key)->data); ///////////////////////////////OOO this is not correct -- need a way to render the bare content
}
Iter
getSequence (string key)
{
if (not contains(key))
return Iter{};
Node const* node = findNode (key);
if (not node->isNested())
return Iter{};
else
return node->data.get<Rec>().scope();
}
DataSource
openContext (Iter& iter)
{
REQUIRE (iter);
DataSource nested{*this};
nested.parScope_ = this;
nested.data_ = & *iter;
return nested;
}
};
namespace {// help the compiler with picking the proper specialisation for the data binding
inline auto
bindDataSource(diff::GenNode const& etd)
{
return TextTemplate::DataSource<diff::GenNode>{etd};
}
}
}// namespace lib
#endif /*LIB_TEXT_TEMPLATE_GEN_NODE_BINDING_H*/

View file

@ -163,6 +163,7 @@
** [Lumiera Forward Iterator]: https://lumiera.org/documentation/technical/library/iterator.html
** @todo WIP-WIP-WIP 3/2024
** @see TextTemplate_test
** @see text-template-gen-node-binding.hpp
** @see gnuplot-gen.hpp
** @see SchedulerStress_test
*/

View file

@ -146,6 +146,7 @@ namespace util {
* @see https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
* @see http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
* @see https://en.wikipedia.org/wiki/Unit_in_the_last_place
* @todo 3/2024 seems we have solved this problem several times meanwhile /////////////////////////////////TICKET #1360 sort out floating-point rounding and precision
*/
inline bool
almostEqual (double d1, double d2, unsigned int ulp =2)

View file

@ -29,6 +29,7 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"///////////////////////TODO
#include "lib/text-template.hpp"
#include "lib/text-template-gen-node-binding.hpp"
#include "lib/format-string.hpp"
#include "lib/format-cout.hpp"///////////////////////TODO
#include "lib/test/diagnostic-output.hpp"///////////////////////TODO

View file

@ -113640,8 +113640,8 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710793367246" ID="ID_1695880616" MODIFIED="1710793369256" TEXT="ETD">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1710793367246" ID="ID_1695880616" MODIFIED="1711508518124" TEXT="ETD">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710804556008" ID="ID_1997691101" MODIFIED="1711475133506" TEXT="DataSrc repr&#xe4;sentiert ein &#xbb;Objekt&#xab; &#x2259; Rec&lt;GenNode&gt;">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1711475218638" ID="ID_44068114" MODIFIED="1711475231130" TEXT="Ben&#xf6;tigte Eigenschaften">
@ -113698,7 +113698,8 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711477500254" ID="ID_403443386" MODIFIED="1711477519140" TEXT="man k&#xf6;nnte es ganz einfach mal &#xbb;pragmatisch&#xab; nutzen">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711477500254" ID="ID_403443386" MODIFIED="1711507689410" TEXT="man k&#xf6;nnte es ganz einfach mal &#xbb;pragmatisch&#xab; nutzen">
<linktarget COLOR="#f83362" DESTINATION="ID_403443386" ENDARROW="Default" ENDINCLINATION="-604;28;" ID="Arrow_ID_1274881948" SOURCE="ID_285017359" STARTARROW="None" STARTINCLINATION="409;-28;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1711477520228" ID="ID_1881261418" MODIFIED="1711477535488" TEXT="und so herausfinden wo es implementiert ist">
<icon BUILTIN="idea"/>
@ -113717,8 +113718,7 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
Man k&#246;nnte erwarten, da&#223; diese string-view tats&#228;chlich nur w&#228;hrend der Iteration genutzt wird &#8212; letztlich m&#246;chte man ja das gerenderte Text-Template irgendwo integrieren...
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1711486798598" ID="ID_1504667047" MODIFIED="1711488886985" TEXT="d.h. wieder der shared-ptr-Trick"/>
@ -113736,16 +113736,68 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711475137705" ID="ID_265880025" MODIFIED="1711475154240" TEXT="Implementierung der Repr&#xe4;sentation">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1711491795547" ID="ID_1481897171" MODIFIED="1711491809910" TEXT="Einstiegspunkt f&#xfc;r einen Scope ist stets eine GenNode">
<node CREATED="1711491812270" ID="ID_234227882" MODIFIED="1711491820513" TEXT="man k&#xf6;nnte das auch genau anders herum handhaben"/>
<node CREATED="1711491821460" ID="ID_1916429769" MODIFIED="1711491899861" TEXT="aber dann h&#xe4;tten wir ein Problem mit Zugriffen auf Nodes die kein Record sind"/>
<node CREATED="1711491812270" ID="ID_234227882" MODIFIED="1711501542307" TEXT="man k&#xf6;nnte das auch genau anders herum handhaben">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...also auf Top-Level einen Record&lt;GenNode&gt; annehmen. Teilweise wird das im Diff-Framework und auch in diversen Tests so gehandhabt (da es einfacher ist)
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1711491821460" ID="ID_1916429769" MODIFIED="1711501577541" TEXT="aber dann h&#xe4;tten wir ein Problem mit Zugriffen auf Nodes die kein Record sind">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...weil eine DataSource ein Referenz-Wrapper ist, und damit einen Pointer auf das Start-Element haben mu&#223;
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1711491921789" ID="ID_714056549" MODIFIED="1711491940208" TEXT="GenNode als Einstiegspunkt dagegen stellt keine Einschr&#xe4;nkung dar">
<node CREATED="1711491941836" ID="ID_194254261" MODIFIED="1711491952929" TEXT="denn sollte man doch einmal einen Record haben,"/>
<node CREATED="1711491953690" ID="ID_477686075" MODIFIED="1711491964956" TEXT="dann l&#xe4;&#xdf;t sich leicht eine Ref-GenNode bauen"/>
</node>
</node>
<node CREATED="1711492643022" ID="ID_149060446" MODIFIED="1711492665647" TEXT="als Abk&#xfc;rzung / Cache wird ein sekund&#xe4;rer Rec-Pointer mitgef&#xfc;hrt">
<node COLOR="#5b280f" CREATED="1711492643022" ID="ID_149060446" MODIFIED="1711504228004" TEXT="als Abk&#xfc;rzung / Cache wird ein sekund&#xe4;rer Rec-Pointer mitgef&#xfc;hrt">
<icon BUILTIN="button_cancel"/>
<node CREATED="1711492667078" ID="ID_502425157" MODIFIED="1711492672470" TEXT="dieser kann NULL sein"/>
<node CREATED="1711492673202" ID="ID_1566411442" MODIFIED="1711492715043" TEXT="&#x27f9; dann ist klar da&#xdf; das Target value-GenNode ist"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1711504230327" ID="ID_1705528103" MODIFIED="1711504308627">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<i>....je l&#228;nger ich dar&#252;ber nachdenke &#8212;</i>
</p>
<p>
umso mehr sehe ich diese Idee im Widerspruch zum GenNode-Design
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="stop-sign"/>
<node CREATED="1711504319359" ID="ID_131172923" MODIFIED="1711504331730" TEXT="GenNode sollte abstrahieren"/>
<node CREATED="1711504333525" ID="ID_629908719" MODIFIED="1711504367519" TEXT="und eben grade nicht eine &#x201e;universal-Datenstruktur&#x201c; sein"/>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1711504378447" ID="ID_1966211266" MODIFIED="1711504390425" TEXT="besser die Optimierung dem Optimiser &#xfc;berlassen">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
<node CREATED="1711504392686" ID="ID_1765343804" MODIFIED="1711504399768" TEXT="alle relevanten Accessoren sind inline"/>
<node CREATED="1711504403580" ID="ID_1563713565" MODIFIED="1711504419404" TEXT="common subexpression extraction sollte das richten">
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1711492744185" ID="ID_1414659694" MODIFIED="1711493061959" TEXT="zudem brauchen wir einen parent-Scope">
<icon BUILTIN="messagebox_warning"/>
@ -113759,20 +113811,88 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
Das ist gradezu die Grundannahme: der Verarbeiter hat die Struktur zu kennen &#8212; die Node hat <i>keine introspektiven F&#228;higkeiten</i>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1711493338536" ID="ID_1143325593" MODIFIED="1711493361420" TEXT="w&#xe4;re aber m&#xf6;glich &#x2014; so wie der Zugriff aktuell implementiert ist">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1711493364914" ID="ID_1017484098" MODIFIED="1711493380944" TEXT="sinnvollerweise m&#xfc;&#xdf;te man das als Teil des Konzepts betrachten"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#338800" CREATED="1711493364914" ID="ID_1017484098" MODIFIED="1711499112194" TEXT="sinnvollerweise m&#xfc;&#xdf;te man das als Teil des Konzepts betrachten">
<icon BUILTIN="yes"/>
<node CREATED="1711499125824" ID="ID_727245116" MODIFIED="1711499133531" TEXT="InstanceCore&lt;SRC&gt;::focusNested()"/>
<node CREATED="1711499134805" ID="ID_1070301223" MODIFIED="1711499142771" TEXT="bestehender Code, aber klarer formuliert"/>
<node COLOR="#435e98" CREATED="1711499149517" ID="ID_668046605" MODIFIED="1711499173225">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
DataSrc-Impl kann sich auf <b>stabile Memory-Location</b>&#160;verlassen
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="yes"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711499198944" ID="ID_509882790" MODIFIED="1711499229342" TEXT="man k&#xf6;nnte damit nun sogar die Map-Implementierung beliebig &#xbb;virtuell schachtelbar&#xab; machen">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711499245448" ID="ID_1914030460" MODIFIED="1711504682259" TEXT="dieser wird durch einen DataSrc-Pointer repr&#xe4;sentiert">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1711504691401" ID="ID_36424118" MODIFIED="1711504724028" TEXT="tail-delegation f&#xfc;r Attribut-Zugriffe"/>
<node COLOR="#435e98" CREATED="1711504724929" ID="ID_792000097" MODIFIED="1711504739272" TEXT="erlaubt somit beliebige Schachtelung">
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1711499521659" ID="ID_1374441904" MODIFIED="1711499539721" TEXT="wo ansiedeln?">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="help"/>
<node CREATED="1711499541233" ID="ID_1123960201" MODIFIED="1711499563146" TEXT="man k&#xf6;nnte das Data-Binding auch in gen-node.hpp legen"/>
<node CREATED="1711499564022" ID="ID_1944746721" MODIFIED="1711499645088" TEXT="allerdings habe ich mir seinerzeit M&#xfc;he gegeben, GenNode &#xbb;schmal&#xab; zu halten">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
wir brauchen nur den Level traits + util + elementares Metaprogramming
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1711499646202" ID="ID_185538526" MODIFIED="1711499667104" TEXT="damit ist TextTemplate bereits jetzt schwergewichtiger.."/>
<node COLOR="#5b280f" CREATED="1711499668336" ID="ID_517325854" MODIFIED="1711499708282" TEXT="kann GenNode ohne Weiteres mit einschlie&#xdf;en">
<icon BUILTIN="button_cancel"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#2f436d" CREATED="1711499709866" ID="ID_701901730" MODIFIED="1711508441008" TEXT="besser: separater Header text-template-gen-node-binding.hpp">
<icon BUILTIN="yes"/>
</node>
</node>
</node>
</node>
<node CREATED="1710804591691" ID="ID_1815976275" MODIFIED="1710804603973" TEXT="Key-Zugriff wird &#xfc;bersetzt in Attribut-Zugriff">
<node CREATED="1711469498958" ID="ID_106772989" MODIFIED="1711469520804" TEXT="kann kaskadieren in einen parent-Scope"/>
<node CREATED="1711469521509" ID="ID_680558791" MODIFIED="1711469543766" TEXT="daf&#xfc;r wird ein optionaler Rec&lt;GenNode&gt;* verwendet"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1711469521509" ID="ID_680558791" MODIFIED="1711506649812" TEXT="daf&#xfc;r wird ein optionaler Rec&lt;GenNode&gt;* verwendet">
<icon BUILTIN="help"/>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1711506650791" ID="ID_1486045472" MODIFIED="1711506683627" TEXT="Generischer Zugriff widerspricht dem GenNode-Design">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1711506695185" ID="ID_133207964" MODIFIED="1711506719546" TEXT="mu&#xdf; bereits wissen, da&#xdf; in der GenNode ein Record liegt"/>
<node CREATED="1711507563671" ID="ID_260828349" MODIFIED="1711507583155" TEXT="verwende eine Hilfsmethode findNode(key)">
<icon BUILTIN="idea"/>
<node CREATED="1711507589594" ID="ID_13726779" MODIFIED="1711507610803" TEXT="diese pr&#xfc;ft der Reihe nach die m&#xf6;glichen Zugriffswege"/>
<node CREATED="1711507611702" ID="ID_1556736224" MODIFIED="1711507619619" TEXT="und kaskadiert in den Parent-Context"/>
<node CREATED="1711507620461" ID="ID_1478877809" MODIFIED="1711507626101" TEXT="kann nullptr zur&#xfc;ckliefern"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711507631097" ID="ID_285017359" MODIFIED="1711507694404" TEXT="n&#xe4;chstes Problem &#xd83e;&#xdc32; Rendern als String">
<arrowlink COLOR="#f83362" DESTINATION="ID_403443386" ENDARROW="Default" ENDINCLINATION="-604;28;" ID="Arrow_ID_1274881948" STARTARROW="None" STARTINCLINATION="409;-28;"/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node CREATED="1710804616944" ID="ID_538897899" MODIFIED="1710804626706" TEXT="Iteration wird &#xfc;bersetzt in Scope-Iteration">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1711469668314" ID="ID_1640263666" MODIFIED="1711469688642" TEXT="hier ist eine zus&#xe4;tzliche Binding-Konvention notwendig">
@ -113787,8 +113907,7 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
...denn in der Praxis wird erwartet, da&#223; im Scope sehr wohl wieder verschachtelte Records liegen; sonst w&#252;rde diese Datenstruktur ja wenig Sinn machen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
@ -113800,8 +113919,7 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
&#10233; wenn Kind <i>kein Record</i>&#160;ist
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<node CREATED="1711469919922" ID="ID_1678329722" MODIFIED="1711469936011" TEXT="dann m&#xfc;ssen wir einen pseudo-Scope synthetisieren"/>
<node CREATED="1711469936951" ID="ID_1819512723" MODIFIED="1711469968399" TEXT="dieser enth&#xe4;lt nur ein virtuelles Attribut &quot;value&quot;"/>
</node>
@ -113818,15 +113936,39 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
es gibt ein Pr&#228;dikat <font face="Monospaced" color="#1729bd">genNode.isNested()</font>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>
<node CREATED="1710804633837" ID="ID_1119504137" MODIFIED="1711470052179" TEXT="normalerweise ist Element im Scope wieder ein Rec&lt;GenNode&gt;">
<linktarget COLOR="#4d81bd" DESTINATION="ID_1119504137" ENDARROW="Default" ENDINCLINATION="5;-35;" ID="Arrow_ID_279787572" SOURCE="ID_1900618698" STARTARROW="None" STARTINCLINATION="-46;4;"/>
</node>
<node CREATED="1710804715954" ID="ID_1537394187" MODIFIED="1711470077889" TEXT="verschachtelte Scopes k&#xf6;nnen aber leer sein (wegen Parent-Delegation)"/>
<node CREATED="1711508494304" ID="ID_1420529551" MODIFIED="1711508511954" TEXT="das wird vom code jedoch automatisch (und transparent) gehandhabt">
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1711508533490" ID="ID_1740637248" MODIFIED="1711508536658" TEXT="Test">
<icon BUILTIN="flag-pink"/>
<node COLOR="#ff00cb" CREATED="1711508538010" ID="ID_1041108883" MODIFIED="1711508554635" TEXT="puh....">
<font NAME="SansSerif" SIZE="11"/>
<icon BUILTIN="smiley-neutral"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711508556799" ID="ID_681566820" MODIFIED="1711508573324" TEXT="erst mal schrittweise herantasten...">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711508602973" ID="ID_1154919226" MODIFIED="1711508628990" TEXT="einen Beispiel-Daten-Kontext bereitstellen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711508585131" ID="ID_1692560421" MODIFIED="1711508628990" TEXT="die DataSource explizit erzeugen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711508631813" ID="ID_464128354" MODIFIED="1711508654315" TEXT="die Zugriffsmethoden durchspielen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711508645715" ID="ID_1542705162" MODIFIED="1711508654315" TEXT="dann weiter zur Iteration">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
</node>
</node>
</node>