Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
weaving-pattern-builder.hpp
Go to the documentation of this file.
1/*
2 WEAVING-PATTERN-BUILDER.hpp - build an invocation pattern for media calculations
3
4 Copyright (C)
5 2024, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
131#ifndef STEAM_ENGINE_WEAVING_PATTERN_BUILDER_H
132#define STEAM_ENGINE_WEAVING_PATTERN_BUILDER_H
133
134#include "lib/error.hpp"
143//#include "lib/test/test-helper.hpp" ////////////////////////////OOO TODO added for test
144#include "lib/format-string.hpp"
145#include "lib/iter-zip.hpp"
146#include "lib/util.hpp"
147
148#include <functional>
149#include <utility>
150#include <vector>
151#include <string>
152
153
154namespace steam {
155namespace engine {
156 namespace err = lumiera::error;
157
158 using StrView = std::string_view;
159 using std::forward;
160 using lib::Depend;
161 using lib::izip;
162 using util::_Fmt;
163 using util::max;
164
165
166
167 template<class POL, class I, class E=I>
169
170 template<uint siz>
171 using SizMark = std::integral_constant<uint,siz>;
172
173
174
184 template<class PAR, class BUILD, uint siz>
186 : PAR
187 {
189
190 uint size() { return 1 + PAR::size(); }
191
192 template<class DAB>
193 void
194 collectEntries (DAB& dataBuilder, uint cntElm =0, uint maxSiz =0)
195 {
196 PAR::collectEntries (dataBuilder, cntElm+1, max (siz,maxSiz));
197 buildEntry (dataBuilder);
198 }
199
200
201 PatternData(PAR&& predecessor, BUILD&& entryBuilder)
202 : PAR{move (predecessor)}
203 , buildEntry{move (entryBuilder)}
204 { }
205 };
206
212 {
213 uint size() { return 0; }
214
215 template<class DAB>
216 void
217 collectEntries (DAB& dataBuilder, uint cntElm, uint maxSiz)
218 {
219 dataBuilder.reserve (cntElm, maxSiz);
220 }
221 };
222
223
224
225
226
227
245 template<class POL, class PROT>
248 {
251 static constexpr SizMark<sizeof(TurnoutWeaving)> sizMark{};
252 static constexpr uint FAN_I = PROT::FAN_I;
253 static constexpr uint FAN_O = PROT::FAN_O;
254
255 using TypeMarker = std::function<BuffDescr(BufferProvider&)>;
258
260 std::vector<TypeMarker> buffTypes;
261 std::vector<ProviderRef> providers;
262
264
266
270
271 template<typename...INIT>
272 WeavingBuilder (PROT&& prototype, StrView nodeSymb, StrView portSpec, INIT&& ...alloInit)
273 : leadPorts{forward<INIT> (alloInit)...}
275 , nodeSymb_{nodeSymb}
276 , portSpec_{portSpec}
277 , prototype_{move(prototype)}
278 { }
279
281 template<class PREV>
282 WeavingBuilder (WeavingBuilder<POL,PREV>&& prevBuilder, PROT&& adaptedPrototype)
283 : leadPorts {move (prevBuilder.leadPorts)}
284 , buffTypes {move (prevBuilder.buffTypes)}
285 , providers {move (prevBuilder.providers)}
286 , resultSlot{move (prevBuilder.resultSlot)}
287 , nodeSymb_ {move (prevBuilder.nodeSymb_)}
288 , portSpec_ {move (prevBuilder.portSpec_)}
289 , prototype_{move (adaptedPrototype)}
290 { }
291
292
294 template<class PFX>
295 using AdaptedPrototype = PROT::template Adapted<PFX>;
296 template<class PFX>
298
303 template<class PFX>
304 auto
305 adaptParam (PFX paramFunctor)
306 {
307 static_assert (PROT::template isSuitableParamFun<PFX>()
308 ,"suitable as param-functor for given processing-functor");
309 //
310 using AdaptedWeavingBuilder = Adapted<PFX>;
311 //
312 return AdaptedWeavingBuilder{move(*this)
313 ,prototype_.moveAdaptedParam (move (paramFunctor))
314 };
315 }
316
317
319 template<class DEC>
320 using DecoratedPrototype = PROT::template Decorated<DEC>;
321 template<class DEC>
323
327 template<class DEC>
328 auto
329 adaptProcFunParam (DEC decorator)
330 {
331 static_assert (PROT::template isSuitableParamAdaptor<DEC>()
332 ,"suitable to adapt the processing-functor's param argument");
333 //
334 using AdaptedWeavingBuilder = Decorated<DEC>;
335 //
336 return AdaptedWeavingBuilder{move(*this)
337 ,prototype_.moveTransformedParam (move (decorator))
338 };
339 }
340
343 {
344 if (leadPorts.size() >= FAN_I)
345 throw err::Logic{_Fmt{"Builder: attempt to add further input, "
346 "but all %d »input slots« of the processing function are already connected."}
347 % FAN_I
348 };
349 PortRef portRef{lead.getPort (portNr)};
350 leadPorts.append (portRef);
351 return move(*this);
352 }
353
354
357 {
358 REQUIRE (leadPorts.size() <= FAN_I);
359 uint cnt = FAN_I - leadPorts.size();
360 if (FAN_I > knownLeads.size())
361 throw err::Logic{_Fmt{"Builder: attempt to auto-connect %d further »input slots«, "
362 "but this ProcNode has only %d predecessor nodes, while the "
363 "given processing function expects %d inputs."}
364 % cnt % knownLeads.size() % FAN_I
365 };
366 while (cnt--)
367 attachToLeadPort (knownLeads[leadPorts.size()], defaultPort);
368 return move(*this);
369 }
370
373 {
374 this->resultSlot = idx;
375 return move(*this);
376 }
377
378
379 auto
381 {
382 // discard excess storage prior to allocating the output types sequence
383 leadPorts.shrinkFit();
384
386 REQUIRE (providers.size() == buffTypes.size());
388 .reserve (buffTypes.size());
389
390 for (auto& [i,typeConstructor] : izip(buffTypes))
391 outTypes.append (
392 typeConstructor (providers[i]));
393
394 ENSURE (leadPorts.size() == FAN_I);
395 ENSURE (outTypes.size() == FAN_O);
396
397 using PortDataBuilder = DataBuilder<POL, Port>;
398 // provide a free-standing functor to build a suitable Port impl (≙Turnout)
399 return [leads = move(leadPorts.build())
400 ,types = move(outTypes.build())
401 ,prototype = move(prototype_)
402 ,resultIdx = resultSlot
404 ]
405 (PortDataBuilder& portData) mutable -> void
406 {
407 portData.template emplace<TurnoutWeaving> (procID
408 ,move(leads)
409 ,move(types)
410 ,resultIdx
411 ,move(prototype)
412 );
413 };
414 }
415
416
417
418 private: /* ====== WeavingBuilder implementation details ====== */
419 void
421 {
422 for (uint i=providers.size(); i < maxSlots; ++i)
423 providers.emplace_back (ctx().mem);
424 }
425
434 template<typename BU>
436 {
444 {
445 return [](BufferProvider& provider)
446 { return provider.getDescriptor<BU>(); };
447 }
448 };
449
450 using OutTypesDescriptors = PROT::template OutTypesApply<BufferDescriptor>;
452
455
465 static auto
467 {
468 std::vector<TypeMarker> defaultBufferTypes;
469 defaultBufferTypes.reserve (std::tuple_size_v<OutDescriptorTup>);
471 ,[&](auto& desc)
472 {
473 defaultBufferTypes.emplace_back(
474 desc.makeBufferDescriptor());
475 });
476 return defaultBufferTypes;
477 }
478 };
479
480
481}}// namespace steam::engine
482#endif /*STEAM_ENGINE_WEAVING_PATTERN_BUILDER_H*/
Abstraction to represent buffer management and lifecycle within the render engine.
Extension to allow placing objects right into the buffers, taking ownership.
Access point to singletons and other kinds of dependencies designated by type.
Definition depend.hpp:281
Builder to create and populate a lib::Several<I>.
Policy & policyConnect()
expose policy to configure other ServeralBuilder
An opaque descriptor to identify the type and further properties of a data buffer.
Interface: a facility providing and managing working buffers for media calculations.
static ProcID & describe(StrView nodeSymb, StrView portSpec, ProcAttrib extAttrib=ProcAttrib{})
build and register a processing ID descriptor
Key abstraction of the Render Engine: A Data processing Node.
Port & getPort(uint portIdx)
Processing structure to activate a Render Node and produce result data.
Definition turnout.hpp:117
Types marked with this mix-in may be moved but not copied.
Definition nocopy.hpp:50
A front-end for using printf-style formatting.
Dependency context to hold global parameters and services for the render engine.
Lumiera error handling (C++ interface).
Front-end for printf-style string template interpolation.
unsigned int uint
Definition integral.hpp:29
Iterator builder to combine several iterables into a tuple sequence.
Construction set to assemble and operate a data processing scheme within a Render Node.
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
constexpr void forEach(TUP &&tuple, FUN fun)
Tuple iteration: perform some arbitrary operation on each element of a tuple.
auto izip(ITS &&...iters)
tuple-combining iterator prefixed by index sequence
Definition iter-zip.hpp:152
LumieraError< LERR_(LOGIC)> Logic
Definition error.hpp:207
lib::SeveralBuilder< I, E, POL::template Policy > DataBuilder
A builder to collect working data.
std::integral_constant< uint, siz > SizMark
std::reference_wrapper< Port > PortRef
std::string_view StrView
Definition proc-id.hpp:82
Steam-Layer implementation namespace root.
auto max(IT &&elms)
Metadata interface to generate symbolic and hash ID tags for media processing steps.
Builder to create and populate instances of the lib::Several container.
Standard implementation for a Weaving Pattern to connect the input and output data feeds (buffers) in...
Data recursion end: prime the port data storage by reserving appropriate storage to hold all known Tu...
void collectEntries(DAB &dataBuilder, uint cntElm, uint maxSiz)
Recursive functional data structure to collect weaving pattern data and finally to emplace a Turnout ...
void collectEntries(DAB &dataBuilder, uint cntElm=0, uint maxSiz=0)
PatternData(PAR &&predecessor, BUILD &&entryBuilder)
TypeMarker makeBufferDescriptor() const
Setup the constructor function for the default BufferDescriptors.
A low-level Builder to prepare and adapt for a specific node invocation.
lib::meta::Tuple< OutTypesDescriptors > OutDescriptorTup
void maybeFillDefaultProviders(size_t maxSlots)
auto adaptProcFunParam(DEC decorator)
Adapt parameter handling by prepending the given transformer function to supply the parameter argumen...
WeavingBuilder && selectResultSlot(uint idx)
static constexpr OutDescriptorTup outDescriptors
A tuple of BufferDescriptor instances for all output buffer types.
PROT::template OutTypesApply< BufferDescriptor > OutTypesDescriptors
WeavingBuilder(WeavingBuilder< POL, PREV > &&prevBuilder, PROT &&adaptedPrototype)
cross-ctor to switch to another prototype
WeavingBuilder< POL, AdaptedPrototype< PFX > > Adapted
DataBuilder< POL, PortRef > leadPorts
std::reference_wrapper< BufferProvider > ProviderRef
WeavingBuilder(PROT &&prototype, StrView nodeSymb, StrView portSpec, INIT &&...alloInit)
Turnout< WeavingPattern > TurnoutWeaving
std::function< BuffDescr(BufferProvider &)> TypeMarker
WeavingBuilder< POL, DecoratedPrototype< DEC > > Decorated
WeavingBuilder && attachToLeadPort(ProcNode &lead, uint portNr)
WeavingBuilder && connectRemainingInputs(DataBuilder< POL, ProcNodeRef > &knownLeads, uint defaultPort)
static constexpr SizMark< sizeof(TurnoutWeaving)> sizMark
auto adaptParam(PFX paramFunctor)
Adapt a parameter-functor into the Feed Prototype, so that it is invoked whenever a new FeedManifold ...
lib::meta::TupleClosureBuilder< typename PROT::Param > ParamClosure
PROT::template Decorated< DEC > DecoratedPrototype
type builder for FeedPrototype with remoulded parameter input
MediaWeavingPattern< PROT > WeavingPattern
PROT::template Adapted< PFX > AdaptedPrototype
type builder for FeedPrototype adapted to another parameter-fun
Partial binding for construction of tuple-like records.
Metaprogramming with tuples-of-types and the std::tuple record.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...