Invocation: complement NodeBase_test with simple example
While initially intended as introductory test, it meanwhile focuses on intricate technical details on the level of basic building blocks, notably the `FeedManifold` Now I have added a simple end-to-end demonstration example how a Render Node is built from scratch, leaving out all technical details and all convenience front-ends like the `NodeBuilder` — just one dummy port invoked directly.
This commit is contained in:
parent
8a4060861f
commit
6c2761b337
3 changed files with 133 additions and 28 deletions
|
|
@ -2,7 +2,7 @@ TESTING "Component Test Suite: Render Engine parts" ./test-suite --group=node
|
|||
|
||||
|
||||
|
||||
PLANNED "Proc Node basics" NodeBase_test <<END
|
||||
TEST "Proc Node basics" NodeBase_test <<END
|
||||
END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "lib/iter-zip.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/several-builder.hpp"
|
||||
#include "steam/engine/proc-node.hpp"
|
||||
#include "steam/engine/turnout.hpp"
|
||||
#include "steam/engine/turnout-system.hpp"
|
||||
|
|
@ -27,17 +28,14 @@
|
|||
#include "steam/engine/diagnostic-buffer-provider.hpp"
|
||||
#include "steam/engine/buffhandle-attach.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
//#include "lib/format-cout.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"/////////////////////TODO
|
||||
#include "lib/format-util.hpp"///////////////////////////////TODO
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
||||
//using std::string;
|
||||
using std::tuple;
|
||||
using std::array;
|
||||
using util::isSameAdr;
|
||||
using lib::test::showType;
|
||||
using lib::makeSeveral;
|
||||
using lib::izip;
|
||||
|
||||
|
||||
|
|
@ -46,14 +44,25 @@ namespace engine{
|
|||
namespace test {
|
||||
|
||||
|
||||
namespace { // Test fixture
|
||||
/**
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************//**
|
||||
* @test basic render node properties and behaviour.
|
||||
/******************************************************//**
|
||||
* @test basic render node structure and building blocks.
|
||||
* This test documents and verifies some fundamental
|
||||
* Render Node structures, looking at intricate technical
|
||||
* details, which are usually hidden below the NodeBuidler.
|
||||
* - #verify_NodeStructure is a demonstration example
|
||||
* to show fundamentals of node construction and
|
||||
* invocation, using a dummy implementation.
|
||||
* - the following cases cover extremely technical details
|
||||
* of the FeedManifold, which serves as junction point
|
||||
* between Render Node and external library functions.
|
||||
* - in a similar style, \ref NodeFeed_test covers the
|
||||
* various parameter- and data connections of Nodes
|
||||
* in a »clean-room« setting
|
||||
* - much more high-level is NodeLink_test, covering
|
||||
* the construction of a Render Node network
|
||||
* - NodeBuilder_test focuses on aspects of node
|
||||
* generation, as packaged into the NodeBuilder.
|
||||
*/
|
||||
class NodeBase_test : public Test
|
||||
{
|
||||
|
|
@ -62,12 +71,20 @@ namespace test {
|
|||
{
|
||||
seedRand();
|
||||
verify_TurnoutSystem();
|
||||
verify_NodeStructure();
|
||||
verify_FeedManifold();
|
||||
verify_FeedPrototype();
|
||||
UNIMPLEMENTED ("build a simple render node and then activate it");
|
||||
}
|
||||
|
||||
/** @test the TurnoutSystem as transient coordinator for node invocation
|
||||
|
||||
/** @test the TurnoutSystem as transient connection hub for node invocation
|
||||
* - for most invocations, just the nominal timeline time and an
|
||||
* arbitrary process indentification-key is placed into fixed
|
||||
* «slots« within the TurnoutSystem, from where these parameters
|
||||
* can be retrieved by actual processing functions;
|
||||
* - for some special cases however, additional storage blocks
|
||||
* can be chained up, to allow accessing arbitrary parameters
|
||||
* through the TurnoutSystem as front-end.
|
||||
*/
|
||||
void
|
||||
verify_TurnoutSystem()
|
||||
|
|
@ -82,14 +99,14 @@ namespace test {
|
|||
|
||||
|
||||
// Demonstrate extension-block to TurnoutSystem
|
||||
// Used to setup elaborate parameter-nodes.
|
||||
// Used to setup elaborate parameter-nodes...
|
||||
double someVal = defaultGen.uni(); // some param value, computed by »elaborate logic«
|
||||
auto spec = buildParamSpec()
|
||||
.addValSlot (someVal); // declare a parameter slot for an extension data block
|
||||
auto acc0 = spec.makeAccessor<0>(); // capture an accessor-functor for later use
|
||||
|
||||
{// Build and connect extension storage block
|
||||
auto dataBlock =
|
||||
auto dataBlock = // ...typically placed locally into a nested stack frame
|
||||
spec.makeBlockBuilder()
|
||||
.buildParamDataBlock(invoker);
|
||||
|
||||
|
|
@ -97,10 +114,98 @@ namespace test {
|
|||
CHECK (invoker.get(acc0) == someVal); // now able to retrieve data from extension block
|
||||
invoker.detachChainBlock (dataBlock);
|
||||
}
|
||||
// base block continues to be usable...
|
||||
CHECK (invoker.getNomTime() == nomTime);
|
||||
}
|
||||
|
||||
|
||||
/** @test the FeedManifold as adapter between Engine and processing library
|
||||
/** @test very basic structure of a Render Node.
|
||||
* - All render processing happens in \ref Port implementations
|
||||
* - here we use a dummy port, which just picks up a parameter
|
||||
* from the TurnoutSystem and writes it into the output buffer;
|
||||
* no further recursive call happens — so this is a source node.
|
||||
* - To _incorporate_ this Port implementation into a Render Node,
|
||||
* the _connectivity_ of the node network must be defined:
|
||||
* + each node has a list of »Leads« (predecessor nodes)
|
||||
* + and an array of port implementation (here just one port)
|
||||
* - note that data placement relies on lib::Several, which can
|
||||
* be configured to use a custom allocator to manage storage
|
||||
* - furthermore, a node gets some ID descriptors, which are used
|
||||
* to generate processing metadata (notably a hash key for caching)
|
||||
* - for the actual invocation, foremost we need a _buffer provider_
|
||||
* - and we need to supply the most basic parameters, like the
|
||||
* nominal timeline time and a proccess-Key. These will be
|
||||
* embedded into the TurnoutSystem, to be accessible throughout
|
||||
* the complete recursive node-pull invocation.
|
||||
* - This test verifies that the actual invocation indeed happened
|
||||
* and placed a random parameter-value into the output buffer.
|
||||
* @remark In reality, processing operations are delegated to a
|
||||
* media-processing library, which requires elaborate buffer handling
|
||||
* and typically entails recursive calls to predecessor nodes. This
|
||||
* intricate logic is handled by the typical Port implementation
|
||||
* known as \ref MediaWeavingPattern; notably the processing will
|
||||
* rely on a transient data structure called \ref FeedManifold, which
|
||||
* is verified in much more detail [below](\ref #verify_FeedManifold)
|
||||
*/
|
||||
void
|
||||
verify_NodeStructure()
|
||||
{
|
||||
class DummyProcessing
|
||||
: public Port
|
||||
{
|
||||
public:
|
||||
DummyProcessing (ProcID& id)
|
||||
: Port{id}
|
||||
{ }
|
||||
|
||||
/** Entrance point to the next recursive step of media processing. */
|
||||
BuffHandle
|
||||
weave (TurnoutSystem& turnoutSystem, OptionalBuff outBuffer) override
|
||||
{// do something deeply relevant, like feeding a dummy parameter...
|
||||
outBuffer->accessAs<long>() = turnoutSystem.getProcKey();
|
||||
return *outBuffer;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Prepare Connectivity for the Node
|
||||
auto leadNodes = makeSeveral<ProcNodeRef>(); // empty, no predecessor nodes
|
||||
auto nodePorts = makeSeveral<Port>() // build the port implementation object(s)
|
||||
.emplace<DummyProcessing> (ProcID::describe ("TestDummy","live(long)"));
|
||||
|
||||
// Build a Render Node
|
||||
ProcNode theNode{Connectivity{nodePorts.build()
|
||||
,leadNodes.build()
|
||||
}};
|
||||
|
||||
// Inspect Node metadata...
|
||||
CHECK (watch(theNode).isSrc());
|
||||
CHECK (watch(theNode).leads().size() == 0);
|
||||
CHECK (watch(theNode).ports().size() == 1);
|
||||
CHECK (watch(theNode).getNodeSpec () == "TestDummy-◎"_expect );
|
||||
CHECK (watch(theNode).getPortSpec(0) == "TestDummy.live(long)"_expect );
|
||||
|
||||
|
||||
// prepare for invoking the node....
|
||||
BufferProvider& provider = DiagnosticBufferProvider::build();
|
||||
BuffHandle buff = provider.lockBufferFor<long> (-55);
|
||||
CHECK (-55 == buff.accessAs<long>()); // allocated some data buffer for the result, with a marker-value
|
||||
|
||||
Time nomTime{Time::ZERO};
|
||||
ProcessKey key = 1 + rani(100); // here we »hide« some data value in the ProcessKey
|
||||
uint port{0}; // we will pull port-#0 of the node
|
||||
|
||||
// Trigger Node invocation...
|
||||
buff = theNode.pull (port, buff, nomTime, key);
|
||||
|
||||
CHECK (key == buff.accessAs<uint>()); // DummyProcessing port placed ProcessKey into the output-buffer
|
||||
buff.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** @test the FeedManifold as adapter between Engine and processing library...
|
||||
* - bind local λ with various admissible signatures
|
||||
* - construct specifically tailored FeedManifold types
|
||||
* - use the DiagnosticBufferProvider for test buffers
|
||||
|
|
|
|||
|
|
@ -91765,19 +91765,19 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1713821236750" ID="ID_1655113761" MODIFIED="1713823539175" TEXT="testgetriebener Aufbau">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1713821706444" ID="ID_1035135639" MODIFIED="1733525811029" TEXT="NodeBase_test">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node COLOR="#338800" CREATED="1713821706444" ID="ID_1035135639" MODIFIED="1739924540014" TEXT="NodeBase_test">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1733525753053" ID="ID_1646783261" MODIFIED="1733525804171" TEXT="Demonstriert die Grundelemente"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1719282799123" ID="ID_605400011" MODIFIED="1719282822229" TEXT="muß ich erst einmal größtenteils auskommentieren">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1713823489509" ID="ID_738439301" MODIFIED="1719282837986" TEXT="idealerweise nebenbei neu mit aufbauen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1713823489509" ID="ID_738439301" MODIFIED="1739924537767" TEXT="idealerweise nebenbei neu mit aufbauen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1733577482085" ID="ID_932666491" MODIFIED="1733577589840" TEXT="Turnout-System: Funktionsweise testen">
|
||||
<node COLOR="#338800" CREATED="1733577482085" ID="ID_932666491" MODIFIED="1739919405096" TEXT="Turnout-System: Funktionsweise testen">
|
||||
<linktarget COLOR="#406cd3" DESTINATION="ID_932666491" ENDARROW="Default" ENDINCLINATION="-128;9;" ID="Arrow_ID_983808840" SOURCE="ID_494911945" STARTARROW="None" STARTINCLINATION="-353;-26;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1733580248780" ID="ID_1698079544" MODIFIED="1736045190074" TEXT="mit nominal Time erzeugen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1733580248780" ID="ID_1698079544" MODIFIED="1739919407685" TEXT="mit nominal Time erzeugen">
|
||||
<arrowlink COLOR="#482eb7" DESTINATION="ID_855223653" ENDARROW="Default" ENDINCLINATION="-595;39;" ID="Arrow_ID_342943763" STARTARROW="None" STARTINCLINATION="-65;-160;"/>
|
||||
<linktarget COLOR="#4f70b3" DESTINATION="ID_1698079544" ENDARROW="Default" ENDINCLINATION="100;348;" ID="Arrow_ID_822714910" SOURCE="ID_1699433498" STARTARROW="None" STARTINCLINATION="356;24;"/>
|
||||
<node CREATED="1733580331065" ID="ID_1781432590" MODIFIED="1733584790502" TEXT="Testen mit Time-Grid!">
|
||||
|
|
@ -91830,11 +91830,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<arrowlink COLOR="#5c6a7a" DESTINATION="ID_1291306906" ENDARROW="Default" ENDINCLINATION="-289;17;" ID="Arrow_ID_1279473915" STARTARROW="None" STARTINCLINATION="177;10;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1739914036725" ID="ID_568175538" MODIFIED="1739914070848" TEXT="Zugriff auf die Basisparameter zeigen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1739914036725" ID="ID_568175538" MODIFIED="1739919401094" TEXT="Zugriff auf die Basisparameter zeigen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1739914046380" ID="ID_487791127" MODIFIED="1739914070848" TEXT="direkt zeigen daß ein Chain-Block an/abgekoppelt werden kann">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1739914046380" ID="ID_487791127" MODIFIED="1739919403060" TEXT="direkt zeigen daß ein Chain-Block an/abgekoppelt werden kann">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1734310118603" ID="ID_1954508996" MODIFIED="1734634792828" TEXT="Feed-Manifold: Eigenschaften demonstrieren">
|
||||
|
|
|
|||
Loading…
Reference in a new issue