WIP refactor building of the active render feeds

RenderConfigurator becomes an internal strategy
controlled by the PlayService
This commit is contained in:
Fischlurch 2011-12-17 04:45:42 +01:00
parent bda0dea990
commit 6852a6feff
13 changed files with 171 additions and 81 deletions

View file

@ -35,6 +35,7 @@
//#include <boost/noncopyable.hpp>
//#include <boost/scoped_ptr.hpp>
//#include <string>
#include <vector>
namespace proc {
@ -86,6 +87,9 @@ namespace engine{
};
typedef std::vector<CalcStream> CalcStreams;

View file

@ -57,25 +57,33 @@ namespace engine{
/** */
CalcStream
/** core operation: activate the Lumiera Render Engine.
* Invoking this service effectively hooks up each channel
* of the given model exit point to deliver into the corresponding
* output sink on the given OutputConnection (which is assumed
* to be already allocated for active use by this connection).
* The generated calculation streams represent actively ongoing
* calculations within the engine, started right away, according
* to the given timing constraints and service quality.
*/
CalcStreams
EngineService::calculate(ModelPort mPort,
Timings nominalTimings,
OutputConnection& output,
Quality serviceQuality)
{
UNIMPLEMENTED ("build a standard calculation stream");
UNIMPLEMENTED ("build a list of standard calculation streams");
}
/** */
CalcStream
CalcStreams
EngineService::calculateBackground(ModelPort mPort,
Timings nominalTimings,
Quality serviceQuality)
{
UNIMPLEMENTED ("build a calculation stream for background rendering");
UNIMPLEMENTED ("build calculation streams for background rendering");
}

View file

@ -138,13 +138,13 @@ namespace engine{
EngineService();
~EngineService() { }
CalcStream
CalcStreams
calculate(ModelPort mPort,
Timings nominalTimings,
OutputConnection& output,
Quality serviceQuality =QoS_DEFAULT);
CalcStream
CalcStreams
calculateBackground(ModelPort mPort,
Timings nominalTimings,
Quality serviceQuality =QoS_BACKGROUND);

View file

@ -158,8 +158,14 @@ namespace play {
return transform (eachElm(*this), connectOutputSink);
}
Timings
getTimingConstraints()
{
UNIMPLEMENTED ("find out about timing constraints"); //////////////////////////TICKET #831
}
bool
isActive()
isActive() const
{
return 0 < Connections::size();
}

View file

@ -98,12 +98,13 @@ namespace play {
class Allocation
{
public:
virtual OpenedSinks getOpenedSinks() =0;
virtual bool isActive() =0;
virtual OpenedSinks getOpenedSinks() =0;
virtual bool isActive() const =0;
virtual Timings getTimingConstraints() =0;
/////TODO add here the getters for timing constraints
protected:
~Allocation();
~Allocation(); ///< never to be managed by clients directly
};
/** established output channel */

View file

@ -22,6 +22,7 @@
#include "proc/play/play-process.hpp"
#include "proc/play/play-service.hpp"
#include "proc/play/render-configurator.hpp"
#include "lib/itertools.hpp"
@ -40,65 +41,33 @@ namespace play {
// using std::auto_ptr;
// using boost::scoped_ptr;
// using std::tr1::bind;
using lib::transform;
namespace { // Implementation details...
using std::tr1::bind;
using std::tr1::function;
using std::tr1::placeholders::_1;
using lib::transform;
Feed
resolveOutputConnection (ModelPort port, POutputManager outputResolver)
{
REQUIRE (outputResolver);
OutputSlot& slot = outputResolver->getOutputFor (port);
if (!slot.isFree())
throw error::State("unable to acquire a suitable output slot" /////////////////////TICKET #197 #816
, LUMIERA_ERROR_CANT_PLAY);
RenderConfigurator& configurator (*(RenderConfigurator*)NULL); //////////////////////////////////TODO: how to get the RenderConfigurator (strategy) here???
return Feed (port,slot,configurator);
}
typedef function<Feed(ModelPort)> ConnectFunction;
/** try to establish an output slot for the given
* global bus or data production exit point.
* @param outputResolver a facility able to resolve to
* a concrete output slot within the actual context
* @throw error::State when resolution fails
*/
ConnectFunction
resolve (POutputManager outputResolver)
{
return bind (resolveOutputConnection, _1, outputResolver);
}
} // (End) hidden service impl details
/**
* Factory: Initialise and configure a new PlayProcess.
* The caller gets to own and manage the returned process entry.
*/
PlayProcess*
PlayProcess::initiate (ModelPorts dataGenerators, POutputManager outputDestinations)
PlayProcess::initiate (ModelPorts dataGenerators, RenderConfigurator& activeOutputFeedBuilder)
{
return new PlayProcess (transform (dataGenerators,
resolve(outputDestinations)));
activeOutputFeedBuilder));
}
/** @internal actually create and configure a play process instance */
PlayProcess::PlayProcess (Feed::Connections pipeConnections)
PlayProcess::PlayProcess (Connections pipeConnections)
{
if (isnil (pipeConnections))
throw error::State ("creating a PlayProcess without any usable output connections"
@ -113,8 +82,8 @@ namespace play {
/** */
Feed::Feed (ModelPort port, OutputSlot& output, RenderConfigurator& renderStrategy)
: renderStreams_(renderStrategy.buildCalculationStreams(port,output))
Feed::Feed (engine::CalcStreams const& newActiveRenderingConnections)
: renderStreams_(newActiveRenderingConnections)
{ }

View file

@ -57,7 +57,6 @@
//#include "common/instancehandle.hpp"
//#include "lib/singleton-ref.hpp"
#include "proc/mobject/model-port.hpp"
#include "proc/play/output-manager.hpp"
#include "proc/engine/calc-stream.hpp"
#include "lib/iter-source.hpp"
#include "lib/util.hpp"
@ -78,7 +77,6 @@ namespace play {
using util::isnil;
using proc::mobject::ModelPort;
typedef proc::play::POutputManager POutputManager;
typedef lib::IterSource<ModelPort>::iterator ModelPorts;
namespace error = lumiera::error;
@ -96,18 +94,14 @@ namespace play {
*/
class Feed
{
engine::CalcStreams renderStreams_;
public:
typedef lib::IterSource<Feed>::iterator Connections;
typedef std::vector<engine::CalcStream> RenderStreams;
RenderStreams renderStreams_;
/** building a Feed effectively involves the EngineService
* to establish an actual rendering plan. Which is abstracted
* here through the RenderConfigurator instance */
Feed (ModelPort, OutputSlot&, RenderConfigurator&);
Feed (engine::CalcStreams const&);
};
@ -132,11 +126,13 @@ namespace play {
{
std::vector<Feed> outputFeeds_;
PlayProcess (Feed::Connections pipeConnections);
typedef lib::IterSource<Feed>::iterator Connections;
PlayProcess (Connections pipeConnections);
public:
static PlayProcess*
initiate (ModelPorts dataGenerators, POutputManager outputDestinations);
initiate (ModelPorts dataGenerators, RenderConfigurator&);
};

View file

@ -25,6 +25,7 @@
#include "include/play-facade.h"
#include "proc/play/play-service.hpp"
#include "proc/play/play-process.hpp"
#include "proc/play/render-configurator.hpp"
#include "lib/util-foreach.hpp"
@ -62,7 +63,7 @@ namespace play {
using std::tr1::placeholders::_1;
using util::remove_if;
using util::and_all;
namespace { // hidden local details of the service implementation....
@ -74,6 +75,11 @@ namespace play {
} // (End) hidden service impl details
using lumiera::Play;
typedef POutputManager Output;
class ProcessTable
: public Sync<RecursiveLock_NoWait>
@ -87,10 +93,10 @@ namespace play {
public:
lumiera::Play::Controller
Play::Controller
establishProcess (PlayProcess* newProcess)
{
lumiera::Play::Controller frontend;
Play::Controller frontend;
try {
frontend.activate (newProcess, bind (&ProcessTable::endProcess, this, _1 ));
}
@ -105,6 +111,7 @@ namespace play {
return frontend;
}
bool
isActive() const
{
@ -130,8 +137,7 @@ namespace play {
};
using lumiera::Play;
PlayService::~PlayService()
{
@ -173,11 +179,22 @@ namespace play {
PlayService::connect (ModelPorts dataGenerators, Output outputDestinations)
{
return pTable_->establishProcess(
PlayProcess::initiate(dataGenerators, outputDestinations));
PlayProcess::initiate(dataGenerators,
buildRenderConfiguration(outputDestinations)));
}
/** */
RenderConfigurator&
PlayService::buildRenderConfiguration (Output outputDestinations)
{
UNIMPLEMENTED ("how to build a suitable render configuration");
}
LUMIERA_ERROR_DEFINE (CANT_PLAY, "unable to build playback or render process for this configuration");

View file

@ -78,6 +78,7 @@ namespace play {
// class DummyImageGenerator;
// class TickService;
class ProcessTable;
class RenderConfigurator;
@ -108,6 +109,8 @@ namespace play {
/** Implementation: build a PlayProcess */
virtual Controller connect(ModelPorts, Output);
RenderConfigurator& buildRenderConfiguration(Output);
public:
PlayService(); /////TODO Subsys::SigTerm terminationHandle);
@ -117,6 +120,9 @@ namespace play {
};
LUMIERA_ERROR_DECLARE (CANT_PLAY); ///< unable to build playback or render process for this configuration
}} // namespace proc::play

View file

@ -21,13 +21,15 @@
* *****************************************************/
#include "lib/error.hpp"
#include "proc/play/render-configurator.hpp"
#include "proc/play/output-manager.hpp"
#include "proc/engine/engine-service.hpp"
//#include "lib/itertools.hpp"
//#include <string>
//#include <memory>
//#include <tr1/functional>
#include <tr1/functional>
//#include <boost/scoped_ptr.hpp>
@ -35,11 +37,36 @@
namespace proc {
namespace play {
namespace error = lumiera::error;
// using std::string;
// using lumiera::Subsys;
// using std::auto_ptr;
// using boost::scoped_ptr;
// using std::tr1::bind;
using std::tr1::bind;
using std::tr1::placeholders::_1;
using engine::EngineService;
typedef EngineService::QoS_Definition RenderQuality;
/** Template Method: how to build an active render feed,
* pulling from the given exit point of the model and
* feeding the OutputSlot established appropriately
* to deliver media data of suitable type */
Feed
RenderConfigurator::buildActiveFeed (ModelPort port)
{
OutputSlot& slot = getOutputFor (port);
return Feed (buildCalculationStreams (port,slot));
}
RenderConfigurator::RenderConfigurator()
: function<Feed(ModelPort)> (bind (&RenderConfigurator::buildActiveFeed, this, _1))
{ }
namespace { // Implementation details...
@ -53,20 +80,41 @@ namespace play {
: public RenderConfigurator
{
Feed::RenderStreams
POutputManager outputResolver_;
Timings playbackTimings_;
RenderQuality renderQuality_;
OutputSlot&
getOutputFor (ModelPort port)
{
REQUIRE (outputResolver_);
OutputSlot& slot = outputResolver_->getOutputFor (port);
if (!slot.isFree())
throw error::State("unable to acquire a suitable output slot" /////////////////////TICKET #197 #816
, LUMIERA_ERROR_CANT_PLAY);
return slot;
}
engine::CalcStreams
buildCalculationStreams (ModelPort port, OutputSlot& output)
{
UNIMPLEMENTED("build an active playback/render feed");
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #832
OutputSlot::Allocation& activeOutputConnection = output.allocate();
Timings nominalTimings = activeOutputConnection.getTimingConstraints()
.constrainedBy(playbackTimings_);
///TODO allocate the output slot
///TODO extract the individual channels
///TODO get the timings
///TODO define the Quality
engine::EngineService::instance().calculate(port, nominalTimings, activeOutputConnection, serviceQuality);
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #832
return EngineService::instance().calculate(port, nominalTimings, activeOutputConnection, renderQuality_);
}
public:
DefaultRenderProcessBuilder(POutputManager outputManager, Timings playbackSpeed)
: outputResolver_(outputManager)
, playbackTimings_(playbackSpeed)
, renderQuality_(EngineService::QoS_DEFAULT)
{ }
};

View file

@ -41,6 +41,8 @@
//#include "lib/singleton-ref.hpp"
#include "proc/mobject/model-port.hpp"
#include "proc/play/play-process.hpp"
#include "proc/engine/calc-stream.hpp"
#include "proc/play/output-slot.hpp"
//#include "proc/play/output-manager.hpp"
//#include "lib/iter-source.hpp"
//#include "lib/util.hpp"
@ -48,6 +50,7 @@
//#include <boost/noncopyable.hpp>
//#include <boost/scoped_ptr.hpp>
//#include <string>
#include <tr1/functional>
#include <vector>
@ -59,6 +62,7 @@ namespace play {
// using lumiera::Display;
// using lumiera::DummyPlayer;
// using util::isnil;
using std::tr1::function;
using proc::mobject::ModelPort;
// typedef proc::play::POutputManager POutputManager;
@ -69,13 +73,38 @@ namespace play {
/** Strategy for configuring the render process */
class RenderConfigurator
: public function<Feed(ModelPort)>
{
public:
virtual ~RenderConfigurator(); ///< this is an interface
private:
Feed buildActiveFeed (ModelPort);
virtual Feed::RenderStreams buildCalculationStreams (ModelPort, OutputSlot&) =0;
protected:
RenderConfigurator();
/** retrieve a suitable output sink for the data
* to be produced at the given model exit point.
* While the port already defines the necessary StreamType,
* this strategy still has to decide what concrete output sink
* to use accordingly.
*/
virtual OutputSlot& getOutputFor (ModelPort port) =0;
/** build active rendering connections, thereby delivering each channel
* of the given model port into the corresponding output sink.
* This strategy will try to allocate the output slot for output (may fail).
* Moreover, a suitable combination of output timings and service quality
* will be picked
* @return List of active CalcStream descriptors, created and registered
* with the EngineFacade, one for each channel connection.
* @note when this strategy function returns, the corresponding
* render activities are already up and running.
*/
virtual engine::CalcStreams buildCalculationStreams (ModelPort, OutputSlot&) =0;
};

View file

@ -81,6 +81,12 @@ namespace play {
{
public:
//////////////TODO accessor functions here
Timings
constrainedBy (Timings additionalConditions)
{
UNIMPLEMENTED ("how to combine timing constraints");
}
};

View file

@ -97,7 +97,7 @@ namespace test {
Timings timings; /////////TODO
// Invoke test subject...
CalcStream calc = engine.calculate(port, timings, output);
CalcStreams calc = engine.calculate(port, timings, output);
////TODO some direct checks on the calculation stream??