switch OutputSlot to use the ScopedCollection

..hehe, makes the code way more sane
This commit is contained in:
Fischlurch 2012-01-06 03:16:22 +01:00
parent e5c42e05e6
commit e41065101a
4 changed files with 102 additions and 47 deletions

View file

@ -404,7 +404,7 @@ namespace lib {
/* === Element access and iteration === */ /* === Element access and iteration === */
I& I&
operator[] (size_t index) operator[] (size_t index) const
{ {
if (index < level_) if (index < level_)
return elements_[index].accessObj(); return elements_[index].accessObj();

View file

@ -75,6 +75,8 @@ namespace meta {
* from the AssetManager, then attach a further * from the AssetManager, then attach a further
* smart-ptr-to-Quantiser to that, which then can be * smart-ptr-to-Quantiser to that, which then can be
* published via the \link advice.hpp "advice system"\endlink * 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 inline PGrid
publishWrapped (TimeGrid& newGrid) publishWrapped (TimeGrid& newGrid)

View file

@ -41,17 +41,19 @@
#include "lib/error.hpp" #include "lib/error.hpp"
#include "proc/play/output-slot.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/handle.hpp"
//#include "lib/time/timevalue.hpp" //#include "lib/time/timevalue.hpp"
//#include "proc/engine/buffer-provider.hpp" //#include "proc/engine/buffer-provider.hpp"
//#include "proc/play/timings.hpp" //#include "proc/play/timings.hpp"
#include "lib/iter-source.hpp"
#include "lib/iter-adapter-stl.hpp"
//#include "lib/sync.hpp" //#include "lib/sync.hpp"
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
//#include <string> //#include <string>
#include <tr1/functional>
#include <vector> #include <vector>
//#include <tr1/memory> //#include <tr1/memory>
@ -66,6 +68,8 @@ namespace play {
using lib::transform; using lib::transform;
using lib::iter_stl::eachElm; using lib::iter_stl::eachElm;
using std::tr1::placeholders::_1;
using std::tr1::bind;
using std::vector; using std::vector;
//using std::tr1::shared_ptr; //using std::tr1::shared_ptr;
using boost::scoped_ptr; using boost::scoped_ptr;
@ -92,6 +96,7 @@ namespace play {
* implementation; yet it may as well be called from a separate * implementation; yet it may as well be called from a separate
* service thread or some kind of callback. * service thread or some kind of callback.
* @note the meaning of FrameID is implementation defined. * @note the meaning of FrameID is implementation defined.
* @note typically the concrete connection is noncopyable
*/ */
class OutputSlot::Connection class OutputSlot::Connection
{ {
@ -121,6 +126,8 @@ namespace play {
{ {
public: public:
virtual ~ConnectionState() { } virtual ~ConnectionState() { }
virtual Connection& access (uint) const =0;
}; };
@ -143,11 +150,12 @@ namespace play {
template<class CON> template<class CON>
class ConnectionStateManager class ConnectionStateManager
: public OutputSlot::ConnectionState : public OutputSlot::ConnectionState
, public vector<CON>
{ {
typedef vector<CON> Connections; typedef lib::ScopedCollection<CON> Connections;
typedef OutputSlot::OpenedSinks OpenedSinks; typedef OutputSlot::OpenedSinks OpenedSinks;
Connections connections_;
/* == Allocation Interface == */ /* == Allocation Interface == */
@ -155,7 +163,7 @@ namespace play {
getOpenedSinks() getOpenedSinks()
{ {
REQUIRE (this->isActive()); REQUIRE (this->isActive());
return transform (eachElm(*this), connectOutputSink); return transform (eachElm(connections_), connectOutputSink);
} }
Timings Timings
@ -167,25 +175,29 @@ namespace play {
bool bool
isActive() const isActive() const
{ {
return 0 < Connections::size(); return 0 < connections_.size();
}
CON&
access (uint chanNr) const
{
return connections_[chanNr];
} }
protected: /* == API for OutputSlot-Impl == */ protected: /* == API for OutputSlot-Impl == */
typedef typename Connections::ElementHolder& ConnectionStorage;
/** factory function to build the actual /** factory function to build the actual
* connection handling objects per channel */ * connection handling objects per channel */
virtual CON buildConnection() =0; virtual void buildConnection(ConnectionStorage) =0;
void
init (uint numChannels)
{
for (uint i=0; i<numChannels; ++i)
push_back(buildConnection());
}
ConnectionStateManager() { } ConnectionStateManager(uint numChannels)
: connections_( numChannels
, bind (&ConnectionStateManager::buildConnection, this, _1 ))
{ }
public: public:
virtual virtual

View file

@ -41,6 +41,8 @@
#include "lib/time/timevalue.hpp" #include "lib/time/timevalue.hpp"
#include "lib/scoped-ptrvect.hpp" #include "lib/scoped-ptrvect.hpp"
#include "lib/iter-source.hpp" #include "lib/iter-source.hpp"
#include "lib/advice.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp" #include "lib/util.hpp"
#include "proc/engine/testframe.hpp" #include "proc/engine/testframe.hpp"
//#include "lib/sync.hpp" //#include "lib/sync.hpp"
@ -57,6 +59,8 @@ namespace proc {
namespace play { namespace play {
//using std::string; //using std::string;
using lib::Symbol;
using util::unConst;
using util::contains; using util::contains;
using lib::time::FrameRate; using lib::time::FrameRate;
using proc::asset::meta::PGrid; using proc::asset::meta::PGrid;
@ -70,6 +74,24 @@ namespace play {
using std::tr1::shared_ptr; using std::tr1::shared_ptr;
//using boost::scoped_ptr; //using boost::scoped_ptr;
namespace { // diagnostics & internals....
inline PGrid
getTestTimeGrid()
{
Symbol gridID("DiagnosticOutputSlot-buffer-grid");
lib::advice::Request<PGrid> 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, * Diagnostic output connection for a single channel,
* allowing to track generated frames and verify * allowing to track generated frames and verify
@ -77,17 +99,20 @@ namespace play {
*/ */
class TrackingInMemoryBlockSequence class TrackingInMemoryBlockSequence
: public OutputSlot::Connection : public OutputSlot::Connection
, boost::noncopyable
{ {
typedef std::tr1::unordered_set<FrameID> FrameTrackingInfo; typedef std::tr1::unordered_set<FrameID> FrameTrackingInfo;
shared_ptr<TrackingHeapBlockProvider> buffProvider_; TrackingHeapBlockProvider buffProvider_;
BufferDescriptor bufferType_; BufferDescriptor bufferType_;
FrameTrackingInfo frameTrackingIndex_; FrameTrackingInfo frameTrackingIndex_;
PGrid frameGrid_; PGrid frameGrid_;
bool closed_;
BuffHandle BuffHandle
trackFrame (FrameID frameNr, BuffHandle const& newBuffer) trackFrame (FrameID frameNr, BuffHandle const& newBuffer)
@ -115,8 +140,9 @@ namespace play {
BuffHandle BuffHandle
claimBufferFor(FrameID frameNr) claimBufferFor(FrameID frameNr)
{ {
REQUIRE (!closed_);
return trackFrame (frameNr, return trackFrame (frameNr,
buffProvider_->lockBuffer (bufferType_)); buffProvider_.lockBuffer (bufferType_));
} }
@ -132,34 +158,38 @@ namespace play {
void void
transfer (BuffHandle const& filledBuffer) transfer (BuffHandle const& filledBuffer)
{ {
REQUIRE (!closed_);
pushout (filledBuffer); pushout (filledBuffer);
} }
void void
pushout (BuffHandle const& data4output) pushout (BuffHandle const& data4output)
{ {
buffProvider_->emitBuffer (data4output); REQUIRE (!closed_);
buffProvider_->releaseBuffer(data4output); buffProvider_.emitBuffer (data4output);
buffProvider_.releaseBuffer(data4output);
} }
void void
discard (BuffHandle const& superseededData) discard (BuffHandle const& superseededData)
{ {
buffProvider_->releaseBuffer (superseededData); REQUIRE (!closed_);
buffProvider_.releaseBuffer (superseededData);
} }
void void
shutDown () shutDown ()
{ {
buffProvider_.reset(); closed_ = true;
} }
public: public:
TrackingInMemoryBlockSequence() TrackingInMemoryBlockSequence()
: buffProvider_(new TrackingHeapBlockProvider()) : buffProvider_()
, bufferType_(buffProvider_->getDescriptor<TestFrame>()) , bufferType_(buffProvider_.getDescriptor<TestFrame>())
, frameTrackingIndex_() , 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"); INFO (engine_dbg, "building in-memory diagnostic output sequence");
} }
@ -173,22 +203,20 @@ namespace play {
/* === Diagnostic API === */ /* === Diagnostic API === */
TestFrame* TestFrame const *
accessEmittedFrame (uint frameNr) const accessEmittedFrame (uint frameNr) const
{ {
REQUIRE (buffProvider_); if (frameNr <= buffProvider_.emittedCnt())
if (frameNr <= buffProvider_->emittedCnt()) return & accessFrame(frameNr);
return &buffProvider_->accessAs<TestFrame> (frameNr);
else else
return 0; ////////////////////////////////TICKET #856 return 0; ////////////////////////////////TICKET #856
} }
diagn::Block* diagn::Block const *
accessEmittedBuffer (uint bufferNr) const accessEmittedBuffer (uint bufferNr) const
{ {
REQUIRE (buffProvider_); if (bufferNr <= buffProvider_.emittedCnt())
if (bufferNr <= buffProvider_->emittedCnt()) return & accessBlock(bufferNr);
return & buffProvider_->access_emitted (bufferNr);
else else
return 0; return 0;
} }
@ -196,9 +224,21 @@ namespace play {
bool bool
wasAllocated (uint frameNr) const wasAllocated (uint frameNr) const
{ {
REQUIRE (buffProvider_);
return contains (frameTrackingIndex_, frameNr); return contains (frameTrackingIndex_, frameNr);
} }
private:
TestFrame const&
accessFrame (uint frameNr) const
{
return unConst(this)->buffProvider_.accessAs<TestFrame> (frameNr);
}
diagn::Block const&
accessBlock (uint bufferNr) const
{
return unConst(this)->buffProvider_.access_emitted (bufferNr);
}
}; };
@ -210,17 +250,18 @@ namespace play {
class SimulatedOutputSequences class SimulatedOutputSequences
: public ConnectionStateManager<TrackingInMemoryBlockSequence> : public ConnectionStateManager<TrackingInMemoryBlockSequence>
{ {
TrackingInMemoryBlockSequence typedef ConnectionStateManager<TrackingInMemoryBlockSequence> _Base;
buildConnection()
void
buildConnection(ConnectionStorage storage)
{ {
return TrackingInMemoryBlockSequence(); storage.create<TrackingInMemoryBlockSequence>();
} }
public: public:
SimulatedOutputSequences (uint numChannels) SimulatedOutputSequences (uint numChannels)
{ : _Base(numChannels)
init (numChannels); { }
}
}; };
@ -276,7 +317,7 @@ namespace play {
{ {
REQUIRE (!isFree(), "diagnostic OutputSlot not (yet) connected"); REQUIRE (!isFree(), "diagnostic OutputSlot not (yet) connected");
REQUIRE (channel <= getOutputChannelCount()); REQUIRE (channel <= getOutputChannelCount());
return static_cast<SimulatedOutputSequences&> (*state_).at(channel); return static_cast<TrackingInMemoryBlockSequence&> (state_->access (channel));
} }
@ -307,7 +348,7 @@ namespace play {
* the emitted Data as a sequence of TestFrame objects. * the emitted Data as a sequence of TestFrame objects.
*/ */
class OutputFramesLog class OutputFramesLog
: public lib::IterSource<TestFrame> : public lib::IterSource<const TestFrame>
, boost::noncopyable , boost::noncopyable
{ {
TrackingInMemoryBlockSequence const& outSeq_; TrackingInMemoryBlockSequence const& outSeq_;
@ -366,8 +407,8 @@ namespace play {
bool bool
buffer_was_closed (uint channel, FrameID frame) buffer_was_closed (uint channel, FrameID frame)
{ {
diagn::Block* block = accessSequence(channel) diagn::Block const *block = accessSequence(channel)
.accessEmittedBuffer(frame); .accessEmittedBuffer(frame);
return block return block
&& block->was_closed(); && block->was_closed();
} }
@ -376,8 +417,8 @@ namespace play {
bool bool
emitted (uint channel, FrameID frame) emitted (uint channel, FrameID frame)
{ {
diagn::Block* block = accessSequence(channel) diagn::Block const *block = accessSequence(channel)
.accessEmittedBuffer(frame); .accessEmittedBuffer(frame);
return block return block
&& block->was_used(); && block->was_used();
} }