switch OutputSlot to use the ScopedCollection
..hehe, makes the code way more sane
This commit is contained in:
parent
e5c42e05e6
commit
e41065101a
4 changed files with 102 additions and 47 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 <boost/noncopyable.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
//#include <string>
|
||||
#include <tr1/functional>
|
||||
#include <vector>
|
||||
//#include <tr1/memory>
|
||||
|
||||
|
|
@ -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 CON>
|
||||
class ConnectionStateManager
|
||||
: public OutputSlot::ConnectionState
|
||||
, public vector<CON>
|
||||
{
|
||||
typedef vector<CON> Connections;
|
||||
typedef lib::ScopedCollection<CON> 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<numChannels; ++i)
|
||||
push_back(buildConnection());
|
||||
}
|
||||
virtual void buildConnection(ConnectionStorage) =0;
|
||||
|
||||
|
||||
ConnectionStateManager() { }
|
||||
ConnectionStateManager(uint numChannels)
|
||||
: connections_( numChannels
|
||||
, bind (&ConnectionStateManager::buildConnection, this, _1 ))
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/scoped-ptrvect.hpp"
|
||||
#include "lib/iter-source.hpp"
|
||||
#include "lib/advice.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "proc/engine/testframe.hpp"
|
||||
//#include "lib/sync.hpp"
|
||||
|
|
@ -57,6 +59,8 @@ namespace proc {
|
|||
namespace play {
|
||||
|
||||
//using std::string;
|
||||
using lib::Symbol;
|
||||
using util::unConst;
|
||||
using util::contains;
|
||||
using lib::time::FrameRate;
|
||||
using proc::asset::meta::PGrid;
|
||||
|
|
@ -70,6 +74,24 @@ namespace play {
|
|||
using std::tr1::shared_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,
|
||||
* 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<FrameID> FrameTrackingInfo;
|
||||
|
||||
|
||||
shared_ptr<TrackingHeapBlockProvider> 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<TestFrame>())
|
||||
: buffProvider_()
|
||||
, bufferType_(buffProvider_.getDescriptor<TestFrame>())
|
||||
, 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<TestFrame> (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<TestFrame> (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>
|
||||
{
|
||||
TrackingInMemoryBlockSequence
|
||||
buildConnection()
|
||||
typedef ConnectionStateManager<TrackingInMemoryBlockSequence> _Base;
|
||||
|
||||
void
|
||||
buildConnection(ConnectionStorage storage)
|
||||
{
|
||||
return TrackingInMemoryBlockSequence();
|
||||
storage.create<TrackingInMemoryBlockSequence>();
|
||||
}
|
||||
|
||||
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<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.
|
||||
*/
|
||||
class OutputFramesLog
|
||||
: public lib::IterSource<TestFrame>
|
||||
: public lib::IterSource<const TestFrame>
|
||||
, 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();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue