diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp index 9bdfc92e5..086d209b7 100644 --- a/src/steam/engine/feed-manifold.hpp +++ b/src/steam/engine/feed-manifold.hpp @@ -73,6 +73,15 @@ namespace engine { BuffS inBuff; BuffS outBuff; + + uint resultSlot{0}; + + BuffHandle + result() const + { + ENSURE (resultSlot < N, "invalid result buffer retrieved."); + return outBuff[resultSlot]; + } }; diff --git a/src/steam/engine/proc-node.hpp b/src/steam/engine/proc-node.hpp index 6a0cdb60d..ee571ec1d 100644 --- a/src/steam/engine/proc-node.hpp +++ b/src/steam/engine/proc-node.hpp @@ -79,6 +79,8 @@ namespace engine { virtual BuffHandle weave (TurnoutSystem&) =0; }; + using PortRef = std::reference_wrapper; + /** * Interface: Description of the input and output ports, * processing function and predecessor nodes for a given ProcNode. diff --git a/src/steam/engine/turnout.hpp b/src/steam/engine/turnout.hpp index 278bbe9ca..8455268ed 100644 --- a/src/steam/engine/turnout.hpp +++ b/src/steam/engine/turnout.hpp @@ -267,6 +267,61 @@ namespace engine { }; + template + struct SimpleWeavingPattern + : PAR + { + using Feed = FeedManifold; + + uint fanIn{0}; + uint fanOut{0}; + + template + using Storage = lib::UninitialisedStorage; + + + Storage leadPort; + Storage inDescr; + Storage outDescr; + + //////////////////////////////////////////OOO builder must set-up those descriptors + + Feed + mount() + { + return Feed{}; + } + + void + pull (Feed& feed, TurnoutSystem& turnoutSys) + { + for (uint i=0; i - - - +

wirkt alles mehr oder weniger beliebig... @@ -790,9 +788,7 @@ - - - +

0000000937: ERR: core-service.hpp:111: worker_3: ~CoreService: Some UI components are still connected to the backbone. @@ -812,9 +808,7 @@ - - - +

...muß diejenigen Bus-Verbindungen abziehen, die von Members dieser Klasse stammen @@ -2028,9 +2022,7 @@ - - - +

...wenn wir eine Mix-in -Implementierung wählen @@ -3509,9 +3501,7 @@ - - - +

ein ZombieCheck spricht an @@ -6005,9 +5995,7 @@ - - - +

...welche ad hoc mit beiläufig geschriebenem Debug/Test-Code belegt werden @@ -9382,9 +9370,7 @@ - - - +

wir haben bisher viel zu naiv angenommen, @@ -86982,6 +86968,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + @@ -87176,8 +87167,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -87236,7 +87227,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -87246,7 +87237,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + +

+ Beschluß: nicht Mehrfach-Outputs, sondern Array-wertige Outputs +

+ +
@@ -87302,8 +87301,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -87327,7 +87327,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -87362,6 +87362,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + +

+ dazu müßte man erst mal diverse komplexe Fälle im Detail durchspielen... +

+
    +
  • + ist es wirklich möglich, diese Auflösung und Zuordnung sofort vom Builder-Call aus zu machen? +
  • +
  • + braucht man die tatsächlichen Koordinaten wirklich nicht mehr später, zur Laufzeit? +
  • +
+ +
+ +
+ + + +
@@ -87706,14 +87732,124 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + + + + + + + + + + + + + + + + + + + + +

+ das wäre KISS; man würde den gleichen Template-Parameter N heranziehen, der auch die FeedManifold steuert; dieser wird nach dem Schema »eins«, »zwei«, »viele« belegt. Zusätzlich gibt es für diesen Ansatz dann eine dynamische Spec über die tatsächliche Anzahl der Buffer In/Out (die stets <= N wäre) +

+ + +
+ +
+ + + + +

+ Im einfachsten Fall wäre das genauso wie die erste Lösung, nur daß der Buffer nicht im Haupt-Objekt liegt (aber natürlich trotzdem im Allocation-Cluster). Allerdings gäbe es hier noch eine weitere, halb-dynamische Lösung: man würde explizit einen Buffer dynamisch allozieren (direkter Allokator-Aufruf, bei dem man die Anzahl Elemente angibt). Das läuft auf einen minimalistischen Spezial-Container hinaus, oder eine ScopedCollection mit Custom-Allocator, oder dann gleich die nächste Lösung.... +

+ + +
+
+ + + + +

+ ...dies ist mit wenig Entwicklungs-Aufgand umzusetzen, erfordert dann aber trotzdem eine explizite Verdrahtung des Allocators und damit eine Vermischung zwischen Objekt-Konstruktion und Builder/Allocator. +

+ + +
+
+ + + + +

+ Unabhängig davon, welche der drei vorgenannten Lösungen zum Zuge kommt, gibt es steths noch eine weitere, komplexere Variante, die aber sehr attraktiv erscheint: es ist nämlich in den weitaus meisten Fällen so, daß nur ein einziger, einheitlicher Buffer-Typ zum Einsatz kommt; daher läuft das Belegen eines Array mit einem expliziten Deskriptor für jeden »Slot« auf erhebliche Speicherverschwendung hinaus. Stattdessen könnte man versucht sein, die Belegung durch ein Stück Code machen zu lassen (eine Closure), und dafür eine Meta-Spec zu interpretieren. Das wird aber in jedem Fell recht komplexer Code, der dann auch zur Render-Zeit läuft (ja wirklich, in jedem Aufruf), und deshalb wieder das Problem aufwirft, woher man die Storage für temporäre Datenstrukturen nimmt. Denn solche wird es zwingend geben, schließlich muß man ja irgendwie markieren, was die bereits behandelten Spezialfälle sind, und welche »Slots« damit übrig bleiben und mit dem Standard-Fall behandelt werden müssen. Ja mei! +

+ + +
+
+
+ + + + + + + +

+ diese Lösung ist wohl etwas brachial +

+ + +
+ + + +

+ ...vor allem gibt es kein »Sicherheitsnetz« — ein Umstand, der mich nachdenklich stimmt, da hier doch ein sehr komplexes Code-System entsteht, in dem die Ausführungs-Pfade keineswegs auf sicheren, festen Bahnen verlaufen... Sollte dann wohl doch in Betracht ziehen, einen passenden, speichersicheren »in-Place«-Container zu implementieren +

+ +
+ + +
+
+
+ + + + + + +

+ ...grundsätzlich besteht diese Möglichkeit, und sie könnte eine gewisse Relevanz bekommen, sobald wir es mit Hardware-Accelleration zu tun haben. Dennoch halte ich das nicht für den Regelfall, und zudem treibt es die Komplexität hoch +

+ + +
+ +
+ + + + + + + + + + + - - @@ -88019,6 +88155,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + +

+ ...und zwar, weil sie nicht speichersicher ist! +

+

+ Das ist genau die Sorte Code, die man zwar durchaus aus Performance-Gründen schreiben kann, aber dann besser nur in einem sorgsam abgezirkelten Implementierungs-Zusammenhang. Genau diese Eingrenzung ist hier aber nicht gegeben: vielmehr entsteht hier ein Baukasten-System, und es ist ohne Weiteres möglich, daß ein Turnout mit falschen Parametern initialisiert wird. +

+

+ +

+

+   ⚠ In einem solchen Fall könnte die Ausführung direkt in die Interpretation +

+

+         von uninitialisiertem Speicher laufen. +

+ +
+ + +
+