Clang(#928): refactor OutputSlot implementation to resolve a scoping problem
Clang is more insistent when it comes to enforcing 'protected' visibility. Since in this case the basic design can be considered sane and optimal, the only (and obvious) solution is to nest the PIMPL into a default base class for implementation; this mirrors the structure of the interface.
This commit is contained in:
parent
4ea20f0e74
commit
cb80d4001a
3 changed files with 56 additions and 36 deletions
|
|
@ -92,7 +92,7 @@ namespace lib {
|
|||
*
|
||||
* All child objects reside in a common chunk of storage
|
||||
* and are owned and managed by this collection holder.
|
||||
* Array style access and iteration.
|
||||
* Array style access and iteration is provided.
|
||||
*/
|
||||
template
|
||||
< class I ///< the nominal Base/Interface class for a family of types
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ namespace play {
|
|||
virtual void discard (BuffHandle const&) =0;
|
||||
virtual void shutDown () =0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extension point for Implementation.
|
||||
|
|
@ -131,7 +131,22 @@ namespace play {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
|
||||
/* ===== Building blocks for OutputSlot implementation ===== */
|
||||
|
||||
/** Base for OutputSlot standard implementation */
|
||||
class OutputSlotImplBase
|
||||
: public OutputSlot
|
||||
{
|
||||
protected:
|
||||
template<class CON>
|
||||
class ConnectionManager;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Maintaining a list of active connections.
|
||||
* Base class for the typical implementation approach.
|
||||
* Using this class is \em not mandatory. But obviously,
|
||||
* we'd get to manage a selection of Connection objects
|
||||
|
|
@ -148,7 +163,7 @@ namespace play {
|
|||
* manages a collection of active Connection subclass objects.
|
||||
*/
|
||||
template<class CON>
|
||||
class ConnectionStateManager
|
||||
class OutputSlotImplBase::ConnectionManager
|
||||
: public OutputSlot::ConnectionState
|
||||
{
|
||||
typedef lib::ScopedCollection<CON> Connections;
|
||||
|
|
@ -172,7 +187,7 @@ namespace play {
|
|||
{
|
||||
UNIMPLEMENTED ("find out about timing constraints"); //////////////////////////TICKET #831
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
isActive() const
|
||||
{
|
||||
|
|
@ -191,7 +206,7 @@ namespace play {
|
|||
init() ///< derived classes need to invoke this to build the actual connections
|
||||
{
|
||||
//////////////////////////TICKET #878 really build all at once? or on demand?
|
||||
connections_.populate_by (&ConnectionStateManager::buildConnection, this);
|
||||
connections_.populate_by (&ConnectionManager::buildConnection, this);
|
||||
}
|
||||
|
||||
typedef typename Connections::ElementHolder& ConnectionStorage;
|
||||
|
|
@ -201,13 +216,13 @@ namespace play {
|
|||
virtual void buildConnection(ConnectionStorage) =0;
|
||||
|
||||
|
||||
ConnectionStateManager(uint numChannels)
|
||||
ConnectionManager(uint numChannels)
|
||||
: connections_(numChannels)
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual
|
||||
~ConnectionStateManager()
|
||||
~ConnectionManager()
|
||||
{ }
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -254,33 +254,12 @@ namespace play {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Special diagnostic connection state implementation,
|
||||
* establishing diagnostic output connections for each channel,
|
||||
* thus allowing to verify the handling of individual buffers
|
||||
*/
|
||||
class SimulatedOutputSequences
|
||||
: public ConnectionStateManager<TrackingInMemoryBlockSequence>
|
||||
{
|
||||
typedef ConnectionStateManager<TrackingInMemoryBlockSequence> _Base;
|
||||
|
||||
void
|
||||
buildConnection(ConnectionStorage storage)
|
||||
{
|
||||
storage.create<TrackingInMemoryBlockSequence>();
|
||||
}
|
||||
|
||||
public:
|
||||
SimulatedOutputSequences (uint numChannels)
|
||||
: _Base(numChannels)
|
||||
{
|
||||
init();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Helper for unit tests: Mock output sink.
|
||||
|
|
@ -296,7 +275,7 @@ namespace play {
|
|||
* remains in memory until shutdown of the current executable
|
||||
*/
|
||||
class DiagnosticOutputSlot
|
||||
: public OutputSlot
|
||||
: public OutputSlotImplBase
|
||||
{
|
||||
|
||||
static const uint MAX_CHANNELS = 5;
|
||||
|
|
@ -311,6 +290,32 @@ namespace play {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special diagnostic connection state implementation,
|
||||
* establishing diagnostic output connections for each channel,
|
||||
* thus allowing to verify the handling of individual buffers
|
||||
*/
|
||||
class SimulatedOutputSequences
|
||||
: public ConnectionManager<TrackingInMemoryBlockSequence>
|
||||
{
|
||||
typedef ConnectionManager<TrackingInMemoryBlockSequence> _Base;
|
||||
|
||||
void
|
||||
buildConnection(ConnectionStorage storage)
|
||||
{
|
||||
storage.create<TrackingInMemoryBlockSequence>();
|
||||
}
|
||||
|
||||
public:
|
||||
SimulatedOutputSequences (uint numChannels)
|
||||
: _Base(numChannels)
|
||||
{
|
||||
init();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** hook into the OutputSlot frontend */
|
||||
ConnectionState*
|
||||
buildState()
|
||||
|
|
|
|||
Loading…
Reference in a new issue