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 === */
|
/* === 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();
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,7 +407,7 @@ 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,7 +417,7 @@ 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();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue