...which aims at building up increasingly more complex Node Graphs, to validate that all clauses are defined and connected properly. Reconsidering the testing plan: initially especially this test was aimed primarily at driving me through the construction of the Node builder and connection scheme. Surprisingly enough, already the first test case basically forced the complete construction, by setting me on tangential routes, notably the **parameter handling**. Now I'm returning to this test plan with an already finished construction, and thus it can be straightened just to give enough coverage to validate the correctness of this construction...
169 lines
6 KiB
C++
169 lines
6 KiB
C++
/*
|
||
NodeLink(Test) - render node connectivity and collaboration
|
||
|
||
Copyright (C)
|
||
2024, Hermann Vosseler <Ichthyostega@web.de>
|
||
|
||
**Lumiera** 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. See the file COPYING for further details.
|
||
|
||
* *****************************************************************/
|
||
|
||
/** @file node-link-test.cpp
|
||
** The \ref NodeLink_test covers the essence of connected render nodes.
|
||
*/
|
||
|
||
|
||
#include "lib/test/run.hpp"
|
||
#include "steam/engine/proc-node.hpp"
|
||
#include "steam/engine/node-builder.hpp"
|
||
#include "steam/engine/test-rand-ontology.hpp" ///////////TODO
|
||
#include "lib/test/diagnostic-output.hpp"/////////////////TODO
|
||
#include "lib/util.hpp"
|
||
|
||
|
||
using util::isnil;
|
||
//using std::string;
|
||
using util::isSameObject;
|
||
|
||
|
||
namespace steam {
|
||
namespace engine{
|
||
namespace test {
|
||
|
||
|
||
|
||
|
||
/***************************************************************//**
|
||
* @test demonstrate and document how [render nodes](\ref proc-node.hpp)
|
||
* are connected into a processing network, allowing to _invoke_
|
||
* a \ref Port on a node to pull-generate a render result.
|
||
* - the foundation layer is formed by the nodes as linked into a network
|
||
* - starting from any Port, a TurnoutSystem can be established
|
||
* - which in turn allows _turn out_ a render result from this port.
|
||
*/
|
||
class NodeLink_test : public Test
|
||
{
|
||
virtual void
|
||
run (Arg)
|
||
{
|
||
seedRand();
|
||
|
||
build_simple_node();
|
||
build_connected_nodes();
|
||
trigger_node_port_invocation();
|
||
}
|
||
|
||
|
||
|
||
|
||
/** @test Build Node Port for simple function
|
||
* and verify observable properties of a Render Node
|
||
* @todo 7/24 ✔ define ⟶ ✔ implement
|
||
*/
|
||
void
|
||
build_simple_node()
|
||
{
|
||
// use some dummy specs and a dummy operation....
|
||
StrView nodeID{ont::DUMMY_NODE_ID};
|
||
StrView procID{ont::DUMMY_PROC_ID};
|
||
CHECK (nodeID == "Test:dummy"_expect);
|
||
CHECK (procID == "op(int)"_expect);
|
||
|
||
// use the NodeBuilder to construct a simple source-node connectivity
|
||
auto con = prepareNode(nodeID)
|
||
.preparePort()
|
||
.invoke(procID, ont::dummyOp)
|
||
.completePort()
|
||
.build();
|
||
CHECK (isnil (con.leads));
|
||
CHECK (1 == con.ports.size());
|
||
|
||
// can build a ProcNode with this connectivity
|
||
ProcNode n1{move(con)};
|
||
CHECK (watch(n1).isValid());
|
||
CHECK (watch(n1).leads().empty());
|
||
CHECK (watch(n1).ports().size() == 1);
|
||
|
||
// can generate a symbolic spec to describe the Port's processing functionality...
|
||
CHECK (watch(n1).getPortSpec(0) == "Test:dummy.op(int)"_expect);
|
||
CHECK (watch(n1).getPortSpec(1) == "↯"_expect);
|
||
|
||
// such a symbolic spec is actually generated by a deduplicated metadata descriptor
|
||
auto& meta1 = ProcID::describe("N1","(arg)");
|
||
auto& meta1b = ProcID::describe("N1","(arg)");
|
||
auto& meta2 = ProcID::describe("N2","(arg)");
|
||
auto& meta3 = ProcID::describe("N1","uga()");
|
||
CHECK ( isSameObject (meta1,meta1b));
|
||
CHECK (not isSameObject (meta1,meta2));
|
||
CHECK (not isSameObject (meta1,meta3));
|
||
CHECK (hash_value(meta1) == hash_value(meta1b));
|
||
CHECK (hash_value(meta1) != hash_value(meta2));
|
||
CHECK (hash_value(meta1) != hash_value(meta3));
|
||
|
||
CHECK (meta1.genProcSpec() == "N1(arg)"_expect);
|
||
CHECK (meta2.genProcSpec() == "N2(arg)"_expect);
|
||
CHECK (meta3.genProcSpec() == "N1.uga()"_expect);
|
||
|
||
// re-generate the descriptor for the source node (n1)
|
||
auto& metaN1 = ProcID::describe("Test:dummy","op(int)");
|
||
CHECK (metaN1.genProcSpec() == "Test:dummy.op(int)"_expect);
|
||
CHECK (metaN1.genProcName() == "Test:dummy.op"_expect);
|
||
CHECK (metaN1.genNodeName() == "Test:dummy"_expect);
|
||
CHECK (metaN1.genNodeSpec(con.leads) == "Test:dummy-◎"_expect);
|
||
}
|
||
|
||
|
||
/** @test TODO Build more elaborate Render Nodes linked into a connectivity network
|
||
* @todo WIP 1/25 🔁 define ⟶ implement
|
||
*/
|
||
void
|
||
build_connected_nodes()
|
||
{
|
||
auto srcOp = [](int param, int* res){ *res = param; };
|
||
|
||
// A Node with two (source) ports
|
||
ProcNode n1{prepareNode("n1")
|
||
.preparePort()
|
||
.invoke("a(int)", srcOp)
|
||
.setParam(5)
|
||
.completePort()
|
||
.preparePort()
|
||
.invoke("b(int)", srcOp)
|
||
.setParam(23)
|
||
.completePort()
|
||
.build()};
|
||
|
||
auto add1Op = [](int* src, int* res){ *res = 1 + *src; };
|
||
ProcNode n2{prepareNode("n2")
|
||
.preparePort()
|
||
.invoke("+1(int)(int)", add1Op)
|
||
.connectLead(n1)
|
||
.completePort()
|
||
.preparePort()
|
||
.invoke("+1(int)(int)", add1Op)
|
||
.connectLead(n1)
|
||
.completePort()
|
||
.build()};
|
||
}
|
||
|
||
|
||
/** @test TODO Invoke some render nodes as linked together
|
||
* @todo WIP 12/24 🔁 define ⟶ implement
|
||
*/
|
||
void
|
||
trigger_node_port_invocation()
|
||
{
|
||
UNIMPLEMENTED ("operate some render nodes as linked together");
|
||
}
|
||
};
|
||
|
||
|
||
/** Register this test class... */
|
||
LAUNCHER (NodeLink_test, "unit node");
|
||
|
||
|
||
|
||
}}} // namespace steam::engine::test
|