From 5f0b8b8a810e53ea56d793ad06b2dcac0320b7c6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 10 Oct 2024 21:35:02 +0200 Subject: [PATCH] Invocation: usage analysis for prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...after having determined the several levels of prototyping currently employed, an important step ahead could be achieved by analysing the intended and implied usage context of this builder scheme, while still assuming the simplifications related to prototyping. It can be assumed that * the Level-2 builder object is ''somehow provided'' * the invocation happens from within a media-handling lib-plugin * alongside with the desired `ProcAsset` spec, an `ExpectationContext` will be provided, allowing to pass-through additional semantic tags The implementation in the lib-plugin is then able to draw from specific knowledge related to the **Domain Ontology** for ''especially for this library'' and provide the necessary wrappers and parameter mapping information. ⟹ the **Level-2**-builder should thus expose an API to * set up a straight forward mapping, based on a given wrapper functor to delegate to the actual library invocation * allow optionally to override some of the input connections * alternatively allow to use a complete `InvocationAdapter`, including a `FeedManifold`, as provided directly by the library-plugin --- src/steam/engine/node-builder.hpp | 54 +++- src/steam/engine/turnout.hpp | 2 +- wiki/thinkPad.ichthyo.mm | 498 ++++++++++++++++++++++++------ 3 files changed, 461 insertions(+), 93 deletions(-) diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index 3afc11253..7b5e7988e 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -204,17 +204,20 @@ namespace engine { , util::MoveOnly { public: + + template PortBuilder - inSlots (uint s) + invoke (FUN&& fun) { - UNIMPLEMENTED ("define number of predecessor-source slots"); + UNIMPLEMENTED ("setup standard wiring to adapt the given processing function"); return move(*this); } + template PortBuilder - outSlots (uint r) + adaptInvocation(ARGS&& ...args) { - UNIMPLEMENTED ("define number of result slots"); + UNIMPLEMENTED ("specify an `InvocationAdapter` to use explicitly"); return move(*this); } @@ -226,6 +229,49 @@ namespace engine { return move(*this); } + PortBuilder + asResultSlot (uint r) + { + UNIMPLEMENTED ("define the output slot to use as result (default is the first one)"); + return move(*this); + } + + PortBuilder + connectLead (uint idx) + { + UNIMPLEMENTED ("connect the next input slot to existing lead-node given by index"); + return move(*this); + } + + PortBuilder + conectLead (ProcNode& leadNode) + { + UNIMPLEMENTED ("connect the next input slot to either existing or new lead-node"); + return move(*this); + } + + PortBuilder + connectLeadPort (uint idx, uint port) + { + UNIMPLEMENTED ("connect next input to lead-node, using a specific port-number"); + return move(*this); + } + + PortBuilder + connectLeadPort (ProcNode& leadNode, uint port) + { + UNIMPLEMENTED ("connect next input to existing or new lead-node, with given port-number"); + return move(*this); + } + + PortBuilder + useLeadPort (uint defaultPort) + { + UNIMPLEMENTED ("use given port-index as default for all following connections"); + return move(*this); + } + + /****************************************************//** * Terminal: complete the Port wiring and return to the node level. */ diff --git a/src/steam/engine/turnout.hpp b/src/steam/engine/turnout.hpp index 06407a713..4fe0bbe8d 100644 --- a/src/steam/engine/turnout.hpp +++ b/src/steam/engine/turnout.hpp @@ -428,7 +428,7 @@ namespace engine { Feed mount() { - return Feed{}; + return Feed{}; //////////////////////OOO cant work this way ... need to pass-in a processing functor for the ctor } void diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index d64d14929..bde4f6033 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -6154,9 +6154,7 @@ - - - +

...wartet noch darauf, @@ -6407,9 +6405,7 @@ - - - +

das ist ein gaaaanz großes Strategisches Thema; vor 2023 hatte ich schon mehrfach versucht, es zu fassen — das ist mir aber bisher nicht gelungen, und deshalb wartet es.... ⌛ @@ -6423,9 +6419,7 @@ - - - +

eigentlich wollen wir "das aktuelle" @@ -6662,9 +6656,7 @@ - - - +

Njet @@ -6802,9 +6794,7 @@ - - - +

damit UNDO funktionieren kann, @@ -7546,9 +7536,7 @@ - - - +

wer bestimmt, @@ -8465,9 +8453,7 @@ - - - +

Problem: Layer sind verkoppelt @@ -9586,9 +9572,7 @@ - - - +

...das heißt, es ist nicht möglich, @@ -11497,9 +11481,7 @@ - - - +

bis jetzt kommen wir ohne Pos-Abstraktion aus @@ -14113,9 +14095,7 @@ - - - +

...denn durch overwrite kann man denormalisierte Pattern erzeugen. @@ -18505,9 +18485,7 @@ - - - +

repräsentiert einen benannten Zeit-Bereich: @@ -18540,9 +18518,7 @@ - - - +

Ein Mini-Container mit Placement, Name und einem Inhalts-Renderer @@ -25878,9 +25854,7 @@ - - - +

...ich hab ja nicht umsonst in der theoretischen Analyse herausgefunden, daß dieses Schema auf ein Phasen-Modell hinausläuft; die Hoffnung wäre höchstens gewesen, daß in der Praxis der 3.Pass derart degeneriert,  daß man ihn in den 1.Pass einfalten kann @@ -25919,9 +25893,7 @@ - - - +

berücksichtigt also nicht die Dekoration und das Padding... obwohl doch eigentlich der 2.Pass das Track-Profil aufgebaut haben sollte @@ -25936,9 +25908,7 @@ - - - +

der Test-Diff ist ungeschickt geschrieben @@ -39453,9 +39423,7 @@ - - - +

Demnach wäre die Übersetzung von Pixel-Koordinaten in irgend etwas modell-Releavantes komplet in das Subject eingekapselt; der Gesten-Controller würde dann einen Screen-relativen Offset aggregieren. Aber auf der zweiten Stufe bleiben wir bei dem Ansatz, daß die Geste direkt das Modell manipuliert @@ -39465,9 +39433,7 @@ - - - +

...Auch wenn ich ein ungutes Bauchgefühl habe, alle Argumente sprechen im Moment dafür, diesem Hinweis zu folgen und das Design in dieser Richtung auszubauen. Im Besonderen würde nämlich ein konsequentes Umsetzen meines ursprünglichen Konzepts bedeuten, daß das Subject-Interface etwas von der Metrik im Modell, und im Besonderen von eine Zeit-Parameter wissen müßte ― es ist aber absehbar, daß in anderen Situationen gänzlich andere Parameter relevant sein könnten ... man denke bloß an die "Position im Fork" @@ -39495,9 +39461,7 @@ - - - +

verwendet hart gedrahtete Konstante TODO_px_per_second @@ -51431,9 +51395,7 @@ - - - +

  • @@ -51454,9 +51416,7 @@ - - - +

    2017 habe ich zunächst versucht, die Analyse soweit zu treiben, daß sich daraus Strukturen ablesen lassen; die Intention war, darin die einfache Struktur eines direkt "point and shot" gegebenen Commands eingebettet zu finden. Dieses Bestreben mußte abgebrochen werden, da ich noch nicht genug über das konrete Interface weiß, um sachadäquat beurteilen zu können, was notwendig ist. @@ -51466,9 +51426,7 @@ - - - +

    ...stattdessen habe ich dann die schon bestehenden und definierten Teile zusammengebunden, um das direkte Absetzen von fest im Code vorgegebenen Commands zu ermöglichen. Diese gehen seither als einfache symbolische Nachrichten über den UI-Bus. Das gesamte Thema "Argument Binding" ist bereits abschließend behandelt (Marshalling via GenNode). Ebenso der asynchrone Dispatch, und die ebenso asynchron entkoppelte Rückmeldung ("push up") in das UI. @@ -51478,9 +51436,7 @@ - - - +

    2018-2019 habe ich eine dieser Vision entsprechende, offene und generische Grundstruktur des UI angelegt, und begonnen, konkret für die Timeline-Repräsentation auszuimplementieren. Auch dies ist grundsätzlich alles geregelt, wir können ein Custom-Stylesheet aufgreifen, wir können eigene Widgets mit custom-drawing realisieren, und trotzdem weitgehend auf das UI-Toolkitset mit allen seinen Zusatzfunktionen zurückgreifen. Nun (2/2021) bin ich wieder an dem Punkt, an dem die erste, einfachste »Geste« zu realisieren wäre: nämlich das Verschieben eines Clip in der Timeline. Und ich halte genau an der Einsicht fest, daß diese Interaktions-Logik nicht fest in ein Widget eingebaut werden darf.
    Da stehe ich, und mehr weiß ich noch nicht... @@ -51515,9 +51471,7 @@ - - - +

    Der Plan ist, einmal Command-Skripts (C++ basierte DSL-Notation) direkt vom Build-System verarbeiten zu lassen; der Build wird daraus passende C++-Translation-Units generieren und übersetzen. Tatsächlich ist all dies nicht besonders anspruchsvoll, denn die eigentliche Arbeit, die DSL-Notation ist bereits geschaffen. Trotzdem ist das Thema vorerst vertagt, weil zur praktischen Ausführung eine Menge zusätzlichem Wissen aus der Praxis notwendig ist, wie z.B. wie teilt man die Commands ein, wer definiert überhaupt Commands, und zu welchem Zweck. Beispielsweise ist es durchaus später einmal denkbar, daß auch eine Lumiera-Extension (Plug-in) zusätzliche Command-Scripts bereitstellt. Dann stellt sich natürlich auf das (ziemlich anspruchsvolle) Problem der Belegung von Command-IDs erneut. @@ -71691,7 +71645,7 @@ - + @@ -71710,6 +71664,48 @@ + + + + +

    + weiteres Argument: ExpectationContext +

    + +
    + + + + + + + +

    + essentiell wichtig diese offen zu halten, denn die direkten Aufrufer können diese nicht interpretieren, sondern reichen sie aus einem offen zu gestaltenden Model heraus durch; dort können Regeln gewirkt haben, die Attributierungen anbringen, welche dann wieder innerhalb der konkreten Domain-Ontology interpretierbar sind +

    + +
    +
    +
    + + + + +

    + ...da beide Seiten wohl einen konkreten Typ-Kontext haben, ist eine Art double-Dispatch notwendig.... +

    +
      +
    • + der aufrufende Builder muß eine Policy mitgeben, in der der Allokator und weitere Dependency-Injection steckt +
    • +
    • + der empfangende Library-Kontext muß dann aber auf dieser Basis selbst eine Template-Instanz machen, um seine konkreten Implementierungs-Buffer-Typen und Funktoren einzubringen +
    • +
    + +
    + +
    @@ -81340,8 +81336,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    build() generiert einen Connectivity-Record by-value

    - - + @@ -81365,15 +81360,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + + + + - + + + + + + + + - - - + + + + + + + + + + @@ -81495,7 +81507,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + + @@ -81609,6 +81622,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + + + + @@ -81652,7 +81671,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + @@ -81661,6 +81680,42 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

    + + + + + +

    + tatsächlich wird jeder Build-Schritt hier delegiert per Proc-Asset ⟶ Media-Lib (Ontology) +

    + +
    + +
    + + + + +

    + ....denn dadurch können wir eine Meta-Ontology vermeiden: der entscheidende Übersetzungs-Schritt, das Ontology-Mapping aus dem Kontext der Edit-Session in das konkrete Processing erfolgt direkt im Kontext einer konkreten Domain-Ontology, beispielsweise FFMpeg. Vorgegeben ist eine semantische Attributierung der Syntax-Struktur im Session-Model und erwartet wird eine korrekte, konkrete Implementierung derselben. +

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

    + ein Schritt: ExpectationContext ⟼ ProcNode +

    + +
    +
    @@ -87266,8 +87321,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    will sagen: ich gehe erst mal im Prototyping von einer Test-Ontology aus, die sich aber informell bereits auf meine Kenntnis der Domäne (Video-Processing) abstützt

    - -
    +
    @@ -87280,8 +87334,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    wie beide aus einer »Ontology« heraus angelegt und gesteuert werden können

    - - +
    @@ -87291,8 +87344,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    und letztlich wie dann ein konkreter Aufruf ablaufen kann

    - -
    +
    @@ -87302,8 +87354,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    sich nicht verrückt machen: das hier ist ein hermeneutischer Zirkel: Um ein gutes Werkzeug bauen zu können, muß ich die Sache  verstehen — und das mache ich, indem ich auf den Werkzeuggebrauch hin stipuliere

    - -
    +
    @@ -87311,6 +87362,55 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + + + + +

    + Ziel: Top-down Realisierung des Builder-API +

    + +
    + + + +

    + Vermöge Analyse und Architektur-Design habe ich mich schrittweise an eine Gliederung des Build-Vorganges in verschiedene Level herangearbeitet. Auf dem mittleren Level-2 laufen alle Fäden zusammen; daher ist der Kern der Aufgabe bewältigt, wenn ein sinnvolles und adäquates Builder-API steht +

    + +
    + +
    + + + + +

    + Weg: bottom-up überlegen wie gerendert werden soll +

    + +
    + + + +

    + Um aber auf das notwendige Builder-API schließen zu können, muß ich wissen +

    +
      +
    • + welche Struktur zum Rendern notwendig und deshalb zu bauen ist +
    • +
    • + wie diese Struktur aus dem Kontext der Domain-Ontologie heraus spezifiziert wird +
    • +
    + +
    + +
    +
    @@ -87751,9 +87851,22 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + + + + + +

    + im alten Design von 2012 war die »Buffer Table« gedacht als eine Entität, die zumindest operational eine gewisse Abstraktion leistet. Im neuen Entwurf dagegen bemerke ich eine starke Tendenz, dies nur noch als eine Laufzeit-Datenstruktur zu betrachten, die durch das »WeavingPattern« bespielt wird +

    + +
    +
    @@ -87871,6 +87984,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + @@ -89202,9 +89316,176 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + + + + + + + + + + + + + + + + +

    + muß irgendwie in den PortBuilder +

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

    + zur Laufzeit haben wir Services wie den Cache und die BufferProvider; diese sollten beser nicht dirket auf dem Builder-API sichtbar sein, sondern magisch injiziert werden +

    + +
    +
    + + + + + + + +

    + jetzt habe ich einen SimpleWeavingBuilder geschrieben, dem man das alles explizit sagen muß +

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

    + ...technisch ist das ein kniffeliger double-Dispatch; beide Seiten der Interaktion haben jeweils einen konkreten Typkontext, den man so nicht direkt als API-Funktion ausdrücken kann, und ich kann im Moment noch nicht vorhersagen, wie das zu lösen ist — es wird darauf ankommen, die Indirektion geschickt zu drehen, so daß sie auf etwas Generisches fällt. +

    + +
    +
    + + + + +

    + mache hier (für den Prototyp) die Anahme: der Level-2-Builder kann konstruiert werden +

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

    + ...insofern die Library die richtigen Eingänge wählen muß und deshalb Annahmen (oder explizite Informationen) zu den Leed-Nodes benötigt; zumindest kann unterstellt werden, daß auch die Lead-Nodes durch die gleiche Library implementiert werden, oder Adapter darstellen, welche kompatible Stromdaten für diese Library produzieren +

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

    + ...das heißt, es kann mehr Leads als Slots geben +

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

    + (oder eines InvocationAdapters oder Pattern Builders) +

    + +
    + +
    +
    @@ -89212,6 +89493,30 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + + + + +

    + ...für sich genommen wäre das eine Festlegung auf das »simple weaving pattern« — das bedeutet, 1:1-Verdrahtung mit explizit anzugebenden Ausnahmen +

    + +
    +
    + + + + +

    + das bedeutet: ein Builder für eine bestimmte Art Weaving-Pattern kann letztlich auch direkt einen Turnout konstruieren, sofern nur das WeavingPattern die 5 Schritte als Member-Functions bereitstellt, welche notwendig sind, um das Port-API zu implementieren +

    + +
    + +
    +
    @@ -89224,7 +89529,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + + + + +

    + ...durch Delegieren an PAT::mount()  —  wobei PAT ≡ weaving pattern +

    + +
    +
    @@ -89234,6 +89548,14 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

    + + + +

    + ....und zwar durch Festlegen des konkreten Typs des Turnout, welcher dann das Weaving-Pattern als Mix-in einbindet, um auf dieser Basis das Turnout-Interface zu implementieren +

    + +