LUMIERA.clone/src/proc/engine/dispatcher.hpp

116 lines
4.1 KiB
C++
Raw Normal View History

/*
DISPATCHER.hpp - translating calculation streams into frame jobs
Copyright (C) Lumiera.org
2011, Hermann Vosseler <Ichthyostega@web.de>
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 02139, USA.
*/
#ifndef PROC_ENGINE_DISPATCHER_H
#define PROC_ENGINE_DISPATCHER_H
#include "proc/common.hpp"
2012-02-24 00:29:59 +01:00
#include "proc/mobject/model-port.hpp"
#include "proc/engine/time-anchor.hpp"
#include "proc/engine/frame-coord.hpp"
#include "proc/engine/job-ticket.hpp"
#include "proc/engine/job-planning.hpp"
#include "lib/time/timevalue.hpp"
2012-02-04 22:20:21 +01:00
#include <boost/noncopyable.hpp>
#include <tr1/functional>
namespace proc {
namespace engine {
using std::tr1::function;
2012-02-24 00:29:59 +01:00
using mobject::ModelPort;
using lib::time::TimeSpan;
using lib::time::FSecs;
using lib::time::Time;
/**
* 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
* instance for operating this planning process. Instead, each chunk of planned jobs
* contains a continuation job, which -- on activation -- will pick up the planning
* of the next chunk. The Dispatcher interface was shaped to support this process,
* with a local JobBuilder to be used within the continuation job, and a TimeAnchor
* to represent the continuation point. All the complexities of planning jobs are
* hidden within the JobPlanningSequence, which, for the purpose of dispatching
* a series of jobs just looks like a sequence of job descriptors
*
* @todo 10/12 still WIP, but conceptually settled by now
*/
class Dispatcher
: public FrameLocator
{
struct JobBuilder
2012-02-24 00:29:59 +01:00
{
Dispatcher& dispatcher_;
TimeAnchor refPoint_;
2012-02-24 00:29:59 +01:00
ModelPort modelPort_;
uint channel_;
/////TODO need storage for the continuation
FrameCoord relativeFrameLocation (TimeAnchor refPoint, uint frameCountOffset =0);
JobBuilder& establishNextJobs (TimeAnchor refPoint);
JobBuilder& prepareContinuation (function<void(TimeAnchor)> delayedAction);
operator JobPlanningSequence()
{
TODO ("build the continuation job if necessary, wrap the sequence");
return JobPlanningSequence(
relativeFrameLocation(refPoint_), dispatcher_);
}
2012-02-24 00:29:59 +01:00
};
public:
2012-02-04 22:20:21 +01:00
virtual ~Dispatcher(); ///< this is an interface
JobBuilder onCalcStream (ModelPort modelPort, uint channel);
2012-02-04 22:20:21 +01:00
protected:
virtual FrameCoord locateRelative (FrameCoord, uint frameCountOffset) =0;
virtual FrameCoord locateRelative (TimeAnchor, uint frameCountOffset) =0; //////////TODO is this really an interface operation, or just a convenience shortcut?
virtual JobTicket& accessJobTicket (ModelPort, TimeValue nominalTime) =0;
};
}} // namespace proc::engine
#endif