diff --git a/src/lib/iter-explorer.hpp b/src/lib/iter-explorer.hpp index f89a9e992..7c9868f4f 100644 --- a/src/lib/iter-explorer.hpp +++ b/src/lib/iter-explorer.hpp @@ -175,9 +175,11 @@ namespace lib { typedef typename SRC::reference reference; typedef typename SRC::pointer pointer; - /** Metafunction: the resulting type when binding a functor of type FUN */ + /** Metafunction: the resulting type when binding ("flat mapping") + * a functor of type FUN. Basically the result of binding a function + * is again an IterExplorer (with an "expanded" state core type) */ template - struct Binding + struct FlatMapped { typedef IterExplorer<_COM_, _COM_> Type; }; @@ -210,11 +212,11 @@ namespace lib { * of the result iterator. */ template - IterExplorer<_COM_, _COM_> + typename FlatMapped::Type operator >>= (FUN explorer) { typedef _COM_ Combinator; // instantiation of the combinator strategy - typedef IterExplorer ResultsIter; // result IterExplorer using that instance as state core + typedef typename FlatMapped::Type ResultsIter; // result IterExplorer using that instance as state core return ResultsIter ( Combinator (explorer // build a new iteration state core diff --git a/src/lib/meta/function.hpp b/src/lib/meta/function.hpp index 7bb4ecffa..87f7379df 100644 --- a/src/lib/meta/function.hpp +++ b/src/lib/meta/function.hpp @@ -230,6 +230,13 @@ namespace meta{ typedef typename FunctionSignature >::Ret Ret; typedef typename FunctionSignature >::Args Args; }; + /** Specialisation when using a function reference */ + template + struct _Fun + { + typedef typename FunctionSignature >::Ret Ret; + typedef typename FunctionSignature >::Args Args; + }; /** Specialisation for passing a functor */ template struct _Fun > diff --git a/src/proc/engine/job-planning.hpp b/src/proc/engine/job-planning.hpp index dbdcc8c52..87ea861c7 100644 --- a/src/proc/engine/job-planning.hpp +++ b/src/proc/engine/job-planning.hpp @@ -28,6 +28,7 @@ //#include "proc/state.hpp" #include "proc/engine/job.hpp" #include "proc/engine/job-ticket.hpp" +#include "proc/engine/time-anchor.hpp" //#include "proc/engine/frame-coord.hpp" //#include "lib/time/timevalue.hpp" //#include "lib/time/timequant.hpp" @@ -190,7 +191,7 @@ namespace engine { return this->wrapping(*prerequisites); // explanation: PlanningState represents a sequence of successive planning points. // actually this is implemented by switching an embedded JobPlanning element - // through a sequence of states. Thus the initial state of the investigation + // through a sequence of states. Thus the initial state of an investigation // (which is a JobPlanning) can stand-in for the sequence of prerequisites } @@ -210,10 +211,10 @@ namespace engine { inline PlanningState - expandPrerequisites (PlanningState const& calculationStep) + expandPrerequisites (JobPlanning const& calculationStep) { PlanningState newSubEvaluation( - calculationStep->discoverPrerequisites()); + calculationStep.discoverPrerequisites()); return newSubEvaluation; } @@ -233,11 +234,18 @@ namespace engine { */ class PlanningStepGenerator { + engine::TimeAnchor anchor_; + public: typedef JobPlanning value_type; typedef JobPlanning& reference; typedef JobPlanning * pointer; +// PlanningStepGenerator() { } + + PlanningStepGenerator(engine::TimeAnchor startPoint) + : anchor_(startPoint) + { } /* === Iteration control API for IterStateWrapper== */ @@ -261,8 +269,14 @@ namespace engine { }; -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #827 -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #827 + + + typedef PlanningState (*SIG_expandPrerequisites) (JobPlanning const&); + + typedef lib::IterExplorer JobPlanningChunkStartPoint; + + typedef JobPlanningChunkStartPoint::FlatMapped::Type ExpandedPlanningSequence; @@ -270,11 +284,18 @@ namespace engine { * @todo 6/12 WIP-WIP-WIP how to prepare jobs for scheduling */ class JobPlanningSequence - : public lib::IterExplorer + : public ExpandedPlanningSequence { public: +// JobPlanningSequence() { } + + JobPlanningSequence(engine::TimeAnchor startPoint) + : ExpandedPlanningSequence( + JobPlanningChunkStartPoint( + PlanningStepGenerator(startPoint)) + >>= expandPrerequisites) + { } }; diff --git a/wiki/renderengine.html b/wiki/renderengine.html index ca637dc40..399e8e00d 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -2797,15 +2797,15 @@ From experiences with other middle scale projects, I prefer having the test code [img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]] -
-
The actual media data is rendered by [[individually scheduled render jobs|RenderJob]]. When preparing such jobs, in order to [[dispatch|FrameDispatcher]] the individual frames calculations required to make a given [[stream of calculations|CalcStream]] happen, a ''node planning phase'' is performed. The goal is to find out
+
+
The actual media data is rendered by [[individually scheduled render jobs|RenderJob]]. All these calculations together implement a [[stream of calculations|CalcStream]], as demanded and directed by the PlayProcess. During the preparation of playback, a ''node planning phase'' is performed, to arrange for [[dispatching|FrameDispatcher]] the individual calculations per frame.  The goal of these //preparations//&nbsp; is to find out
 * what channel(s) to pull
 * what prerequisites to prepare
 * what parameters to provide
 The result of this planning phase is the {{{JobTicket}}}, a complete ''execution plan''.
-This planning is uniform for each segment and treated for all channels together, resulting in a nested tree structure of sub job tickets, allocated and stored alongside with the processing nodes and wiring descriptors to form the segment's data and descriptor network. Job tickets are //higher order functions:// entering a concrete frame number and channel into a given job ticket will produce an actual job descriptor, which in itself is again a function, to be invoked through the scheduler when it's time to trigger the actual calculations.
+This planning is uniform for each [[segment|Segmentation]] and treated for all channels together, resulting in a nested tree structure of sub job tickets, allocated and stored alongside with the processing nodes and wiring descriptors to form the segment's data and descriptor network. Job tickets are //higher order functions:// entering a concrete frame number and channel into a given job ticket will produce an actual job descriptor, which in itself is again a function, to be invoked through the scheduler when it's time to trigger the actual calculations.
 
-!Structure of the render Jobs created
+!Structure of the Render Jobs created
 To be more precise: in the general case, invoking the ~JobTicket with a given frame number will produce //multiple jobs//  -- typically each frame rendering will require at least one further source media frame; and because Lumiera render jobs will //never block waiting on IO,// this source media access will be packaged as a separate [[resource retrieving job|ResourceJob]], to be treated specifically by the scheduler.
 
 To support the generation of multiple dependent jobs, a ~JobTicket might refer to further ~JobTickets corresponding to the prerequisites. These prerequisite ~JobTickets are the result of a classical recursive descent call into the top level ProcNode, to perform the planning step. There is always an 1:1 relation between actual jobs generated and the corresponding tickets. More precisely, for each possible job to generate there is a suitable ''job closure'', representing exactly the context information necessary to get that job started. To stress that point: a ProcNode might be configured such as to perform a series of recursive invocations of other prerequisite nodes right away (especially when those recursive invocations correspond just to further CPU bound calculations) -- yet still there is only //one//&nbsp; ~JobTicket, because there will be only one Job to invoke the whole sequence. On the other hand, when there is a prerequisite requiring an operation to be scheduled separately, a corresponding separate {{{JobClosure}}} will be referred.