diff --git a/src/proc/engine/calc-stream.hpp b/src/proc/engine/calc-stream.hpp index 3263ddfd5..9772c1c34 100644 --- a/src/proc/engine/calc-stream.hpp +++ b/src/proc/engine/calc-stream.hpp @@ -35,6 +35,7 @@ //#include //#include //#include +#include namespace proc { @@ -86,6 +87,9 @@ namespace engine{ }; + typedef std::vector CalcStreams; + + diff --git a/src/proc/engine/engine-service.cpp b/src/proc/engine/engine-service.cpp index a4e989a19..926cef268 100644 --- a/src/proc/engine/engine-service.cpp +++ b/src/proc/engine/engine-service.cpp @@ -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"); } diff --git a/src/proc/engine/engine-service.hpp b/src/proc/engine/engine-service.hpp index 7e5c1339b..3c0c1e708 100644 --- a/src/proc/engine/engine-service.hpp +++ b/src/proc/engine/engine-service.hpp @@ -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); diff --git a/src/proc/play/output-slot-connection.hpp b/src/proc/play/output-slot-connection.hpp index e4e9b6787..2cbd34c4e 100644 --- a/src/proc/play/output-slot-connection.hpp +++ b/src/proc/play/output-slot-connection.hpp @@ -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(); } diff --git a/src/proc/play/output-slot.hpp b/src/proc/play/output-slot.hpp index 6fe5b09a2..8c7dd9c86 100644 --- a/src/proc/play/output-slot.hpp +++ b/src/proc/play/output-slot.hpp @@ -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 */ diff --git a/src/proc/play/play-process.cpp b/src/proc/play/play-process.cpp index 01301d102..de1a66795 100644 --- a/src/proc/play/play-process.cpp +++ b/src/proc/play/play-process.cpp @@ -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 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) { } diff --git a/src/proc/play/play-process.hpp b/src/proc/play/play-process.hpp index 80df7a389..532c3c70c 100644 --- a/src/proc/play/play-process.hpp +++ b/src/proc/play/play-process.hpp @@ -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::iterator ModelPorts; namespace error = lumiera::error; @@ -96,18 +94,14 @@ namespace play { */ class Feed { + engine::CalcStreams renderStreams_; public: - typedef lib::IterSource::iterator Connections; - - typedef std::vector 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 outputFeeds_; - PlayProcess (Feed::Connections pipeConnections); + typedef lib::IterSource::iterator Connections; + + PlayProcess (Connections pipeConnections); public: static PlayProcess* - initiate (ModelPorts dataGenerators, POutputManager outputDestinations); + initiate (ModelPorts dataGenerators, RenderConfigurator&); }; diff --git a/src/proc/play/play-service.cpp b/src/proc/play/play-service.cpp index c2265c588..b6ae24042 100644 --- a/src/proc/play/play-service.cpp +++ b/src/proc/play/play-service.cpp @@ -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 @@ -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"); diff --git a/src/proc/play/play-service.hpp b/src/proc/play/play-service.hpp index 144e24925..6cc4f9386 100644 --- a/src/proc/play/play-service.hpp +++ b/src/proc/play/play-service.hpp @@ -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 diff --git a/src/proc/play/render-configurator.cpp b/src/proc/play/render-configurator.cpp index 65df04958..b134de40b 100644 --- a/src/proc/play/render-configurator.cpp +++ b/src/proc/play/render-configurator.cpp @@ -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 //#include -//#include +#include //#include @@ -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 (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) + { } + }; diff --git a/src/proc/play/render-configurator.hpp b/src/proc/play/render-configurator.hpp index 4dc94861b..7b9ef6336 100644 --- a/src/proc/play/render-configurator.hpp +++ b/src/proc/play/render-configurator.hpp @@ -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 //#include //#include +#include #include @@ -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 { 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; }; diff --git a/src/proc/play/timings.hpp b/src/proc/play/timings.hpp index a3613bbf9..5c6963f17 100644 --- a/src/proc/play/timings.hpp +++ b/src/proc/play/timings.hpp @@ -81,6 +81,12 @@ namespace play { { public: //////////////TODO accessor functions here + + Timings + constrainedBy (Timings additionalConditions) + { + UNIMPLEMENTED ("how to combine timing constraints"); + } }; diff --git a/tests/components/proc/engine/engine-interface-test.cpp b/tests/components/proc/engine/engine-interface-test.cpp index 3b0e96bd8..0345b0334 100644 --- a/tests/components/proc/engine/engine-interface-test.cpp +++ b/tests/components/proc/engine/engine-interface-test.cpp @@ -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??