2011-05-23 04:43:56 +02:00
/*
2011-05-23 05:46:40 +02:00
DISPATCHER . hpp - translating calculation streams into frame jobs
2011-05-23 04:43:56 +02:00
Copyright ( C ) Lumiera . org
2011-05-23 05:46:40 +02:00
2011 , Hermann Vosseler < Ichthyostega @ web . de >
2011-05-23 04:43:56 +02:00
This program 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 .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2011-05-23 05:46:40 +02:00
# ifndef PROC_ENGINE_DISPATCHER_H
# define PROC_ENGINE_DISPATCHER_H
2011-05-23 04:43:56 +02:00
# include "proc/common.hpp"
2012-02-24 00:29:59 +01:00
# include "proc/mobject/model-port.hpp"
2012-02-09 22:24:05 +01:00
# include "proc/engine/time-anchor.hpp"
# include "proc/engine/frame-coord.hpp"
2012-02-13 00:37:57 +01:00
# include "proc/engine/job-ticket.hpp"
2012-07-01 03:42:50 +02:00
# include "proc/engine/job-planning.hpp"
2011-05-23 04:43:56 +02:00
# include "lib/time/timevalue.hpp"
2012-02-04 22:20:21 +01:00
# include <boost/noncopyable.hpp>
2014-04-03 22:42:48 +02:00
# include <functional>
2011-05-23 04:43:56 +02:00
2011-12-02 16:10:03 +01:00
namespace proc {
2011-05-23 04:43:56 +02:00
namespace engine {
2014-04-03 22:42:48 +02:00
using std : : function ;
2012-02-24 00:29:59 +01:00
using mobject : : ModelPort ;
2013-11-18 00:01:43 +01:00
using lib : : time : : FrameCnt ;
2011-05-28 01:46:06 +02:00
using lib : : time : : TimeSpan ;
using lib : : time : : FSecs ;
using lib : : time : : Time ;
2013-01-12 12:38:33 +01:00
2011-05-23 04:43:56 +02:00
/**
2012-10-10 04:35:56 +02:00
* Internal abstraction : a service within the engine
* for translating a logical calculation stream ( corresponding to a PlayProcess )
* into a sequence of individual RenderJob entries for calculations and data access .
* The actual implementation of this service is tied to the low - level - model , i . e .
* the render nodes network . The Dispatcher service is used to implement the CalcStreams
* during playback and rendering ; there will be a continuous , chunk - wise proceeding
* evaluation and planning of new jobs , which can then be handed over to the Scheduler
* for time - bound activation .
*
* \ par usage considerations
* the asynchronous and ongoing nature of the render process mandates to avoid a central
2013-11-16 20:23:02 +01:00
* instance for operating this planning process . Instead , together with each chunk of
* planned jobs we generate a continuation job , which - - on activation - - will pick up
* the planning of the next chunk . The Dispatcher interface was shaped especially to
* support this process , with a local JobBuilder for use within the continuation job ,
* and a TimeAnchor to represent the continuation point . All the complexities of
* actually planning the jobs are hidden within the JobPlanningSequence ,
* which , for the purpose of dispatching a series of jobs just looks
* like a sequence of job descriptors
2012-10-10 04:35:56 +02:00
*
* @ todo 10 / 12 still WIP , but conceptually settled by now
2011-05-23 04:43:56 +02:00
*/
2011-05-23 05:46:40 +02:00
class Dispatcher
2012-10-10 04:35:56 +02:00
: public FrameLocator
2011-05-23 04:43:56 +02:00
{
2012-04-26 04:11:31 +02:00
struct JobBuilder
2012-02-24 00:29:59 +01:00
{
2013-11-18 02:25:27 +01:00
Dispatcher * dispatcher_ ;
2012-02-24 00:29:59 +01:00
ModelPort modelPort_ ;
uint channel_ ;
2013-11-18 02:25:27 +01:00
FrameCoord relativeFrameLocation ( TimeAnchor & refPoint , FrameCnt frameCountOffset = 0 ) ;
2012-04-26 04:11:31 +02:00
2013-06-16 04:36:32 +02:00
JobPlanningSequence
establishNextJobs ( TimeAnchor & refPoint )
2012-04-26 04:11:31 +02:00
{
2012-10-10 04:35:56 +02:00
return JobPlanningSequence (
2013-08-18 03:16:49 +02:00
relativeFrameLocation ( refPoint ) ,
2013-11-18 02:25:27 +01:00
* dispatcher_ ) ;
2012-04-26 04:11:31 +02:00
}
2012-02-24 00:29:59 +01:00
} ;
2011-05-23 04:43:56 +02:00
2013-06-16 04:36:32 +02:00
2011-05-23 04:43:56 +02:00
public :
2012-02-04 22:20:21 +01:00
virtual ~ Dispatcher ( ) ; ///< this is an interface
2012-04-26 04:11:31 +02:00
JobBuilder onCalcStream ( ModelPort modelPort , uint channel ) ;
2012-02-04 22:20:21 +01:00
2011-05-23 04:43:56 +02:00
2012-10-06 02:29:19 +02:00
protected :
2013-11-18 02:25:27 +01:00
/** core dispatcher operation: based on the coordinates of a reference point,
* establish binding frame number , nominal time and real ( wall clock ) deadline .
* @ return new FrameCoord record ( copy ) , with the nominal time , frame number
* and deadline adjusted in accordance to the given frame offset .
*/
virtual FrameCoord locateRelative ( FrameCoord const & , FrameCnt frameOffset ) = 0 ;
2012-10-10 04:35:56 +02:00
2013-11-18 02:25:27 +01:00
virtual bool isEndOfChunk ( FrameCnt , ModelPort port ) = 0 ;
2013-05-30 02:10:56 +02:00
////////TODO: API-1 = just get next frame, without limitations .... CHECK
////////TODO: API-2 = query limitation of planning chunk .... CHECK
////////TODO: API-3 = establish next chunk .... still WIP
////////TODO: Question: why not embedding the time anchor directly within the location generator??
//////// Answer: no this would lead to a huge blob called "the dispatcher"
////////TODO: immediate point to consider: the time anchor is responsible for the real timing calculations. But how to introduce the play strategy *here* ?
2013-06-02 03:09:18 +02:00
////////////TODO: the solution is simple: get rid of the additional job placed magically into the chunk
//////////// instead, provide a dedicated API function to create exactly that job
//////////// and *enclosed* into a specialised JobClosure subclass, embody the code for the follow-up
//////////// As a corollary: the scheduling deadline should be defined right *within* the job!
2013-08-13 01:16:29 +02:00
////////////TODO: remaining issues
//////////// - the TimeAnchor needs to be created directly from the JobParameter. No mutable state!
//////////// - but this leads to a lot of duplicated Timings records, unless we rewrite the TimeAnchor to be noncopyable and use a Timings const&
2012-10-10 04:35:56 +02:00
virtual JobTicket & accessJobTicket ( ModelPort , TimeValue nominalTime ) = 0 ;
2011-05-23 04:43:56 +02:00
} ;
2011-12-02 16:10:03 +01:00
} } // namespace proc::engine
2011-05-23 04:43:56 +02:00
# endif