diff --git a/src/proc/engine/dispatcher.hpp b/src/proc/engine/dispatcher.hpp
index 806f49cd4..b084f6c83 100644
--- a/src/proc/engine/dispatcher.hpp
+++ b/src/proc/engine/dispatcher.hpp
@@ -60,6 +60,8 @@ namespace engine {
ModelPort modelPort_;
uint channel_;
+ /////TODO need storage for the continuation
+
FrameCoord relativeFrameLocation (TimeAnchor refPoint, uint frameCountOffset);
JobBuilder& establishNextJobs (TimeAnchor refPoint);
@@ -70,8 +72,9 @@ namespace engine {
{
UNIMPLEMENTED ("how to represent the closure for defining and scheduling jobs");
- ////////TODO: use a closure based on the JobTicket (which can be accessed through the dispatcher backlink)
- //////////// Because this closure is what backs the IterSource, it needs to have a reliable storage though.
+ ////////TODO: use a closure based on FrameCoord plus a back-reference to the Dispatcher.
+ //////////// Thus actually we need a *generator* for a sequence of FrameCoord
+ //////////// This generator is then wrapped up into an evaluation-Monad (IterExplorer)
}
};
@@ -83,8 +86,9 @@ namespace engine {
JobTicket& accessJobTicket (FrameCoord const&);
- protected:
- virtual FrameCoord locateFrameNext (uint frameCountOffset, TimeAnchor refPoint) =0;
+ protected:
+ virtual FrameCoord locateRelative (FrameCoord, uint frameCountOffset) =0;
+ virtual FrameCoord locateRelative (TimeAnchor, uint frameCountOffset) =0;
};
diff --git a/src/proc/engine/frame-coord.hpp b/src/proc/engine/frame-coord.hpp
index c211b1193..a73be8d96 100644
--- a/src/proc/engine/frame-coord.hpp
+++ b/src/proc/engine/frame-coord.hpp
@@ -90,5 +90,33 @@ namespace engine {
+ /**
+ * Facility for producing a sequence of FrameCoord.
+ * This interface describes the essence of generating
+ * a series of frame locations, which is necessary for
+ * planning render jobs. To implement it, actually some
+ * kind of \link lib::time::Quantiser frame grid \endlink
+ * is necessary -- in practice we use a Dispatcher, which is
+ * backed by the Segmentation (i.e. the render nodes network).
+ */
+ class FrameSequencer
+ : boost::noncopyable
+ {
+
+ public:
+ virtual ~FrameSequencer(); ///< this is an interface
+
+ FrameCoord
+ getNextFrame (FrameCoord refPoint)
+ {
+ return locateRelative (refPoint, +1 );
+ }
+
+ protected:
+ virtual FrameCoord locateRelative (FrameCoord, uint frameCountOffset) =0;
+ };
+
+
+
}} // namespace proc::engine
#endif
diff --git a/src/proc/engine/job-planning.hpp b/src/proc/engine/job-planning.hpp
index abe77c9d8..f0268b289 100644
--- a/src/proc/engine/job-planning.hpp
+++ b/src/proc/engine/job-planning.hpp
@@ -240,7 +240,8 @@ namespace engine {
*/
class PlanningStepGenerator
{
- engine::TimeAnchor anchor_;
+ engine::FrameSequencer* locationGenerator_;
+ engine::FrameCoord current_;
public:
typedef JobPlanning value_type;
@@ -252,6 +253,12 @@ namespace engine {
PlanningStepGenerator(engine::TimeAnchor startPoint)
: anchor_(startPoint)
{ }
+ //////////////////////////////////////////////////////////////TODO actually we need two distinct services
+ //////////////////////////////////////////////////////////////TODO - getting the next FrameCoord
+ //////////////////////////////////////////////////////////////TODO - getting the JobTicket for this location
+ //////////////////////////////////////////////////////////////TODO Actually, the Dispatcher would provide exactly those services,
+ //////////////////////////////////////////////////////////////TODO but depending on the Dispatcher constitutes a cyclic dependency.
+ //////////////////////////////////////////////////////////////TODO There seems to be a problem hidden somewhere in this design.
/* === Iteration control API for IterStateWrapper== */
@@ -287,6 +294,28 @@ namespace engine {
/**
+ * This iterator represents a pipeline to pull planned jobs from.
+ * For dispatching individual frame jobs for rendering, this pipeline is
+ * generated and internally wired such as to interpret the render node definitions.
+ *
+ * \par Explanation of the structure
+ *
+ * The JobPlanningSequence is constructed from several nested layers of functionality
+ * - for the client, it is an iterator, exposing a sequence of JobPlanning elements
+ * - a JobPlanning element allows to add a frame render job to the scheduler
+ * - actually such an element can even be \em converted directly into a Job (descriptor)
+ * - the sequence of such JobPlanning elements (that is, the iterator) is called a PlanningState,
+ * since evaluating this iterator effectively drives the process of job planning ahead
+ * - this planning process is \em implemented as a recursive evaluation and exploration of
+ * a tree of prerequisites; these prerequisites are defined in the JobTicket datastructure
+ * - there is an underlying grid of evaluation starting points, each corresponding to a
+ * single frame. Typically, each frame generates at least two jobs, one for fetching
+ * data, and one for the actual calculations. Depending on the actual render network,
+ * a lot of additional jobs might be necessary
+ * - this basic frame grid is generated by the PlanningStepGenerator, which is
+ * effectively backed by the Dispatcher and thus the render node model.
+ *
+ *
* @todo 6/12 WIP-WIP-WIP how to prepare jobs for scheduling
*/
class JobPlanningSequence
diff --git a/src/proc/engine/job-ticket.hpp b/src/proc/engine/job-ticket.hpp
index b38df691c..45ff53b47 100644
--- a/src/proc/engine/job-ticket.hpp
+++ b/src/proc/engine/job-ticket.hpp
@@ -242,6 +242,9 @@ using util::isnil;
/////////////////////TODO problem is: we need an JobTicket::Prerequisite instance, where the descriptor points to "self" (this JobTicket)
/////////////////////TODO : but this instance needs to reside somewhere at a safe location, since we want to embed an LinkedElements-iterator
/////////////////////TODO : into the ExplorationState. And obviously we do not want that instance in each JobTicket, only in the top level ones
+
+ /////////////////////TODO : on second thought -- better have a top-level entry point to the evaluation of a frame
+ /////////////////////TODO basically this inherits from Prerequisite and lives somehow in the dispatcher-table or segment
}
diff --git a/src/proc/engine/time-anchor.hpp b/src/proc/engine/time-anchor.hpp
index f944a5f86..7d2b5cc63 100644
--- a/src/proc/engine/time-anchor.hpp
+++ b/src/proc/engine/time-anchor.hpp
@@ -46,17 +46,14 @@ namespace engine {
// class ExitNode;
/**
- * The process of playback or rendering is a continued series of
- * exploration and evaluation. The outline of what needs to be calculated
- * is determined continuously, proceeding in chunks of evaluation.
- * Each of these continued partial evaluations establishes a distinct
- * anchor or breaking point in time: everything before this point
- * is settled and planned thus far. Effectively, this time point
- * acts as a evaluation closure, to be picked up on the
- * next partial evaluation. More specifically, the TimeAnchor
- * closure is the definitive binding between the abstract
- * logical time of the session timeline, and the real
- * wall-clock time forming the deadline for rendering.
+ * The process of playback or rendering is a continued series of exploration and evaluation.
+ * The outline of what needs to be calculated is determined continuously, proceeding in
+ * chunks of evaluation. Each of these continued partial evaluations establishes a distinct
+ * anchor or breaking point in time: everything before this point can be considered settled
+ * and planned thus far. Effectively, this time point acts as a evaluation closure,
+ * to be picked up on the next partial evaluation. More specifically, the TimeAnchor closure
+ * is the definitive binding between the abstract logical time of the session timeline, and
+ * the real wall-clock time forming the deadline for rendering.
*
* \par internals
* The time anchor associates a nominal time, defined on the implicit time grid