2008-07-20 20:08:08 +02:00
|
|
|
|
/*
|
2024-12-28 23:16:55 +01:00
|
|
|
|
PARAM-WEAVING-PATTERN.hpp - Pattern to carry out special parameter computations
|
2010-12-17 23:28:49 +01:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
Copyright (C)
|
2024-12-13 03:28:28 +01:00
|
|
|
|
2024, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-17 23:28:49 +01:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
**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.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
|
2008-07-20 20:08:08 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
2024-12-13 03:28:28 +01:00
|
|
|
|
|
2024-12-28 21:41:08 +01:00
|
|
|
|
/** @file param-weaving-pattern.hpp
|
2024-12-28 23:16:55 +01:00
|
|
|
|
** Construction kit to establish a set of parameters pre-computed prior to invocation
|
|
|
|
|
|
** of nested nodes. This arrangement is also known as »Parameter Agent Node« (while actually
|
|
|
|
|
|
** it is a Weaving Patter residing within some Node's Port). The use-case is to provide a set
|
|
|
|
|
|
** of additional parameter values, beyond what can be derived directly by a parameter-functor
|
|
|
|
|
|
** based on the _absolute-nominal-Time_ of the invocation. The necessity for such a setup may
|
|
|
|
|
|
** arise when additional context or external state must be combined with the nominal time into
|
|
|
|
|
|
** a tuple of data values, which shall then be consumed by several follow-up evaluations further
|
|
|
|
|
|
** down into a recursive invocation tree _for one single render job._ The solution provided by
|
|
|
|
|
|
** the Parameter Agent Node relies on placing those additional data values into a tuple stored
|
|
|
|
|
|
** directly in the render invocation stack frame, prior to descending into further recursive
|
|
|
|
|
|
** Node evaluations. Notably, parameter-functors within the scope of this evaluation tree can
|
|
|
|
|
|
** then access these additional parameters through the TurnoutSystem of the overall invocation.
|
2024-12-21 23:58:56 +01:00
|
|
|
|
**
|
2024-12-28 23:16:55 +01:00
|
|
|
|
** @see node-builder.hpp
|
2024-12-21 23:58:56 +01:00
|
|
|
|
** @see weaving-pattern-builder.hpp
|
2024-12-28 23:16:55 +01:00
|
|
|
|
** @see NodeFeed_test::feedParamNode()
|
2024-12-21 23:58:56 +01:00
|
|
|
|
** @see \ref proc-node.hpp "Overview of Render Node structures"
|
2024-12-13 03:28:28 +01:00
|
|
|
|
**
|
2024-12-21 23:58:56 +01:00
|
|
|
|
** @warning WIP as of 12/2024 first complete integration round of the Render engine ////////////////////////////TICKET #1367
|
2024-12-13 03:28:28 +01:00
|
|
|
|
**
|
2008-07-20 20:08:08 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-12-28 21:41:08 +01:00
|
|
|
|
#ifndef STEAM_ENGINE_PARAM_WEAVING_PATTERN_H
|
|
|
|
|
|
#define STEAM_ENGINE_PARAM_WEAVING_PATTERN_H
|
2008-07-20 20:08:08 +02:00
|
|
|
|
|
2024-12-13 03:28:28 +01:00
|
|
|
|
#include "steam/common.hpp"
|
2024-12-14 03:50:10 +01:00
|
|
|
|
#include "steam/engine/turnout.hpp"
|
2024-12-13 03:28:28 +01:00
|
|
|
|
#include "steam/engine/turnout-system.hpp"
|
2024-12-28 23:16:55 +01:00
|
|
|
|
#include "steam/engine/feed-manifold.hpp" ////////////TODO wegdamit
|
2024-12-29 03:23:59 +01:00
|
|
|
|
#include "lib/meta/function.hpp"
|
|
|
|
|
|
#include "lib/meta/variadic-helper.hpp"
|
|
|
|
|
|
#include "lib/meta/tuple-helper.hpp"
|
2024-12-13 03:28:28 +01:00
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation
|
|
|
|
|
|
//#include "vault/gear/job.h"
|
|
|
|
|
|
//#include "steam/engine/exit-node.hpp"
|
|
|
|
|
|
//#include "lib/time/timevalue.hpp"
|
|
|
|
|
|
//#include "lib/linked-elements.hpp"
|
|
|
|
|
|
#include "lib/several.hpp"
|
|
|
|
|
|
//#include "lib/util-foreach.hpp"
|
|
|
|
|
|
//#include "lib/iter-adapter.hpp"
|
2024-12-21 23:58:56 +01:00
|
|
|
|
//#include "lib/meta/function.hpp"
|
2024-12-13 03:28:28 +01:00
|
|
|
|
//#include "lib/itertools.hpp"
|
|
|
|
|
|
//#include "lib/util.hpp" ////////OOO wegen manifoldSiz<FUN>()
|
2008-07-20 20:08:08 +02:00
|
|
|
|
|
2024-12-13 03:28:28 +01:00
|
|
|
|
//#include <stack>
|
2024-12-28 23:16:55 +01:00
|
|
|
|
#include <tuple>
|
|
|
|
|
|
#include <utility>
|
2008-07-20 20:08:08 +02:00
|
|
|
|
|
|
|
|
|
|
|
2018-11-15 23:55:13 +01:00
|
|
|
|
namespace steam {
|
2008-07-20 20:08:08 +02:00
|
|
|
|
namespace engine {
|
|
|
|
|
|
|
2024-12-28 23:16:55 +01:00
|
|
|
|
using std::move;
|
2024-12-29 03:23:59 +01:00
|
|
|
|
using std::forward;
|
|
|
|
|
|
using std::make_tuple;
|
2024-12-28 23:16:55 +01:00
|
|
|
|
using std::tuple;
|
|
|
|
|
|
using lib::Several;////TODO RLY?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<class ANK, typename...FUNZ>
|
|
|
|
|
|
struct ParamBuildSpec
|
|
|
|
|
|
{
|
|
|
|
|
|
using Functors = tuple<FUNZ...>;
|
|
|
|
|
|
|
2024-12-29 03:23:59 +01:00
|
|
|
|
using ResTypes = typename lib::meta::ElmTypes<Functors>::template Apply<lib::meta::_FunRet>;
|
|
|
|
|
|
using ParamTup = lib::meta::Tuple<ResTypes>;
|
|
|
|
|
|
|
2024-12-28 23:16:55 +01:00
|
|
|
|
Functors functors_;
|
|
|
|
|
|
|
|
|
|
|
|
ParamBuildSpec (Functors&& funz)
|
|
|
|
|
|
: functors_{move (funz)}
|
|
|
|
|
|
{ }
|
2024-12-29 03:23:59 +01:00
|
|
|
|
|
|
|
|
|
|
template<typename FUN>
|
|
|
|
|
|
auto
|
|
|
|
|
|
addSlot (FUN&& paramFun)
|
|
|
|
|
|
{
|
|
|
|
|
|
return ParamBuildSpec<ANK,FUNZ...,FUN>{std::tuple_cat (move(functors_)
|
|
|
|
|
|
,make_tuple (forward<FUN>(paramFun)))};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename PAR>
|
|
|
|
|
|
auto
|
|
|
|
|
|
addValSlot (PAR paramVal)
|
|
|
|
|
|
{
|
|
|
|
|
|
return addSlot ([paramVal](TurnoutSystem&){ return paramVal; });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-29 18:27:05 +01:00
|
|
|
|
/** @internal the _chain constructor type_ is a type rebinding meta function (nested struct),
|
|
|
|
|
|
* which extends the HeteroData chain given by \a ANK with the sequence of types derived from
|
|
|
|
|
|
* the result-values of all functors stored in the ParamBuildSpec, i.e. the resulting param tuple.
|
|
|
|
|
|
* @remark HeteroData defines a nested struct `Chain`, and with the help of `RebindVariadic`,
|
|
|
|
|
|
* the type sequence from the ParamTup can be used to instantiate this Chain context.
|
|
|
|
|
|
*/
|
|
|
|
|
|
using ChainCons = typename lib::meta::RebindVariadic<ANK::template Chain, ParamTup>::Type;
|
|
|
|
|
|
|
|
|
|
|
|
typename ChainCons::NewFrame
|
|
|
|
|
|
buildParamDataBlock (TurnoutSystem& turnoutSys)
|
|
|
|
|
|
{
|
2024-12-29 23:55:19 +01:00
|
|
|
|
return std::apply ([&](auto&&... paramFun)
|
|
|
|
|
|
{ // invoke parameter-functors and build NewFrame from results
|
|
|
|
|
|
return ChainCons::build (paramFun (turnoutSys) ...);
|
|
|
|
|
|
}
|
|
|
|
|
|
,functors_);
|
2024-12-29 18:27:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-12-29 03:23:59 +01:00
|
|
|
|
template<size_t slot>
|
|
|
|
|
|
class Slot
|
|
|
|
|
|
: util::MoveOnly
|
|
|
|
|
|
{
|
|
|
|
|
|
ParamBuildSpec& spec_;
|
|
|
|
|
|
|
|
|
|
|
|
Slot (ParamBuildSpec& spec)
|
|
|
|
|
|
: spec_{spec}
|
|
|
|
|
|
{ }
|
|
|
|
|
|
friend class ParamBuildSpec;
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
auto
|
|
|
|
|
|
invokeParamFun (TurnoutSystem& turnoutSys)
|
|
|
|
|
|
{
|
|
|
|
|
|
return std::get<slot> (spec_.functors_) (turnoutSys);
|
|
|
|
|
|
}
|
2024-12-29 18:27:05 +01:00
|
|
|
|
|
|
|
|
|
|
/** a getter functor able to work on the full extended HeteroData-Chain
|
|
|
|
|
|
* @remark the front-end of this chain resides in TurnoutSystem */
|
|
|
|
|
|
using Accessor = typename ChainCons::template Accessor<slot>;
|
|
|
|
|
|
static auto makeAccessor() { return Accessor{}; }
|
|
|
|
|
|
|
|
|
|
|
|
static auto&
|
|
|
|
|
|
getParamVal (TurnoutSystem& turnoutSys)
|
|
|
|
|
|
{
|
|
|
|
|
|
return turnoutSys.get (makeAccessor());
|
|
|
|
|
|
}
|
2024-12-29 03:23:59 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template<size_t idx>
|
|
|
|
|
|
Slot<idx>
|
|
|
|
|
|
slot()
|
|
|
|
|
|
{ return *this; }
|
2024-12-28 23:16:55 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
auto
|
|
|
|
|
|
buildParamSpec()
|
|
|
|
|
|
{
|
|
|
|
|
|
return ParamBuildSpec<TurnoutSystem::FrontBlock>{tuple<>{}};
|
|
|
|
|
|
}
|
2008-07-20 20:08:08 +02:00
|
|
|
|
|
2024-12-13 03:28:28 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
2024-12-28 23:16:55 +01:00
|
|
|
|
* Implementation for a _Weaving Pattern_ to conduct extended parameter evaluation.
|
2024-12-13 03:28:28 +01:00
|
|
|
|
*/
|
|
|
|
|
|
template<class INVO>
|
2024-12-28 21:41:08 +01:00
|
|
|
|
struct ParamWeavingPattern
|
2024-12-13 03:28:28 +01:00
|
|
|
|
: INVO
|
|
|
|
|
|
{
|
|
|
|
|
|
using Feed = typename INVO::Feed;
|
|
|
|
|
|
|
|
|
|
|
|
static_assert (_verify_usable_as_InvocationAdapter<Feed>());
|
|
|
|
|
|
|
|
|
|
|
|
Several<PortRef> leadPort;
|
|
|
|
|
|
Several<BuffDescr> outTypes;
|
|
|
|
|
|
|
|
|
|
|
|
uint resultSlot{0};
|
|
|
|
|
|
|
|
|
|
|
|
/** forwarding-ctor to provide the detailed input/output connections */
|
|
|
|
|
|
template<typename...ARGS>
|
2024-12-28 21:41:08 +01:00
|
|
|
|
ParamWeavingPattern (Several<PortRef>&& pr
|
2024-12-14 03:50:10 +01:00
|
|
|
|
,Several<BuffDescr>&& dr
|
|
|
|
|
|
,uint resultIdx
|
|
|
|
|
|
,ARGS&& ...args)
|
2024-12-13 03:28:28 +01:00
|
|
|
|
: INVO{forward<ARGS>(args)...}
|
|
|
|
|
|
, leadPort{move(pr)}
|
|
|
|
|
|
, outTypes{move(dr)}
|
|
|
|
|
|
, resultSlot{resultIdx}
|
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Feed
|
2024-12-01 05:24:12 +01:00
|
|
|
|
mount (TurnoutSystem& turnoutSys)
|
2024-12-13 03:28:28 +01:00
|
|
|
|
{
|
2024-12-01 05:24:12 +01:00
|
|
|
|
ENSURE (leadPort.size() <= INVO::FAN_I);
|
|
|
|
|
|
ENSURE (outTypes.size() <= INVO::FAN_O);
|
|
|
|
|
|
return INVO::buildFeed (turnoutSys);
|
2024-12-13 03:28:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
pull (Feed& feed, TurnoutSystem& turnoutSys)
|
|
|
|
|
|
{
|
2024-12-01 05:24:12 +01:00
|
|
|
|
if constexpr (Feed::hasInput())
|
|
|
|
|
|
for (uint i=0; i<leadPort.size(); ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
BuffHandle inputData = leadPort[i].get().weave (turnoutSys);
|
|
|
|
|
|
feed.inBuff.createAt(i, move(inputData));
|
|
|
|
|
|
}
|
2024-12-13 03:28:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
shed (Feed& feed, OptionalBuff outBuff)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (uint i=0; i<outTypes.size(); ++i)
|
2024-12-01 05:24:12 +01:00
|
|
|
|
{
|
|
|
|
|
|
BuffHandle resultData =
|
|
|
|
|
|
i == resultSlot and outBuff? *outBuff
|
|
|
|
|
|
: outTypes[i].lockBuffer();
|
|
|
|
|
|
feed.outBuff.createAt(i, move(resultData));
|
|
|
|
|
|
}
|
|
|
|
|
|
feed.connect();
|
2024-12-13 03:28:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
weft (Feed& feed)
|
|
|
|
|
|
{
|
|
|
|
|
|
feed.invoke(); // process data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BuffHandle
|
|
|
|
|
|
fix (Feed& feed)
|
|
|
|
|
|
{
|
2024-12-01 05:24:12 +01:00
|
|
|
|
if constexpr (Feed::hasInput())
|
|
|
|
|
|
for (uint i=0; i<leadPort.size(); ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
feed.inBuff[i].release();
|
|
|
|
|
|
}
|
2024-12-13 03:28:28 +01:00
|
|
|
|
for (uint i=0; i<outTypes.size(); ++i)
|
2024-12-01 05:24:12 +01:00
|
|
|
|
{
|
|
|
|
|
|
feed.outBuff[i].emit(); // state transition: data ready
|
|
|
|
|
|
if (i != resultSlot)
|
|
|
|
|
|
feed.outBuff[i].release();
|
|
|
|
|
|
}
|
|
|
|
|
|
ENSURE (resultSlot < INVO::FAN_O, "invalid result buffer configured.");
|
2024-12-13 03:28:28 +01:00
|
|
|
|
return feed.outBuff[resultSlot];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2008-07-20 20:08:08 +02:00
|
|
|
|
|
|
|
|
|
|
|
2024-12-13 03:28:28 +01:00
|
|
|
|
}}// namespace steam::engine
|
2024-12-28 21:41:08 +01:00
|
|
|
|
#endif /*STEAM_ENGINE_PARAM_WEAVING_PATTERN_H*/
|