diff --git a/src/lib/scoped-collection.hpp b/src/lib/scoped-collection.hpp index f3a1e313f..b9174401b 100644 --- a/src/lib/scoped-collection.hpp +++ b/src/lib/scoped-collection.hpp @@ -404,7 +404,7 @@ namespace lib { /* === Element access and iteration === */ I& - operator[] (size_t index) + operator[] (size_t index) const { if (index < level_) return elements_[index].accessObj(); diff --git a/src/proc/asset/meta/time-grid.cpp b/src/proc/asset/meta/time-grid.cpp index c46509787..89744eee0 100644 --- a/src/proc/asset/meta/time-grid.cpp +++ b/src/proc/asset/meta/time-grid.cpp @@ -75,6 +75,8 @@ namespace meta { * from the AssetManager, then attach a further * smart-ptr-to-Quantiser to that, which then can be * published via the \link advice.hpp "advice system"\endlink + * @note this allows to use a time grid just "by name", + * without explicit dependance to the Session / Assets */ inline PGrid publishWrapped (TimeGrid& newGrid) diff --git a/src/proc/play/output-slot-connection.hpp b/src/proc/play/output-slot-connection.hpp index 29e6bf8e4..71a830c7e 100644 --- a/src/proc/play/output-slot-connection.hpp +++ b/src/proc/play/output-slot-connection.hpp @@ -41,17 +41,19 @@ #include "lib/error.hpp" #include "proc/play/output-slot.hpp" +#include "lib/scoped-collection.hpp" +#include "lib/iter-adapter-stl.hpp" +#include "lib/iter-source.hpp" #include "lib/handle.hpp" //#include "lib/time/timevalue.hpp" //#include "proc/engine/buffer-provider.hpp" //#include "proc/play/timings.hpp" -#include "lib/iter-source.hpp" -#include "lib/iter-adapter-stl.hpp" //#include "lib/sync.hpp" #include #include //#include +#include #include //#include @@ -65,7 +67,9 @@ namespace play { //using std::string; using lib::transform; using lib::iter_stl::eachElm; - + + using std::tr1::placeholders::_1; + using std::tr1::bind; using std::vector; //using std::tr1::shared_ptr; using boost::scoped_ptr; @@ -92,6 +96,7 @@ namespace play { * implementation; yet it may as well be called from a separate * service thread or some kind of callback. * @note the meaning of FrameID is implementation defined. + * @note typically the concrete connection is noncopyable */ class OutputSlot::Connection { @@ -121,6 +126,8 @@ namespace play { { public: virtual ~ConnectionState() { } + + virtual Connection& access (uint) const =0; }; @@ -143,11 +150,12 @@ namespace play { template class ConnectionStateManager : public OutputSlot::ConnectionState - , public vector { - typedef vector Connections; + typedef lib::ScopedCollection Connections; typedef OutputSlot::OpenedSinks OpenedSinks; + Connections connections_; + /* == Allocation Interface == */ @@ -155,7 +163,7 @@ namespace play { getOpenedSinks() { REQUIRE (this->isActive()); - return transform (eachElm(*this), connectOutputSink); + return transform (eachElm(connections_), connectOutputSink); } Timings @@ -167,25 +175,29 @@ namespace play { bool isActive() const { - return 0 < Connections::size(); + return 0 < connections_.size(); + } + + CON& + access (uint chanNr) const + { + return connections_[chanNr]; } protected: /* == API for OutputSlot-Impl == */ + typedef typename Connections::ElementHolder& ConnectionStorage; + /** factory function to build the actual * connection handling objects per channel */ - virtual CON buildConnection() =0; - - void - init (uint numChannels) - { - for (uint i=0; i query4grid(gridID) ; + PGrid testGrid25 = query4grid.getAdvice(); + + if (!testGrid25) + testGrid25 = TimeGrid::build (gridID, FrameRate::PAL); + + ENSURE (testGrid25); + return testGrid25; + } + } + + /** * Diagnostic output connection for a single channel, * allowing to track generated frames and verify @@ -77,17 +99,20 @@ namespace play { */ class TrackingInMemoryBlockSequence : public OutputSlot::Connection + , boost::noncopyable { typedef std::tr1::unordered_set FrameTrackingInfo; - shared_ptr buffProvider_; + TrackingHeapBlockProvider buffProvider_; BufferDescriptor bufferType_; FrameTrackingInfo frameTrackingIndex_; PGrid frameGrid_; + bool closed_; + BuffHandle trackFrame (FrameID frameNr, BuffHandle const& newBuffer) @@ -115,8 +140,9 @@ namespace play { BuffHandle claimBufferFor(FrameID frameNr) { + REQUIRE (!closed_); return trackFrame (frameNr, - buffProvider_->lockBuffer (bufferType_)); + buffProvider_.lockBuffer (bufferType_)); } @@ -132,34 +158,38 @@ namespace play { void transfer (BuffHandle const& filledBuffer) { + REQUIRE (!closed_); pushout (filledBuffer); } void pushout (BuffHandle const& data4output) { - buffProvider_->emitBuffer (data4output); - buffProvider_->releaseBuffer(data4output); + REQUIRE (!closed_); + buffProvider_.emitBuffer (data4output); + buffProvider_.releaseBuffer(data4output); } void discard (BuffHandle const& superseededData) { - buffProvider_->releaseBuffer (superseededData); + REQUIRE (!closed_); + buffProvider_.releaseBuffer (superseededData); } void shutDown () { - buffProvider_.reset(); + closed_ = true; } public: TrackingInMemoryBlockSequence() - : buffProvider_(new TrackingHeapBlockProvider()) - , bufferType_(buffProvider_->getDescriptor()) + : buffProvider_() + , bufferType_(buffProvider_.getDescriptor()) , frameTrackingIndex_() - , frameGrid_(TimeGrid::build ("DiagnosticOutputSlot-buffer-grid", FrameRate::PAL)) /////////////TODO should rather pass that in as part of a "timings" definition + , frameGrid_(getTestTimeGrid()) /////////////TODO should rather pass that in as part of a "timings" definition + , closed_(false) { INFO (engine_dbg, "building in-memory diagnostic output sequence"); } @@ -173,22 +203,20 @@ namespace play { /* === Diagnostic API === */ - TestFrame* + TestFrame const * accessEmittedFrame (uint frameNr) const { - REQUIRE (buffProvider_); - if (frameNr <= buffProvider_->emittedCnt()) - return &buffProvider_->accessAs (frameNr); + if (frameNr <= buffProvider_.emittedCnt()) + return & accessFrame(frameNr); else return 0; ////////////////////////////////TICKET #856 } - diagn::Block* + diagn::Block const * accessEmittedBuffer (uint bufferNr) const { - REQUIRE (buffProvider_); - if (bufferNr <= buffProvider_->emittedCnt()) - return & buffProvider_->access_emitted (bufferNr); + if (bufferNr <= buffProvider_.emittedCnt()) + return & accessBlock(bufferNr); else return 0; } @@ -196,9 +224,21 @@ namespace play { bool wasAllocated (uint frameNr) const { - REQUIRE (buffProvider_); return contains (frameTrackingIndex_, frameNr); } + + private: + TestFrame const& + accessFrame (uint frameNr) const + { + return unConst(this)->buffProvider_.accessAs (frameNr); + } + + diagn::Block const& + accessBlock (uint bufferNr) const + { + return unConst(this)->buffProvider_.access_emitted (bufferNr); + } }; @@ -210,17 +250,18 @@ namespace play { class SimulatedOutputSequences : public ConnectionStateManager { - TrackingInMemoryBlockSequence - buildConnection() + typedef ConnectionStateManager _Base; + + void + buildConnection(ConnectionStorage storage) { - return TrackingInMemoryBlockSequence(); + storage.create(); } public: SimulatedOutputSequences (uint numChannels) - { - init (numChannels); - } + : _Base(numChannels) + { } }; @@ -276,7 +317,7 @@ namespace play { { REQUIRE (!isFree(), "diagnostic OutputSlot not (yet) connected"); REQUIRE (channel <= getOutputChannelCount()); - return static_cast (*state_).at(channel); + return static_cast (state_->access (channel)); } @@ -307,7 +348,7 @@ namespace play { * the emitted Data as a sequence of TestFrame objects. */ class OutputFramesLog - : public lib::IterSource + : public lib::IterSource , boost::noncopyable { TrackingInMemoryBlockSequence const& outSeq_; @@ -366,8 +407,8 @@ namespace play { bool buffer_was_closed (uint channel, FrameID frame) { - diagn::Block* block = accessSequence(channel) - .accessEmittedBuffer(frame); + diagn::Block const *block = accessSequence(channel) + .accessEmittedBuffer(frame); return block && block->was_closed(); } @@ -376,8 +417,8 @@ namespace play { bool emitted (uint channel, FrameID frame) { - diagn::Block* block = accessSequence(channel) - .accessEmittedBuffer(frame); + diagn::Block const *block = accessSequence(channel) + .accessEmittedBuffer(frame); return block && block->was_used(); }