Chain-Load: draft - generate DOT diagram from calculation topology
With all the preceding DSL work, this turns out to be surprisingly easy; the only minor twist is the grouping of nodes into (time)levels, which can be achieved with a "lagging" update from the loop body Note: next step will be to extract the DSL helpers into a Library header
This commit is contained in:
parent
65fa16b626
commit
1c4b1a2973
4 changed files with 529 additions and 40 deletions
438
src/lib/dot-gen.hpp
Normal file
438
src/lib/dot-gen.hpp
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
DOT-GEN.hpp - DSL to generate Graphviz-DOT code
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2023, 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 dot-gen.hpp
|
||||
** Support for generation of Graphviz-DOT code for structure visualisation.
|
||||
**
|
||||
** @see TestChainLoad_test
|
||||
** @see SchedulerStress_test
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB_DOT_GEN_H
|
||||
#define LIB_DOT_GEN_H
|
||||
|
||||
|
||||
#include "vault/common.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
|
||||
//#include "vault/gear/job.h"
|
||||
//#include "vault/gear/activity.hpp"
|
||||
//#include "vault/gear/nop-job-functor.hpp"
|
||||
//#include "lib/time/timevalue.hpp"
|
||||
//#include "lib/meta/variadic-helper.hpp"
|
||||
//#include "lib/meta/function.hpp"
|
||||
//#include "lib/wrapper.hpp"
|
||||
#include "lib/format-util.hpp" /////////////////TODO used only for dot generation
|
||||
#include "lib/util.hpp" /////////////////TODO used only for dot generation
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
//#include <string>
|
||||
//#include <deque>
|
||||
#include <memory>
|
||||
#include <sstream> /////////////////TODO used only for dot generation
|
||||
#include <string>
|
||||
#include <vector> /////////////////TODO used only for dot generation
|
||||
#include <array>
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
||||
// using std::string;
|
||||
// using std::function;
|
||||
// using lib::time::TimeValue;
|
||||
// using lib::time::Time;
|
||||
// using lib::time::FSecs;
|
||||
// using lib::time::Offset;
|
||||
// using lib::meta::RebindVariadic;
|
||||
using util::toString; /////////////////TODO used only for dot generation
|
||||
using util::isnil; /////////////////TODO used only for dot generation
|
||||
using util::max;
|
||||
using util::unConst;
|
||||
// using std::forward;
|
||||
using std::string;
|
||||
using std::swap;
|
||||
using std::move;
|
||||
using boost::hash_combine;
|
||||
|
||||
|
||||
namespace {// Diagnostic markers
|
||||
// const string MARK_INC{"IncSeq"};
|
||||
// const string MARK_SEQ{"Seq"};
|
||||
const size_t DEFAULT_FAN = 16;
|
||||
const size_t DEFAULT_SIZ = 256;
|
||||
|
||||
// using SIG_JobDiagnostic = void(Time, int32_t);
|
||||
}
|
||||
|
||||
|
||||
namespace dot {
|
||||
|
||||
struct Code : string
|
||||
{
|
||||
using string::string;
|
||||
Code(string const& c) : string{c} { }
|
||||
Code(string && c) : string{move(c)}{ }
|
||||
};
|
||||
|
||||
struct Section
|
||||
{
|
||||
std::vector<string> lines;
|
||||
|
||||
Section (string name)
|
||||
: lines{"// "+name}
|
||||
{ }
|
||||
|
||||
Section&&
|
||||
operator+= (Code const& code)
|
||||
{
|
||||
lines.emplace_back(code);
|
||||
return move(*this);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to generate DOT-Graphviz rendering of topology
|
||||
*/
|
||||
class DotOut
|
||||
{
|
||||
std::ostringstream buff_;
|
||||
|
||||
static uint const IDENT_STEP = 2;
|
||||
public:
|
||||
void
|
||||
putLine (string line, uint indent=0)
|
||||
{
|
||||
if (indent)
|
||||
buff_ << string(indent,' ');
|
||||
buff_ << line
|
||||
<< '\n';
|
||||
}
|
||||
|
||||
void
|
||||
put (Code const& code)
|
||||
{
|
||||
buff_ << code;
|
||||
}
|
||||
|
||||
void
|
||||
put (Section const& sect)
|
||||
{
|
||||
for (string const& line : sect.lines)
|
||||
putLine (line, IDENT_STEP);
|
||||
}
|
||||
|
||||
template<class P, class...PS>
|
||||
void
|
||||
put (P const& part, PS const& ...parts)
|
||||
{
|
||||
put (part);
|
||||
putLine ("");
|
||||
put (parts...);
|
||||
}
|
||||
|
||||
/** retrieve complete code generated thus far */
|
||||
operator string() const
|
||||
{
|
||||
return buff_.str();
|
||||
}
|
||||
};
|
||||
|
||||
struct Node : Code
|
||||
{
|
||||
Node (size_t id)
|
||||
: Code{"N"+toString(id)}
|
||||
{ }
|
||||
|
||||
Node&&
|
||||
addAttrib (string def)
|
||||
{
|
||||
if (back() != ']')
|
||||
append ("[");
|
||||
else
|
||||
{
|
||||
resize (length()-2);
|
||||
append (", ");
|
||||
}
|
||||
append (def+" ]");
|
||||
return move(*this);
|
||||
}
|
||||
|
||||
Node&&
|
||||
label (size_t i)
|
||||
{
|
||||
return addAttrib ("label="+toString(i));
|
||||
}
|
||||
|
||||
Node&&
|
||||
style (Code const& code)
|
||||
{
|
||||
if (not isnil(code))
|
||||
addAttrib (code);
|
||||
return move(*this);
|
||||
}
|
||||
};
|
||||
|
||||
struct Scope : Code
|
||||
{
|
||||
Scope (size_t id)
|
||||
: Code{"{ /*"+toString(id)+"*/ }"}
|
||||
{ }
|
||||
|
||||
Scope&&
|
||||
add (Code const& code)
|
||||
{
|
||||
resize(length()-1);
|
||||
append (code+" }");
|
||||
return move(*this);
|
||||
}
|
||||
|
||||
Scope&&
|
||||
rank (string rankSetting)
|
||||
{
|
||||
return add(Code{"rank="+rankSetting});
|
||||
}
|
||||
};
|
||||
|
||||
inline Code
|
||||
connect (size_t src, size_t dest)
|
||||
{
|
||||
return Code{Node(src) +" -> "+ Node(dest)};
|
||||
}
|
||||
|
||||
template<class...COD>
|
||||
inline DotOut
|
||||
digraph (COD ...parts)
|
||||
{
|
||||
DotOut script;
|
||||
script.putLine (Code{"digraph {"});
|
||||
script.put (parts...);
|
||||
script.putLine (Code{"}"});
|
||||
return script;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A Generator for synthetic Render Jobs for Scheduler load testing.
|
||||
* @tparam maxFan maximal fan-in/out from a node, also limits maximal parallel strands.
|
||||
* @see TestChainLoad_test
|
||||
*/
|
||||
template<size_t numNodes =DEFAULT_SIZ, size_t maxFan =DEFAULT_FAN>
|
||||
class TestChainLoad
|
||||
: util::MoveOnly
|
||||
{
|
||||
|
||||
public:
|
||||
struct Node
|
||||
: util::MoveOnly
|
||||
{
|
||||
using _Arr = std::array<Node*, maxFan>;
|
||||
using Iter = typename _Arr::iterator;
|
||||
|
||||
/** Table with connections to other Node records */
|
||||
struct Tab : _Arr
|
||||
{
|
||||
Iter after = _Arr::begin();
|
||||
Iter end() { return after; }
|
||||
friend Iter end(Tab& tab) { return tab.end(); }
|
||||
|
||||
void clear() { after = _Arr::begin(); } ///< @warning pointer data in array not cleared
|
||||
|
||||
size_t size() const { return unConst(this)->end()-_Arr::begin(); }
|
||||
bool empty() const { return 0 == size(); }
|
||||
|
||||
Iter
|
||||
add(Node* n)
|
||||
{
|
||||
if (after != _Arr::end())
|
||||
{
|
||||
*after = n;
|
||||
return after++;
|
||||
}
|
||||
NOTREACHED ("excess node linkage");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
size_t hash;
|
||||
size_t level{0}, repeat{0};
|
||||
Tab pred{0}, succ{0};
|
||||
|
||||
Node(size_t seed =0)
|
||||
: hash{seed}
|
||||
{ }
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
hash = 0;
|
||||
level = repeat = 0;
|
||||
pred.clear();
|
||||
succ.clear();
|
||||
}
|
||||
|
||||
Node&
|
||||
addPred (Node* other)
|
||||
{
|
||||
REQUIRE (other);
|
||||
pred.add (other);
|
||||
other->succ.add (this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Node&
|
||||
addSucc (Node* other)
|
||||
{
|
||||
REQUIRE (other);
|
||||
succ.add (other);
|
||||
other->pred.add (this);
|
||||
return *this;
|
||||
}
|
||||
Node& addPred(Node& other) { return addPred(&other); }
|
||||
Node& addSucc(Node& other) { return addSucc(&other); }
|
||||
|
||||
size_t
|
||||
calculate()
|
||||
{
|
||||
for (Node*& entry: pred)
|
||||
if (entry)
|
||||
hash_combine (hash, entry->hash);
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
using NodeTab = typename Node::Tab;
|
||||
using NodeStorage = std::array<Node, numNodes>;
|
||||
using CtrlRule = std::function<size_t(size_t, double)>;
|
||||
|
||||
std::unique_ptr<NodeStorage> nodes_;
|
||||
|
||||
CtrlRule seedingRule_ {[](size_t, double){ return 0; }};
|
||||
CtrlRule expansionRule_{[](size_t, double){ return 0; }};
|
||||
CtrlRule reductionRule_{[](size_t, double){ return 0; }};
|
||||
|
||||
public:
|
||||
TestChainLoad()
|
||||
: nodes_{new NodeStorage}
|
||||
{ }
|
||||
|
||||
|
||||
size_t size() const { return nodes_->size(); }
|
||||
size_t topLevel() const { return nodes_->back().level; }
|
||||
size_t getSeed() const { return nodes_->front().hash; }
|
||||
size_t getHash() const { return nodes_->back().hash; }
|
||||
|
||||
|
||||
/* ===== topology control ===== */
|
||||
|
||||
/**
|
||||
* Use current configuration and seed to (re)build Node connectivity.
|
||||
*/
|
||||
TestChainLoad
|
||||
buildToplolgy()
|
||||
{
|
||||
NodeTab a,b, // working data for generation
|
||||
*curr{&a}, // the current set of nodes to carry on
|
||||
*next{&b}; // the next set of nodes connected to current
|
||||
Node* node = &nodes_->front();
|
||||
size_t level{0};
|
||||
size_t expectedLevel = max (1u, numNodes/maxFan);
|
||||
|
||||
// prepare building blocks for the topology generation...
|
||||
auto height = [&](double level)
|
||||
{
|
||||
return level/expectedLevel;
|
||||
};
|
||||
auto spaceLeft = [&]{ return next->size() < maxFan; };
|
||||
auto addNode = [&]{
|
||||
Node* n = *next->add (node++);
|
||||
n->clear();
|
||||
n->level = level;
|
||||
return n;
|
||||
};
|
||||
auto apply = [&](CtrlRule& rule, Node* n)
|
||||
{
|
||||
return rule (n->hash, height(level));
|
||||
};
|
||||
|
||||
addNode(); // prime next with root node
|
||||
// visit all further nodes and establish links
|
||||
while (node < &nodes_->back())
|
||||
{
|
||||
++level;
|
||||
curr->clear();
|
||||
swap (next, curr);
|
||||
size_t toReduce{0};
|
||||
Node* r;
|
||||
REQUIRE (spaceLeft());
|
||||
for (Node* o : *curr)
|
||||
{ // follow-up on all Nodes in current level...
|
||||
o->calculate();
|
||||
size_t toSeed = apply (seedingRule_, o);
|
||||
size_t toExpand = apply (expansionRule_,o);
|
||||
while (0 < toSeed and spaceLeft())
|
||||
{ // start a new chain from seed
|
||||
Node* n = addNode();
|
||||
n->hash = this->getSeed();
|
||||
--toSeed;
|
||||
}
|
||||
while (0 < toExpand and spaceLeft())
|
||||
{ // fork out secondary chain from o
|
||||
Node* n = addNode();
|
||||
o->addSucc(n);
|
||||
--toExpand;
|
||||
}
|
||||
if (not toReduce and spaceLeft())
|
||||
{ // carry-on the chain from o
|
||||
r = addNode();
|
||||
toReduce = apply (reductionRule_, o);
|
||||
}
|
||||
else
|
||||
--toReduce;
|
||||
ENSURE (r);
|
||||
r->addPred(o);
|
||||
}
|
||||
}
|
||||
ENSURE (node == &nodes_->back());
|
||||
// connect ends of all remaining chains to top-Node
|
||||
node->clear();
|
||||
node->level = ++level;
|
||||
for (Node* o : *next)
|
||||
node->addPred(o);
|
||||
//
|
||||
return move(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace lib
|
||||
#endif /*LIB_DOT_GEN_H*/
|
||||
|
|
@ -177,18 +177,7 @@ namespace test {
|
|||
CHECK (0 == graph.getHash());
|
||||
|
||||
///////////////////////////////////////////////////////////////////////TODO : what follows is WIP to test the DOT graph generator....
|
||||
using N = TestChainLoad<>::Node;
|
||||
std::array<N,7> n;
|
||||
n[1].addPred(n[0]);
|
||||
n[2].addPred(n[0]);
|
||||
n[3].addPred(n[1]);
|
||||
n[3].addPred(n[2]);
|
||||
n[5].addPred(n[1]);
|
||||
n[6].addPred(n[3]);
|
||||
n[6].addPred(n[4]);
|
||||
n[6].addPred(n[5]);
|
||||
n[0].hash = 55;
|
||||
n[4].hash = n[0].hash;
|
||||
using N = const TestChainLoad<32>::Node;
|
||||
|
||||
using namespace dot;
|
||||
Section nodes("Nodes");
|
||||
|
|
@ -200,8 +189,12 @@ namespace test {
|
|||
Code TOP {"shape=box, style=rounded"};
|
||||
Code DEFAULT{};
|
||||
|
||||
auto nNr = [&](N& nn){ return size_t(&nn - &n[0]); };
|
||||
for (N& nn : n)
|
||||
N& n0n = *graph.allNodes();
|
||||
auto nNr = [&](N& nn){ return size_t(&nn - &n0n); };
|
||||
size_t level(0);
|
||||
Scope timeLevel{level};
|
||||
layers += timeLevel.rank("min ");
|
||||
for (N& nn : graph.allNodes())
|
||||
{
|
||||
size_t i = nNr(nn);
|
||||
nodes += Node(i).label(i+1).style(i==0 ? BOTTOM
|
||||
|
|
@ -210,12 +203,16 @@ namespace test {
|
|||
: DEFAULT);
|
||||
for (N* suc : nn.succ)
|
||||
topology += connect(i, nNr(*suc));
|
||||
|
||||
if (level != nn.level)
|
||||
{
|
||||
++level;
|
||||
ENSURE (level == nn.level);
|
||||
timeLevel = Scope(level).rank("same");
|
||||
layers += timeLevel;
|
||||
}
|
||||
timeLevel.add(Node(i));
|
||||
}
|
||||
layers += Scope(0).rank("min ").add(Node(0));
|
||||
layers += Scope(1).rank("same").add(Node(1)).add(Node(2));
|
||||
layers += Scope(2).rank("same").add(Node(3)).add(Node(4)).add(Node(5));
|
||||
layers += Scope(3).rank("same").add(Node(6));
|
||||
|
||||
cout << digraph(nodes,layers,topology) <<endl;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
//#include "lib/meta/variadic-helper.hpp"
|
||||
//#include "lib/meta/function.hpp"
|
||||
//#include "lib/wrapper.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/format-util.hpp" /////////////////TODO used only for dot generation
|
||||
#include "lib/util.hpp" /////////////////TODO used only for dot generation
|
||||
|
||||
|
|
@ -147,9 +148,9 @@ namespace test {
|
|||
{ }
|
||||
|
||||
Section&&
|
||||
operator+= (Code&& code)
|
||||
operator+= (Code const& code)
|
||||
{
|
||||
lines.emplace_back(move (code));
|
||||
lines.emplace_back(code);
|
||||
return move(*this);
|
||||
}
|
||||
};
|
||||
|
|
@ -295,13 +296,17 @@ namespace test {
|
|||
{
|
||||
using _Arr = std::array<Node*, maxFan>;
|
||||
using Iter = typename _Arr::iterator;
|
||||
using CIter = typename _Arr::const_iterator;
|
||||
|
||||
/** Table with connections to other Node records */
|
||||
struct Tab : _Arr
|
||||
{
|
||||
Iter after = _Arr::begin();
|
||||
Iter end() { return after; }
|
||||
friend Iter end(Tab& tab) { return tab.end(); }
|
||||
|
||||
Iter end() { return after; }
|
||||
CIter end() const{ return after; }
|
||||
friend Iter end (Tab & tab){ return tab.end(); }
|
||||
friend CIter end (Tab const& tab){ return tab.end(); }
|
||||
|
||||
void clear() { after = _Arr::begin(); } ///< @warning pointer data in array not cleared
|
||||
|
||||
|
|
@ -391,6 +396,15 @@ namespace test {
|
|||
size_t getHash() const { return nodes_->back().hash; }
|
||||
|
||||
|
||||
using NodeIter = decltype(lib::explore (std::declval<NodeStorage & >()));
|
||||
|
||||
NodeIter
|
||||
allNodes()
|
||||
{
|
||||
return lib::explore (*nodes_);
|
||||
}
|
||||
|
||||
|
||||
/* ===== topology control ===== */
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -95854,13 +95854,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700100290904" ID="ID_1991398605" MODIFIED="1700100351351" TEXT="brauche Hilfsmittel zur Visualisierung">
|
||||
<arrowlink COLOR="#62819c" DESTINATION="ID_1464042796" ENDARROW="Default" ENDINCLINATION="21;-256;" ID="Arrow_ID_596151514" STARTARROW="None" STARTINCLINATION="787;55;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1700100356900" HGAP="45" ID="ID_216360062" LINK="#ID_764096140" MODIFIED="1700100481583" TEXT="erst mal einfaches Referenz-Skript (re)-generieren" VSHIFT="-5">
|
||||
<node COLOR="#338800" CREATED="1700100356900" FOLDED="true" HGAP="45" ID="ID_216360062" LINK="#ID_764096140" MODIFIED="1700105412090" TEXT="erst mal einfaches Referenz-Skript (re)-generieren" VSHIFT="-5">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1700100394556" ID="ID_587545230" MODIFIED="1700100416123" TEXT="die entsprechende Node-Struktur fest verdrahtet aufbauen"/>
|
||||
<node CREATED="1700100416777" ID="ID_1280977723" MODIFIED="1700100426249" TEXT="Code-Schema zur Generierung daran entwickeln"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700100453954" HGAP="138" ID="ID_645441127" MODIFIED="1700100479215" TEXT="auf komplexere Topologien ausweiten" VSHIFT="-12">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1700100453954" HGAP="138" ID="ID_645441127" MODIFIED="1700105287506" TEXT="auf komplexere Topologien ausweiten" VSHIFT="-12">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -96016,7 +96016,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699972014017" ID="ID_1464042796" MODIFIED="1700100343215" TEXT="Topologie sichtbar machen">
|
||||
<linktarget COLOR="#62819c" DESTINATION="ID_1464042796" ENDARROW="Default" ENDINCLINATION="21;-256;" ID="Arrow_ID_596151514" SOURCE="ID_1991398605" STARTARROW="None" STARTINCLINATION="787;55;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1699972026007" ID="ID_551004748" MODIFIED="1699984490886" TEXT="Idee: DOT generieren (Graphviz)">
|
||||
<node COLOR="#435e98" CREATED="1699972026007" ID="ID_551004748" MODIFIED="1700105381375" TEXT="Idee: DOT generieren (Graphviz)">
|
||||
<arrowlink COLOR="#435fb4" DESTINATION="ID_1402372766" ENDARROW="Default" ENDINCLINATION="-1358;124;" ID="Arrow_ID_1189460163" STARTARROW="None" STARTINCLINATION="-1697;146;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1699982887957" ID="ID_1019263938" MODIFIED="1699983239443" TEXT="sollte mit einfachsten DOT-Features möglich sein">
|
||||
|
|
@ -96043,8 +96043,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699983274744" ID="ID_1122794529" MODIFIED="1699983281544" TEXT="Darstellungsfeatures bereitstellen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1699983274744" FOLDED="true" ID="ID_1122794529" MODIFIED="1700105386483" TEXT="Darstellungsfeatures bereitstellen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1699984555015" ID="ID_1692130388" MODIFIED="1699984558895" TEXT="von unten nach oben"/>
|
||||
<node CREATED="1699984543111" ID="ID_219083359" MODIFIED="1699984554042" TEXT="Zeitebene : horizontal auf einem Level"/>
|
||||
<node CREATED="1699984727751" ID="ID_1646991690" MODIFIED="1699984735954" TEXT="Seed-Nodes: circle"/>
|
||||
|
|
@ -96135,7 +96135,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1699989949319" ID="ID_1160779868" MODIFIED="1699989973277" STYLE="fork" TEXT="wichtig">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1699989949319" FOLDED="true" ID="ID_1160779868" MODIFIED="1700105389973" STYLE="fork" TEXT="wichtig">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1699989975909" ID="ID_1742749035" MODIFIED="1699990064728">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -96162,11 +96162,14 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699983287679" ID="ID_1236079516" MODIFIED="1699983381771" TEXT="Ausgabestruktur erzeugen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1699983387905" ID="ID_1906181979" MODIFIED="1699983399913" TEXT="muß Klammern und Gruppen erzeugen">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699983287679" ID="ID_1236079516" MODIFIED="1700105397578" TEXT="Ausgabestruktur erzeugen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#435e98" CREATED="1699983387905" FOLDED="true" ID="ID_1906181979" MODIFIED="1700105376397" TEXT="muß Klammern und Gruppen erzeugen">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1699995923504" ID="ID_685647464" MODIFIED="1699995941946" TEXT="brauche eine DSL mit builder-Notation"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node COLOR="#435e98" CREATED="1699995923504" ID="ID_685647464" MODIFIED="1700105364799" TEXT="brauche eine DSL mit builder-Notation">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1699998536090" ID="ID_1929608086" MODIFIED="1699998999619" TEXT="muß Subexpressions in der DSL abgrenzen">
|
||||
<edge COLOR="#82603d" STYLE="linear"/>
|
||||
<node CREATED="1699998574428" ID="ID_1088049425" MODIFIED="1699998608692" TEXT="Möglichkeit-1 : end-Function">
|
||||
|
|
@ -96368,8 +96371,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699983576099" ID="ID_1099057461" MODIFIED="1700100170389" TEXT="einfachen Basis-Renderer für DOT anlegen (ausbaufähig)">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1699983576099" ID="ID_1099057461" MODIFIED="1700105296039" TEXT="einfachen Basis-Renderer für DOT anlegen (ausbaufähig)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1699984818923" ID="ID_1140148647" MODIFIED="1700099172943" TEXT="Generator-Funktionen für Standard-Codebausteine">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -96387,8 +96390,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
...aber sage erst mal <b>YAGNI</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1700099220184" ID="ID_98826849" MODIFIED="1700099995491" TEXT="das wäre nämlich nicht trivial in C++">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
|
|
@ -96413,10 +96415,35 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1699983654942" ID="ID_1968810638" MODIFIED="1699983679568" TEXT="lokale Spezialisierung hiervon im Arbeits-Scope">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699983654942" ID="ID_1968810638" MODIFIED="1700105304336" TEXT="lokale Spezialisierung hiervon im Arbeits-Scope">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1700105305528" ID="ID_1899482943" MODIFIED="1700105320553" TEXT="testweise direkt im verify_Topology() aufgebaut">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1700105322133" ID="ID_1080416201" MODIFIED="1700105347114" TEXT="einfache For-Schleife mit »schleppendem« time-Level">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700105473288" ID="ID_363744899" MODIFIED="1700105544295" TEXT="Operatoren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1700105477363" ID="ID_1347431300" MODIFIED="1700105485349" TEXT="Iteration über alle Nodes">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1700105486643" ID="ID_305524836" MODIFIED="1700105501783" TEXT="exponiere direkt lib::IterExplorer()">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1700105502189" ID="ID_1284175277" MODIFIED="1700105541879" TEXT="alle weiteren Operatoren lassen sich dann leicht darauf aufbauen"/>
|
||||
<node COLOR="#338800" CREATED="1700105521395" ID="ID_5876464" MODIFIED="1700105535812" TEXT="Umgang mit const Nodes ermöglichen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700105549294" ID="ID_1778641158" MODIFIED="1700105554766" TEXT="Neuberechnung">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700105555476" ID="ID_587761135" MODIFIED="1700105558876" TEXT="Scheduling">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -103828,6 +103855,19 @@ class Something
|
|||
<node CREATED="1699978461307" ID="ID_1957589954" MODIFIED="1699978480653" TEXT="color : outline / edges"/>
|
||||
<node CREATED="1699978481466" ID="ID_1236422711" MODIFIED="1699978503602" TEXT="fillcolor — setzt style=filled vorraus"/>
|
||||
</node>
|
||||
<node CREATED="1700105113377" ID="ID_1656490787" LINK="https://graphviz.org/faq/#FaqLarger" MODIFIED="1700105197251" TEXT="Größen">
|
||||
<node CREATED="1700105117995" ID="ID_1615340120" LINK="https://graphviz.org/docs/attrs/size/" MODIFIED="1700105130514" TEXT="size">
|
||||
<node CREATED="1700105132262" ID="ID_343226797" MODIFIED="1700105138969" TEXT="maximalgräße in Inches"/>
|
||||
<node CREATED="1700105139702" ID="ID_1994987569" MODIFIED="1700105152857" TEXT="size! : dann verbindliche Größe"/>
|
||||
<node CREATED="1700105153462" ID="ID_1167641306" MODIFIED="1700105161830" TEXT="Wechselwirkung mit ratio"/>
|
||||
</node>
|
||||
<node CREATED="1700105163468" ID="ID_514140217" LINK="https://graphviz.org/docs/attrs/ratio/" MODIFIED="1700105172944" TEXT="ratio">
|
||||
<node CREATED="1700105202533" ID="ID_133109322" MODIFIED="1700105215303" TEXT="entweder numerisches Seitenverhältnis"/>
|
||||
<node CREATED="1700105215851" ID="ID_948086315" MODIFIED="1700105219623" TEXT="oder Strategie">
|
||||
<node CREATED="1700105253878" ID="ID_1875666186" MODIFIED="1700105266504" TEXT="fill / compress / expand / auto"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue