Invocation: build a complex Render Node network for integration test
Using basically the same topology as in the preceding test, which focused on connectivity. However, in this case we retrieve actual processing functions from the »Test-Rand« ontology in order to perform hash-chaining computations on full data blocks. And, in addition, a »Param Agent Node« is used.
This commit is contained in:
parent
6c2761b337
commit
93812d5a6d
5 changed files with 175 additions and 51 deletions
|
|
@ -90,10 +90,10 @@ namespace test {
|
|||
verify_TurnoutSystem()
|
||||
{
|
||||
Time nomTime{rani(10'000),0}; // drive test with a random »nominal Time« <10s with ms granularity
|
||||
TurnoutSystem invoker{nomTime}; // a time spec is mandatory, all further parameters are optional
|
||||
TurnoutSystem turoSys{nomTime}; // a time spec is mandatory, all further parameters are optional
|
||||
|
||||
CHECK (invoker.getNomTime() == nomTime); // can access those basic params from within the render invocation.
|
||||
CHECK (invoker.getProcKey() == ProcessKey{});
|
||||
CHECK (turoSys.getNomTime() == nomTime); // can access those basic params from within the render invocation.
|
||||
CHECK (turoSys.getProcKey() == ProcessKey{});
|
||||
|
||||
/* == That's all required for basic usage. == */
|
||||
|
||||
|
|
@ -108,14 +108,14 @@ namespace test {
|
|||
{// Build and connect extension storage block
|
||||
auto dataBlock = // ...typically placed locally into a nested stack frame
|
||||
spec.makeBlockBuilder()
|
||||
.buildParamDataBlock(invoker);
|
||||
.buildParamDataBlock(turoSys);
|
||||
|
||||
invoker.attachChainBlock (dataBlock); // link extension data block into the TurnoutSystem
|
||||
CHECK (invoker.get(acc0) == someVal); // now able to retrieve data from extension block
|
||||
invoker.detachChainBlock (dataBlock);
|
||||
turoSys.attachChainBlock (dataBlock); // link extension data block into the TurnoutSystem
|
||||
CHECK (turoSys.get(acc0) == someVal); // now able to retrieve data from extension block
|
||||
turoSys.detachChainBlock (dataBlock);
|
||||
}
|
||||
// base block continues to be usable...
|
||||
CHECK (invoker.getNomTime() == nomTime);
|
||||
CHECK (turoSys.getNomTime() == nomTime);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ namespace test {
|
|||
CHECK (not watch(nFilt).isSrc());
|
||||
CHECK (watch(nSrc).getNodeSpec() == "Test:generate-◎"_expect );
|
||||
CHECK (watch(nFilt).getNodeSpec() == "Test:manipulate◁—Test:generate-◎"_expect );
|
||||
CHECK (watch(nFilt).getPortSpec(0) == "manipulate(TestFrame)"_expect );
|
||||
CHECK (watch(nFilt).getPortSpec(0) == "manipulate(TestFrame)(TestFrame)"_expect );
|
||||
|
||||
// prepare to invoke this Node chain...
|
||||
BufferProvider& provider = DiagnosticBufferProvider::build();
|
||||
|
|
@ -468,7 +468,7 @@ namespace test {
|
|||
CHECK (watch(nS1).getNodeSpec() == "Test:generate-◎"_expect );
|
||||
CHECK (watch(nS2).getNodeSpec() == "Test:generate-◎"_expect );
|
||||
CHECK (watch(nMix).getNodeSpec() == "Test:combine┉┉{Test:generate}"_expect );
|
||||
CHECK (watch(nMix).getPortSpec(0) == "combine(TestFrame/2)"_expect );
|
||||
CHECK (watch(nMix).getPortSpec(0) == "combine(TestFrame/2)(TestFrame)"_expect );
|
||||
|
||||
// prepare to invoke this Node chain...
|
||||
BufferProvider& provider = DiagnosticBufferProvider::build();
|
||||
|
|
|
|||
|
|
@ -21,8 +21,11 @@
|
|||
#include "steam/engine/node-builder.hpp"
|
||||
#include "steam/engine/test-rand-ontology.hpp"
|
||||
#include "steam/engine/diagnostic-buffer-provider.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"/////////////////TODO
|
||||
#include "steam/asset/meta/time-grid.hpp"
|
||||
#include "lib/time/timequant.hpp"
|
||||
#include "lib/time/timecode.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"/////////////////TODO
|
||||
|
||||
#include <array>
|
||||
|
||||
|
|
@ -35,6 +38,10 @@ namespace steam {
|
|||
namespace engine{
|
||||
namespace test {
|
||||
|
||||
using lib::time::Time;
|
||||
using lib::time::QuTime;
|
||||
using lib::time::FrameNr;
|
||||
using lib::time::FrameCnt;
|
||||
|
||||
|
||||
|
||||
|
|
@ -313,8 +320,9 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/** @test TODO Invoke some render nodes as linked together
|
||||
* @todo WIP 12/24 🔁 define ⟶ implement
|
||||
* @todo WIP 2/25 🔁 define ⟶ ✔ implement
|
||||
*/
|
||||
void
|
||||
trigger_node_port_invocation()
|
||||
|
|
@ -323,70 +331,134 @@ namespace test {
|
|||
auto testMan = testRand().setupManipulator();
|
||||
auto testMix = testRand().setupCombinator();
|
||||
|
||||
/*
|
||||
ont::Flavr SRC_A = 10;
|
||||
ont::Flavr SRC_B = 20;
|
||||
|
||||
// Prepare for Time-Quantisation --> Frame-# or Offset parameter
|
||||
Symbol SECONDS_GRID = "grid_sec";
|
||||
steam::asset::meta::TimeGrid::build (SECONDS_GRID, 1);
|
||||
|
||||
|
||||
// Prepare a precomputed parameter for the complete tree
|
||||
auto selectFrameNo = [&](TurnoutSystem& tuSys){ return FrameNr::quant (tuSys.getNomTime(), SECONDS_GRID); };
|
||||
auto paramSpec = buildParamSpec()
|
||||
.addSlot (selectFrameNo);
|
||||
|
||||
auto accFrameNo = paramSpec.makeAccessor<0>();
|
||||
|
||||
// Prepare mapping- and automation-functions
|
||||
auto stepFilter = [] (FrameCnt id)-> ont::Param { return util::limited (10, -10 + id, 20); };
|
||||
auto stepMixer = [] (FrameCnt id)-> double { return util::limited (0, + id, 50) / 50.0; };
|
||||
|
||||
// note: binds the accessor for the precomputed FrameNo-parameter
|
||||
auto autoFilter = [=](TurnoutSystem& tuSys){ return stepFilter (tuSys.get (accFrameNo)); };
|
||||
auto autoMixer = [=](TurnoutSystem& tuSys){ return stepMixer (tuSys.get (accFrameNo)); };
|
||||
|
||||
|
||||
// A Node with two (source) ports
|
||||
ProcNode n1s{prepareNode("srcA")
|
||||
.preparePort()
|
||||
.invoke("a(int)", src_op)
|
||||
.setParam(5)
|
||||
.invoke(testGen.procID(), testGen.makeFun()) // params(frameNo, flavour)
|
||||
.closeParam<1>(SRC_A + 0) // --> flavour ≔ SRC_A + port#0
|
||||
.retrieveParam(accFrameNo)
|
||||
.completePort()
|
||||
.preparePort()
|
||||
.invoke("b(int)", src_op)
|
||||
.setParam(23)
|
||||
.invoke(testGen.procID(), testGen.makeFun())
|
||||
.closeParam<1>(SRC_A + 1) // --> flavour ≔ SRC_A + port#1
|
||||
.retrieveParam(accFrameNo)
|
||||
.completePort()
|
||||
.build()};
|
||||
|
||||
// A node to add some "processing" to each data chain
|
||||
auto add1_op = [](int* src, int* res){ *res = 1 + *src; };
|
||||
// A node to »filter« the data in chain-A
|
||||
ProcNode n1f{prepareNode("filterA")
|
||||
.preparePort()
|
||||
.invoke("a+1(int)(int)", add1_op)
|
||||
.invoke(testMan.procID(), testMan.makeFun())
|
||||
.attachParamFun(autoFilter) // filter-param <-- autoFilter(frameNo)
|
||||
.connectLead(n1s)
|
||||
.completePort()
|
||||
.preparePort()
|
||||
.invoke("b+1(int)(int)", add1_op)
|
||||
.invoke(testMan.procID(), testMan.makeFun())
|
||||
.attachParamFun(autoFilter)
|
||||
.connectLead(n1s)
|
||||
.completePort()
|
||||
.build()};
|
||||
|
||||
// Need a secondary source, this time with three ports
|
||||
|
||||
// A secondary source Node, this time with three ports
|
||||
ProcNode n2s{prepareNode("srcB")
|
||||
.preparePort()
|
||||
.invoke("a(int)", src_op)
|
||||
.setParam(7)
|
||||
.invoke(testGen.procID(), testGen.makeFun()) // params(frameNo, flavour)
|
||||
.closeParam<1>(SRC_B + 0) // --> flavour ≔ SRC_B + port#0
|
||||
.retrieveParam(accFrameNo)
|
||||
.completePort()
|
||||
.preparePort()
|
||||
.invoke("b(int)", src_op)
|
||||
.setParam(13)
|
||||
.invoke(testGen.procID(), testGen.makeFun())
|
||||
.closeParam<1>(SRC_B + 1) // --> flavour ≔ SRC_B + port#1
|
||||
.retrieveParam(accFrameNo)
|
||||
.completePort()
|
||||
.preparePort()
|
||||
.invoke("c(int)", src_op)
|
||||
.setParam(17)
|
||||
.invoke(testGen.procID(), testGen.makeFun())
|
||||
.closeParam<1>(SRC_B + 2) // --> flavour ≔ SRC_B + port#2
|
||||
.retrieveParam(accFrameNo)
|
||||
.completePort()
|
||||
.build()};
|
||||
|
||||
// Wiring for the Mix, building up three ports
|
||||
// Since the first source-chain has only two ports,
|
||||
// for the third result port we'll re-use the second source
|
||||
|
||||
// Wiring for the Mix, building three ports,
|
||||
// drawing from both source-chains
|
||||
ProcNode mix{prepareNode("mix")
|
||||
.preparePort()
|
||||
.invoke("a-mix(int/2)(int)", mix_op)
|
||||
.invoke(testMix.procID(), testMix.makeFun())
|
||||
.attachParamFun(autoMixer) // mixer-param <-- autoMixer(frameNo)
|
||||
.connectLead(n1f)
|
||||
.connectLead(n2s)
|
||||
.completePort()
|
||||
.preparePort()
|
||||
.invoke("b-mix(int/2)(int)", mix_op)
|
||||
.invoke(testMix.procID(), testMix.makeFun())
|
||||
.attachParamFun(autoMixer)
|
||||
.connectLead(n1f)
|
||||
.connectLead(n2s)
|
||||
.completePort()
|
||||
.preparePort()
|
||||
.invoke("c-mix(int/2)(int)", mix_op)
|
||||
.connectLeadPort(n1f,1)
|
||||
.invoke(testMix.procID(), testMix.makeFun())
|
||||
.attachParamFun(autoMixer)
|
||||
.connectLeadPort(n1f,1) // note: using 2nd port from chain-A, which only has two ports
|
||||
.connectLead(n2s)
|
||||
.completePort()
|
||||
.build()};
|
||||
*/
|
||||
UNIMPLEMENTED ("operate some render nodes as linked together");
|
||||
|
||||
|
||||
// Set a »Param-Agent«-Node on top to pre-compute the FrameNo
|
||||
ProcNode parNode{prepareNode("Param")
|
||||
.preparePort()
|
||||
.computeParam(paramSpec)
|
||||
.delegateLead(mix)
|
||||
.completePort()
|
||||
.preparePort()
|
||||
.computeParam(paramSpec)
|
||||
.delegateLead(mix)
|
||||
.completePort()
|
||||
.preparePort()
|
||||
.computeParam(paramSpec)
|
||||
.delegateLead(mix)
|
||||
.completePort()
|
||||
.build()};
|
||||
|
||||
|
||||
BufferProvider& provider = DiagnosticBufferProvider::build();
|
||||
const BuffDescr buffDescr = provider.getDescriptorFor(sizeof(TestFrame));
|
||||
|
||||
auto invoke = [&](Time nomTime, uint port)
|
||||
{ // Sequence to invoke a Node...
|
||||
BuffHandle buff = provider.lockBuffer(buffDescr);
|
||||
CHECK (not buff.accessAs<TestFrame>().isValid());
|
||||
buff = parNode.pull (port, buff, nomTime, ProcessKey{});
|
||||
HashVal checksum = buff.accessAs<TestFrame>().getChecksum();
|
||||
buff.release();
|
||||
return checksum;
|
||||
};
|
||||
|
||||
SHOW_EXPR(invoke(Time::ZERO, 1));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -225,8 +225,9 @@ namespace test {
|
|||
string
|
||||
procSpec()
|
||||
{
|
||||
return _Fmt{"%s(%s)"}
|
||||
return _Fmt{"%s(%s)(%s)"}
|
||||
% (filter? util::showHash(filter):"")
|
||||
% streamType
|
||||
% streamType;
|
||||
}
|
||||
};
|
||||
|
|
@ -254,7 +255,8 @@ namespace test {
|
|||
string
|
||||
procSpec()
|
||||
{
|
||||
return _Fmt{"(%s/2)"}
|
||||
return _Fmt{"(%s/2)(%s)"}
|
||||
% streamType
|
||||
% streamType;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -105765,7 +105765,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1739227684914" ID="ID_1108065190" MODIFIED="1739227736066" TEXT="und das scaffolding muß im Test-Code verständlich bleiben">
|
||||
<node CREATED="1739228198716" ID="ID_566097177" MODIFIED="1739228220611" TEXT="sollte also möglichst die Standard Node-Builder-Fälle nutzen"/>
|
||||
</node>
|
||||
<node CREATED="1739227741390" ID="ID_803165715" MODIFIED="1739227795410" TEXT="aber dieser 3.Testfall kann schon noch ein Zacken komplexer sein">
|
||||
<node CREATED="1739227741390" ID="ID_803165715" MODIFIED="1739988451652" TEXT="aber dieser 3.Testfall kann schon noch ein Zacken komplexer sein">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1739228229334" ID="ID_1295084534" MODIFIED="1739228240372" TEXT="es könnte schon ein Integrationstest sein"/>
|
||||
<node CREATED="1739228241556" ID="ID_481563144" MODIFIED="1739228254206" TEXT="...der diese ganze Prototyping-Phase besiegelt"/>
|
||||
<node CREATED="1739228257834" ID="ID_980216686" MODIFIED="1739228281727">
|
||||
|
|
@ -105784,9 +105785,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1739229080787" ID="ID_508301525" MODIFIED="1739229206584" TEXT="komplett über das Turnout-System steuern"/>
|
||||
<node CREATED="1739229119334" ID="ID_144074931" MODIFIED="1739229138054" TEXT="es gibt ein einfaches Frame-Grid zur Übersetzung in Frame-Nr"/>
|
||||
<node CREATED="1739229092233" ID="ID_687505824" MODIFIED="1739229232886" TEXT="der ProcessingKey wird testhalber in den Mix-Parameter (0...100) übersetzt"/>
|
||||
<node CREATED="1739229092233" ID="ID_687505824" MODIFIED="1739984911570" TEXT="ausdedem leiten wir einen Offset-Parameter aus der Zeit ab"/>
|
||||
<node CREATED="1739984916213" ID="ID_114154554" MODIFIED="1739984936785" TEXT="aus dem Offset errechnet der Param-Funktor dann den Mix-Parameter"/>
|
||||
<node CREATED="1739229243685" ID="ID_1117664884" MODIFIED="1739229263638" TEXT="eine Param-Node demonstriert das Aufbauen synthetischer Parameter"/>
|
||||
<node COLOR="#338800" CREATED="1739229265043" FOLDED="true" ID="ID_1535044883" MODIFIED="1739914190981" TEXT="neues Feature: ein Param-Tupel im Builder partiell schließen">
|
||||
<node COLOR="#338800" CREATED="1739229265043" FOLDED="true" ID="ID_1535044883" MODIFIED="1739926309278" TEXT="neues Feature: ein Param-Tupel im Builder partiell schließen">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#a60e65" CREATED="1739229289864" ID="ID_719879915" MODIFIED="1739902084019">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -106413,6 +106415,54 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1739926551533" ID="ID_1744658909" MODIFIED="1739926586194" TEXT="in Schleife aufrufen für einen Zeitbereich">
|
||||
<node CREATED="1739926858394" ID="ID_1310843645" MODIFIED="1739926874449" TEXT="jeweils einen Output-Buffer belegen"/>
|
||||
<node CREATED="1739926876070" ID="ID_1858797669" MODIFIED="1739926959714" TEXT="einen zufälligen Zeitpunkt ziehen"/>
|
||||
<node CREATED="1739926961967" ID="ID_763806405" MODIFIED="1739926983118" TEXT="Node aufrufen und Checksumme abgreifen"/>
|
||||
<node CREATED="1739926984356" ID="ID_1685710106" MODIFIED="1739926999349" TEXT="Sofort die Berechnung bare-bone-wiederholen"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1739927022286" ID="ID_1569493230" MODIFIED="1739927035564" TEXT="was mache ich mit den drei Ports?">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1739974041862" ID="ID_152876783" MODIFIED="1739974050013" TEXT="Möglichkeit-1 : random auswählen"/>
|
||||
<node CREATED="1739974052425" ID="ID_922254600" MODIFIED="1739974061779" TEXT="Möglichkeit-2 : zusammenführen">
|
||||
<node CREATED="1739974072046" ID="ID_599872890" MODIFIED="1739974079369" TEXT="das würde den Test deutlich verschärfen"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1739988475500" ID="ID_1619027230" MODIFIED="1739988486611" TEXT="Node-Setup aufbauen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1739988488649" ID="ID_1937491223" MODIFIED="1739988507621" TEXT="per copy-n-paste aus den vorhergehenden Testfällen">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1739988510201" ID="ID_658104724" MODIFIED="1739988915058" TEXT="brauche Param-Node">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1739988517197" ID="ID_68703644" MODIFIED="1739988528313" TEXT="definiere eine Param-Spec mit (nur) einem Slot"/>
|
||||
<node CREATED="1739988529403" ID="ID_11348533" MODIFIED="1739988557117" TEXT="dieser Slot macht die Time ⟼ Frame-Quantisierung"/>
|
||||
<node CREATED="1739989858137" ID="ID_900282341" MODIFIED="1739989865292" TEXT="Accessor speichern"/>
|
||||
<node CREATED="1739989866288" ID="ID_493861231" MODIFIED="1739989875603" TEXT="Accessor in nachgeschalteter Automation verwenden"/>
|
||||
<node COLOR="#338800" CREATED="1739989877848" ID="ID_1873390720" MODIFIED="1739989886659" TEXT="Param-Node per NodeBuilder konstruieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1739989888437" ID="ID_1096325319" MODIFIED="1739989899313" TEXT="geht durch den Compiler">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1739989900451" ID="ID_1706149148" MODIFIED="1739989907994" TEXT="Invocation....">
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1739989909161" ID="ID_1372911486" MODIFIED="1739989918255" TEXT="scheitert mit Exception">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1739990057078" ID="ID_820424784" MODIFIED="1739990076825" TEXT="TestFrame: missing or corrupted metadata">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1739989985056" ID="ID_1521515943" MODIFIED="1739990002894" TEXT="Beobachtung: 3 clean-up-Meldungen vom DiagnosticBufferProvider">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1739990004438" ID="ID_1675021686" MODIFIED="1739990013969" TEXT="wir verwenden nur zwei Instanzen">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1739990015547" ID="ID_75625440" MODIFIED="1739990022949" TEXT="woher kommt die 3.Meldung?"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue