Lumiera  0.pre.03
»edit your freedom«
node-builder.hpp
Go to the documentation of this file.
1 /*
2  NODE-BUILDER.hpp - Setup of render nodes connectivity
3 
4  Copyright (C)
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6  2024, Hermann Vosseler <Ichthyostega@web.de>
7 
8   **Lumiera** is free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License as published by the
10   Free Software Foundation; either version 2 of the License, or (at your
11   option) any later version. See the file COPYING for further details.
12 
13 */
14 
82 #ifndef ENGINE_NODE_BUILDER_H
83 #define ENGINE_NODE_BUILDER_H
84 
85 
86 #include "lib/error.hpp"
87 //#include "lib/symbol.hpp"//////////////////////////////TODO RLY?
88 #include "lib/nocopy.hpp"
91 #include "steam/engine/turnout.hpp"
92 #include "lib/several-builder.hpp"
93 #include "lib/format-string.hpp"
94 #include "lib/index-iter.hpp"
95 #include "lib/test/test-helper.hpp"
96 
97 #include <utility>
98 #include <vector>
99 
100 
101 namespace steam {
102 namespace engine {
103  namespace err = lumiera::error;
104 
105 // using lib::Literal;
106  using util::_Fmt;
107  using std::forward;
108  using std::move;
109 
110 
111  namespace { // default policy configuration to use heap allocator
112 
114  {
115  template<class I, class E=I>
117  };
118  //
119  }//(End) policy
120 
121 
122 
128  template<class POL, class I, class E=I>
130 
131 
132 
133  template<class POL, class DAT>
134  class NodeBuilder;
135 
136  template<class POL, class DAT>
138 
139 
140 
141 
142  template<class POL, class DAT = PatternDataAnchor>
143  class NodeBuilder
145  {
148 
149  protected:
150  StrView symbol_;
151  LeadRefs leads_;
152  DAT patternData_;
153 
154  public:
155  template<typename...INIT>
156  NodeBuilder (StrView nodeSymbol, INIT&& ...alloInit)
157  : symbol_{nodeSymbol}
158  , leads_{forward<INIT> (alloInit)...}
159  { }
160 
161  template<class BUILD, uint siz, class D0>
162  NodeBuilder (NodeBuilder<POL,D0>&& pred, SizMark<siz>, BUILD&& entryBuilder)
163  : symbol_{pred.symbol_}
164  , leads_{move (pred.leads_)}
165  , patternData_{move (pred.patternData_), forward<BUILD> (entryBuilder)}
166  { }
167 
168  template<class P, class D0>
169  friend class NodeBuilder;
170 
171 
173  addLead (ProcNode const& lead)
174  {
175  leads_.append (lead);
176  return move(*this);
177  }
178 
179 
181  PortBuilderRoot<POL,DAT> preparePort();
182 
183 
199  template<template<typename> class ALO =std::void_t, typename...INIT>
200  auto
201  withAllocator (INIT&& ...alloInit)
202  {
203  using AllocatorPolicy = lib::allo::SetupSeveral<ALO,INIT...>;
204  return NodeBuilder<AllocatorPolicy>{symbol_, forward<INIT>(alloInit)...};
205  }
206 
207 
208  /************************************************************/
213  {
214  PortData ports;
215  patternData_.collectEntries(ports);
216  return Connectivity{ports.build()
217  ,leads_.build()
218  };
219  }
220  };
221 
223  template<class POL, class D0, uint siz, class BUILD>
225 
226 
227 
228 
229  template<class POL, class DAT>
230  class PortBuilderRoot
231  : protected NodeBuilder<POL,DAT>
232  {
233  public:
235  completePort()
236  {
237  static_assert(not sizeof(POL),
238  "can not build a port without specifying a processing function");
239  }
240 
243  template<typename FUN>
244  auto invoke (StrView portSpec, FUN fun);
245 
247  template<class ADA, typename...ARGS>
248  auto adaptInvocation(ARGS&& ...args);
249 
250 
251  private:
253  : NodeBuilder<POL>{move(anchor)}
254  { }
255 
257  };
258 
266  template<class POL, class DAT>
269  {
270  return PortBuilderRoot<POL,DAT>{move(*this)};
271  }
272 
273 
274 
275  template<class POL, class DAT, class WAB>
277  : public PortBuilderRoot<POL,DAT>
278  {
280 
281  WAB weavingBuilder_;
282  uint defaultPort_;
283 
284  public:
285 
286  template<class ILA, typename...ARGS>
288  createBuffers (ARGS&& ...args)
289  {
290  UNIMPLEMENTED ("define builder for all buffers to use");
291  return move(*this);
292  }
293 
297  asResultSlot (uint r)
298  {
299  weavingBuilder_.selectResultSlot(r);
300  return move(*this);
301  }
302 
305  connectLead (uint idx)
306  {
307  return connectLeadPort (idx, this->defaultPort_);
308  }
309 
312  conectLead (ProcNode& leadNode)
313  {
314  return connectLeadPort (leadNode, this->defaultPort_);
315  }
316 
319  connectLeadPort (uint idx, uint port)
320  {
321  if (idx >= _Par::leads_.size())
322  throw err::Logic{_Fmt{"Builder refers to lead-node #%d, yet only %d are currently defined."}
323  % idx % _Par::leads_.size()
324  ,LERR_(INDEX_BOUNDS)
325  };
326  weavingBuilder_.attachToLeadPort (_Par::leads_[idx], port);
327  return move(*this);
328  }
329 
332  connectLeadPort (ProcNode& leadNode, uint port)
333  {
334  uint knownEntry{0};
335  for (auto& lead : lib::IndexIter{_Par::leads_})
336  if (util::isSameObject (leadNode, lead))
337  break;
338  else
339  ++knownEntry;
340  if (knownEntry == _Par::leads_.size())
341  _Par::addLead (leadNode);
342 
343  ENSURE (knownEntry < _Par::leads_.size());
344  weavingBuilder_.attachToLeadPort (knownEntry, port);
345  return move(*this);
346  }
347 
350  useLeadPort (uint defaultPort)
351  {
352  this->defaultPort_ = defaultPort;
353  return move(*this);
354  }
355 
356 
357  /*************************************************************/
360  auto
362  {
363  weavingBuilder_.connectRemainingInputs (_Par::leads_, this->defaultPort_);
364  weavingBuilder_.fillRemainingBufferTypes();
365  return NodeBuilder{static_cast<NodeBuilder<POL,DAT>&&> (*this) // slice away PortBulder subclass data
366  ,weavingBuilder_.sizMark
367  ,weavingBuilder_.build()};
368  } // chain to builder with extended patternData
369 
370  private:
371  template<typename FUN>
372  PortBuilder(_Par&& base, FUN&& fun, StrView portSpec)
373  : _Par{move(base)}
374  , weavingBuilder_{forward<FUN> (fun), _Par::symbol_, portSpec, _Par::leads_.policyConnect()}
375  , defaultPort_{_Par::patternData_.size()}
376  { }
377 
378  friend class PortBuilderRoot<POL,DAT>;
379  };
380 
381 
403  template<class POL, class DAT>
404  template<typename FUN>
405  auto
406  PortBuilderRoot<POL,DAT>::invoke (StrView portSpec, FUN fun)
407  {
408  using WeavingBuilder_FUN = WeavingBuilder<POL, manifoldSiz<FUN>(), FUN>;
409  return PortBuilder<POL,DAT, WeavingBuilder_FUN>{move(*this), move(fun), portSpec};
410  }
411 /*
412  template<class POL>
413  template<class ADA, typename...ARGS>
414  auto
415  PortBuilderRoot<POL>::adaptInvocation(ARGS&& ...args)
416  {
417  return move(*this);
418  }
419  */
420 
427  inline auto
428  prepareNode (StrView nodeSymbol)
429  {
430  return NodeBuilder<UseHeapAlloc>{nodeSymbol};
431  }
432 
433 
434 
435 
436 
439  {
440  public:
441 
442  void
443  requiredSources ()
444  {
445  UNIMPLEMENTED ("enumerate all source feeds required");
446 // return move(*this);
447  }
448 
449  void
450  retrieve (void* streamType)
451  {
452  UNIMPLEMENTED ("recursively define a predecessor feed");
453 // return move(*this);
454  }
455 
456  /****************************************************/
459  void
461  {
462  UNIMPLEMENTED("Level-3 build-walk");
463  }
464  };
465 
466 
469  {
470  public:
471 
472  void
473  from (void* procAsset)
474  {
475  UNIMPLEMENTED ("recursively enter definition of processor node to produce this feed link");
476 // return move(*this);
477  }
478  };
479 
480 
481 
485  inline auto
486  retrieve(void* streamType)
487  {
488  UNIMPLEMENTED("start a connectivity definition at Level-3");
489  return LinkBuilder{};
490  }
491 
492 
493 }} // namespace steam::engine
494 #endif /*ENGINE_NODE_BUILDER_H*/
PortBuilder conectLead(ProcNode &leadNode)
connect the next input slot to either existing or new lead-node"
auto invoke(StrView portSpec, FUN fun)
setup standard wiring to adapt the given processing function.
Several< I > build()
Terminal Builder: complete and lock the collection contents.
void build()
Terminal: trigger the Level-3 build walk to produce a ProcNode network.
PortBuilder connectLead(uint idx)
connect the next input slot to existing lead-node given by index
auto retrieve(void *streamType)
Entrance point for defining data flows and processing steps.
Types marked with this mix-in may be moved but not copied.
Definition: nocopy.hpp:49
A low-level Builder to prepare and adapt for a specific node invocation.
Front-end for printf-style string template interpolation.
Extension point: how to configure the SeveralBuilder to use an allocator ALO, initialised by ARGS...
Steam-Layer implementation namespace root.
A front-end for using printf-style formatting.
Fixed standard setup used in each Port of the Render Node to generate data.
PortBuilder connectLeadPort(ProcNode &leadNode, uint port)
connect next input to existing or new lead-node, with given port-number
PortBuilder useLeadPort(uint defaultPort)
use given port-index as default for all following connections
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Iterator-style access handle to a referred container with subscript index.
Construction kit to establish an invocation scheme for media calculations.
Subscript-index based access to a container, packaged as iterator.
Definition: index-iter.hpp:112
Builder to create and populate a lib::Several<I>.
Interface to the processing nodes and the render nodes network.
auto completePort()
Terminal: complete the Port wiring and return to the node level.
A collection of frequently used helper functions to support unit testing.
Connectivity build()
Terminal: complete the ProcNode Connectivity defined thus far.
auto prepareNode(StrView nodeSymbol)
Entrance point for building actual Render Node Connectivity (Level-2)
Lumiera error handling (C++ interface).
PortBuilderRoot< POL, DAT > preparePort()
recursively enter detailed setup of a single processing port
Interface: Description of the input and output ports, processing function and predecessor nodes for a...
Key abstraction of the Render Engine: A Data processing Node.
Definition: proc-node.hpp:154
auto withAllocator(INIT &&...alloInit)
cross-builder function to specify usage of a dedicated node allocator
Policy Mix-In used to adapt to the ElementFactory and Allocator.
SeveralBuilder && append(VAL &&val, VALS &&...vals)
append copies of one or several arbitrary elements
NodeBuilder(NodeBuilder< POL, D0 > &&, SizMark< siz >, BUILD &&) -> NodeBuilder< POL, PatternData< D0, BUILD, siz >>
Deduction Guide: help the compiler with deducing follow-up NodeBuilder parameters.
Builder to create and populate instances of the lib::Several container.
PortBuilder asResultSlot(uint r)
define the output slot to use as result
PortBuilder connectLeadPort(uint idx, uint port)
connect next input to lead-node, using a specific port-number