Audacity  3.0.3
Classes | Public Types | Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy > Class Template Reference

Utility to register hooks into a host class that attach client data. More...

#include <ClientData.h>

Inheritance diagram for ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >:
[legend]
Collaboration diagram for ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >:
[legend]

Classes

class  RegisteredFactory
 Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrieval key. More...
 

Public Types

using DataType = ClientData
 
using DataPointer = Pointer< ClientData >
 
using DataFactory = std::function< DataPointer(Host &) >
 Type of function from which RegisteredFactory is constructed; it builds attachments. More...
 

Public Member Functions

 ~Site ()
 
 Site ()
 
 Site (const Site &other)
 
Siteoperator= (const Site &other)
 
 Site (Site &&other)
 
Siteoperator= (Site &&other)
 
size_t size () const
 How many attachment pointers are in the Site. More...
 
Retrieval and reassignment of attachments
template<typename Subclass = ClientData>
Subclass & Get (const RegisteredFactory &key)
 Get reference to an attachment, creating on demand if not present, down-cast it to Subclass. More...
 
template<typename Subclass = const ClientData>
auto Get (const RegisteredFactory &key) const -> typename std::enable_if< std::is_const< Subclass >::value, Subclass & >::type
 Get reference to an attachment, creating on demand if not present, down-cast it to Subclass. More...
 
template<typename Subclass = ClientData>
Subclass * Find (const RegisteredFactory &key)
 Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand. More...
 
template<typename Subclass = const ClientData>
auto Find (const RegisteredFactory &key) const -> typename std::enable_if< std::is_const< Subclass >::value, Subclass * >::type
 Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand. More...
 
template<typename ReplacementPointer >
void Assign (const RegisteredFactory &key, ReplacementPointer &&replacement)
 Reassign Site's pointer to ClientData. More...
 

Static Public Member Functions

static size_t slots ()
 How many static factories have been registered with this specialization of Site. More...
 

Protected Member Functions

member functions for use by @b Host
template<typename Function >
void ForEach (const Function &function)
 Invoke function on each ClientData object that has been created in this. More...
 
template<typename Function >
void ForEach (const Function &function) const
 Invoke function on each ClientData object that has been created in this. More...
 
template<typename Function >
ClientData * FindIf (const Function &function)
 Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr. More...
 
template<typename Function >
const ClientData * FindIf (const Function &function) const
 Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr. More...
 
void BuildAll ()
 For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it. More...
 

Private Types

using DataFactories = Lockable< std::vector< DataFactory >, RegistryLockingPolicy >
 
using DataContainer = Lockable< Copyable< std::vector< DataPointer >, ObjectCopyingPolicy >, ObjectLockingPolicy >
 

Private Member Functions

template<typename Subclass >
Subclass & DoGet (Locked< DataContainer > &data, const RegisteredFactory &key)
 
template<typename Subclass >
Subclass * DoFind (Locked< DataContainer > &data, const RegisteredFactory &key)
 
Locked< DataContainerGetData ()
 
Locked< const DataContainerGetData () const
 
DataPointerBuild (Locked< DataContainer > &, typename DataContainer::iterator iter, size_t index)
 

Static Private Member Functions

static Locked< DataFactoriesGetFactories ()
 
static void EnsureIndex (Locked< DataContainer > &data, size_t index)
 
static DataContainer::iterator GetIterator (Locked< DataContainer > &data, size_t index)
 

Private Attributes

decltype(Dereferenceable(std::declval< DataPointer & >())) Slot (Locked< DataContainer > &data, const RegisteredFactory &key, bool create)
 
DataContainer mData
 Container of pointers returned by factories, per instance of Host class. More...
 

Detailed Description

template<typename Host, typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
class ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >

Utility to register hooks into a host class that attach client data.

This allows the host object to be the root of an ownership tree of sub-objects at run-time, but inverting the compile-time dependency among implementation files: The host's implementation is in low-level files, and cyclic file dependencies are avoided. The set of client objects attached to each host object is not fixed in the definition of the host class, but instead a system of registration of factories of client objects lets it be open-ended.

Besides mere storage and retrieval, this can also implement the observer pattern, in which the host pushes notifications to some virtual function defined in each attached item.

Host side usage pattern
class Host;
class AbstractClientData // Abstract base class for attached data
{
virtual ~AbstractClientData(); // minimum for memory management
// optional extra observer protocols
virtual void NotificationMethod(
// maybe host passes reference to self, maybe not
// Host &host
) = 0;
};
class Host
: public ClientData::Site< Host, AbstractClientData >
// That inheritance is a case of CRTP
// (the "curiously recurring template pattern")
// in which the base class takes the derived class as a template argument
{
public:
Host()
{
// If using an Observer protocol, force early creation of all client
// data:
}
void NotifyAll()
{
// Visit all non-null objects
ForEach( []( AbstractClientData &data ){
data.NotificationMethod(
// *this
);
} );
}
}
Client side usage pattern
class MyClientData : public AbstractClientData
{
public:
MyClientData( Host &host )
{
// ... use host, maybe keep a back pointer to it, maybe not,
// depending how Host declares NotificationMethod ...
// ... Maybe Host too is an abstract class and we invoke some
// virtual function of it ...
}
void NotificationMethod(
// Host &host
) override
{
// ... Observer actions
// (If there is more than one separately compiled module using this
// protocol, beware that the sequence of notifications is unspecified)
}
private:
int mExtraStuff;
};
// Registration of a factory at static initialization time, to be called
// when a Host uses BuildAll, or else lazily when client code uses
// Host::Get()
static const Host::RegisteredFactory key{
[]( Host &host ){ return std::make_unique< MyClientData >( host ); }
};
// Use of that key at other times, not dependent on notifications from
// the core
void DoSomething( Host &host )
{
// This may force lazy construction of MyClientData, always returning
// an object (or else throwing)
auto &data = host.Get< MyClientData >( key );
auto val = pData->mExtraStuff;
// ...
}
void DoAnotherThing( Host &host )
{
// Does not force lazy construction of MyClientData
auto *pData = host.Find< MyClientData >( key );
if ( pData ) {
auto val = data.mExtraStuff;
// ...
}
}
void DoYetAnotherThing( Host &host )
{
// Reassign the pointer in this client's slot
host.Assign( key, MyReplacementObject( host ) );
}
Lazy or eager construction

If the client only needs retrieval, it might need construction of data only on demand. But if the host is meant to push notifications to the clients, then the host class is responsible for forcing early building of all ClientData when host is constructed, as in the example above.

Unusual registration sequences

If registration of a factory happens after some host objects are already in existence, their associated client data fail to be created if you rely only on BuildAll in the @B Host constructor. Early deregistration of factories is permitted, in which case any later constructed host objects will carry null pointers in the associated slot, and a small "leak" in the space of per-host slots will persist until the program exits. All such usage is not recommended.

Template Parameters
HostType that derives from this base class; it supports hooks to invoke attached object factories. This is an example of the curiously recurring template pattern
ClientDataCommon base class of attachments; must have a virtual destructor
CopyingPolicyCopyingPolicy value Chooses deep, shallow, or (default) no-op copying of attachments
PointerThe kind of pointer Host will hold to ClientData; default is std::unique_ptr. You might want to use std::shared_ptr, std::weak_ptr, or wxWeakRef instead
ObjectLockingPolicyLockingPolicy value chooses thread safety policy for array of attachments in each Host, default is unsafe
RegistryLockingPolicyLockingPolicy value chooses thread safety policy for the static table of attachment factory functions, default is unsafe

Definition at line 219 of file ClientData.h.

Member Typedef Documentation

◆ DataContainer

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
using ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DataContainer = Lockable< Copyable< std::vector< DataPointer >, ObjectCopyingPolicy >, ObjectLockingPolicy >
private

Definition at line 466 of file ClientData.h.

◆ DataFactories

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
using ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DataFactories = Lockable< std::vector< DataFactory >, RegistryLockingPolicy >
private

Definition at line 464 of file ClientData.h.

◆ DataFactory

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
using ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DataFactory = std::function< DataPointer( Host& ) >

Type of function from which RegisteredFactory is constructed; it builds attachments.

Definition at line 231 of file ClientData.h.

◆ DataPointer

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
using ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DataPointer = Pointer< ClientData >

Definition at line 229 of file ClientData.h.

◆ DataType

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
using ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DataType = ClientData

Definition at line 228 of file ClientData.h.

Constructor & Destructor Documentation

◆ ~Site()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::~Site ( )
inline

Definition at line 222 of file ClientData.h.

223  {
224  static_assert( std::has_virtual_destructor<ClientData>::value,
225  "ClientData::Site requires a data class with a virtual destructor" );
226  }

◆ Site() [1/3]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Site ( )
inline

Definition at line 233 of file ClientData.h.

234  {
235  auto factories = GetFactories();
236  auto size = factories.mObject.size();
237  mData.reserve( size );
238  }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetFactories(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::mData, and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::size().

Here is the call graph for this function:

◆ Site() [2/3]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Site ( const Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy > &  other)
inline

Definition at line 239 of file ClientData.h.

240  : mData( other.mData )
241  { }

◆ Site() [3/3]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Site ( Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy > &&  other)
inline

Definition at line 244 of file ClientData.h.

245  : mData( std::move(other.mData) )
246  { }

Member Function Documentation

◆ Assign()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename ReplacementPointer >
void ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Assign ( const RegisteredFactory key,
ReplacementPointer &&  replacement 
)
inline

Reassign Site's pointer to ClientData.

If ObjectLockingPolicy isn't default, then reassignments are serialized.

Template Parameters
ReplacementPointerPointer<Subclass> where Subclass derives ClientData
Parameters
keyReference to static object created in client code
replacementA temporary or std::move'd pointer

Definition at line 355 of file ClientData.h.

359  {
360  auto index = key.mIndex;
361  auto data = GetData();
362  EnsureIndex( data, index );
363  auto iter = GetIterator( data, index );
364  // Copy or move as appropriate:
365  *iter = std::forward< ReplacementPointer >( replacement );
366  }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::EnsureIndex(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetIterator(), key, and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::RegisteredFactory::mIndex.

Here is the call graph for this function:

◆ Build()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
DataPointer& ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Build ( Locked< DataContainer > &  ,
typename DataContainer::iterator  iter,
size_t  index 
)
inlineprivate

Definition at line 543 of file ClientData.h.

545  {
546  // If there is no object at index, then invoke the factory, else do
547  // nothing.
548  // The factory may be null or may return null, in which case do nothing.
549  auto &result = *iter;
550  if (!Dereferenceable(result)) {
551  // creation on demand
552  auto factories = GetFactories();
553  auto &factory = factories.mObject[index];
554  result = factory
555  ? factory( static_cast< Host& >( *this ) )
556  : DataPointer{};
557  }
558  return result;
559  }

References ClientData::Dereferenceable(), factory, and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetFactories().

Referenced by ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::BuildAll().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ BuildAll()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
void ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::BuildAll ( )
inlineprotected

For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it.

Definition at line 441 of file ClientData.h.

442  {
443  // Note that we cannot call this function in the Site constructor as we
444  // might wish, because we pass *this to the factories, but this is not yet
445  // fully constructed as the ultimate derived class. So delayed calls to
446  // this function are needed.
447  size_t size;
448  {
449  auto factories = GetFactories();
450  size = factories.mObject.size();
451  // Release lock on factories before getting one on data -- otherwise
452  // there would be a deadlock possibility inside Ensure
453  }
454  auto data = GetData();
455  EnsureIndex( data, size - 1 );
456  auto iter = GetIterator( data, 0 );
457  for ( size_t ii = 0; ii < size; ++ii, ++iter )
458  static_cast< void >( Build( data, iter, ii ) );
459  }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Build(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::EnsureIndex(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetFactories(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetIterator(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::size().

Referenced by AudacityProject::AudacityProject(), and WaveTrackView::BuildSubViews().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoFind()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Subclass >
Subclass* ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DoFind ( Locked< DataContainer > &  data,
const RegisteredFactory key 
)
inlineprivate

Definition at line 494 of file ClientData.h.

495  {
496  const auto &d = Slot( data, key, false );
497  if (!d)
498  return nullptr;
499  else
500  return static_cast< Subclass* >( &*d );
501  }

References key, and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Slot.

◆ DoGet()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Subclass >
Subclass& ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DoGet ( Locked< DataContainer > &  data,
const RegisteredFactory key 
)
inlineprivate

Definition at line 483 of file ClientData.h.

484  {
485  const auto &d = Slot( data, key, true );
486  if (!d)
487  // Oops, a factory was deregistered too soon, or returned a null, or
488  // the pointer was reassigned null
490  return static_cast< Subclass& >( *d );
491  }

References key, ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Slot, and THROW_INCONSISTENCY_EXCEPTION.

◆ EnsureIndex()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
static void ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::EnsureIndex ( Locked< DataContainer > &  data,
size_t  index 
)
inlinestaticprivate

Definition at line 524 of file ClientData.h.

525  {
526  if (data.mObject.size() <= index)
527  data.mObject.resize(index + 1);
528  }

References ClientData::Locked< Lockable >::mObject.

Referenced by ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Assign(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::BuildAll().

Here is the caller graph for this function:

◆ Find() [1/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Subclass = ClientData>
Subclass* ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Find ( const RegisteredFactory key)
inline

Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand.

(Lifetime of the object may depend on the host's lifetime and also on the client's use of Assign(). Site is not responsible for guarantees.)

Template Parameters
SubclassExpected actual type of attachment, assumed to be correct
Parameters
keyReference to static object created in client code

Definition at line 333 of file ClientData.h.

334  {
335  auto data = GetData();
336  return DoFind< Subclass >( data, key );
337  }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData(), and key.

Referenced by AppendItem(), TrackPanelResizeHandle::Cancel(), anonymous_namespace{TrackMenus.cpp}::DoMixAndRender(), anonymous_namespace{TransportMenus.cpp}::DoMoveToLabel(), TrackUtilities::DoRemoveTracks(), and TrackPanelResizeHandle::Drag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Find() [2/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Subclass = const ClientData>
auto ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Find ( const RegisteredFactory key) const -> typename std::enable_if< std::is_const< Subclass >::value, Subclass * >::type
inline

Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand.

(Lifetime of the object may depend on the host's lifetime and also on the client's use of Assign(). Site is not responsible for guarantees.)

Template Parameters
SubclassExpected actual type of attachment, assumed to be correct
Parameters
keyReference to static object created in client code

const overload returns pointers to const only.

Definition at line 342 of file ClientData.h.

344  {
345  auto data = GetData();
346  return DoFind< Subclass >( data, key );
347  }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData(), and key.

Here is the call graph for this function:

◆ FindIf() [1/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Function >
ClientData* ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::FindIf ( const Function &  function)
inlineprotected

Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr.

Beware that the sequence of visitation is not specified.

Template Parameters
Functiontakes reference to ClientData, returns value convertible to bool
Parameters
functionof type Function

Definition at line 412 of file ClientData.h.

413  {
414  auto data = GetData();
415  for( auto &pObject : data.mObject ) {
416  const auto &ptr = Dereferenceable(pObject);
417  if ( ptr && function ( *ptr ) )
418  return &*ptr;
419  }
420  return nullptr;
421  }

References ClientData::Dereferenceable(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData().

Referenced by WaveTrackView::ToggleSubView().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindIf() [2/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Function >
const ClientData* ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::FindIf ( const Function &  function) const
inlineprotected

Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr.

Beware that the sequence of visitation is not specified.

Template Parameters
Functiontakes reference to ClientData, returns value convertible to bool
Parameters
functionof type Function

const overload only compiles with a function callable with a const reference to ClientData.

Definition at line 426 of file ClientData.h.

427  {
428  auto data = GetData();
429  for( auto &pObject : data.mObject ) {
430  const auto &ptr = Dereferenceable(pObject);
431  if ( ptr ) {
432  const auto &c_ref = *ptr;
433  if ( function( c_ref ) )
434  return &*c_ref;
435  }
436  }
437  return nullptr;
438  }

References ClientData::Dereferenceable(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData().

Here is the call graph for this function:

◆ ForEach() [1/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Function >
void ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::ForEach ( const Function &  function)
inlineprotected

Invoke function on each ClientData object that has been created in this.

Template Parameters
Functiontakes reference to ClientData, return value is ignored
Parameters
functionof type Function

Definition at line 380 of file ClientData.h.

381  {
382  auto data = GetData();
383  for( auto &pObject : data.mObject ) {
384  const auto &ptr = Dereferenceable(pObject);
385  if ( ptr )
386  function( *ptr );
387  }
388  }

References ClientData::Dereferenceable(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData().

Referenced by WaveTrackView::DoSetDisplay(), WaveTrackView::DoSetMinimized(), WaveTrackView::GetAllSubViews(), WaveTrackView::GetDisplays(), WaveTrackView::GetSubViews(), and WaveTrackView::Reparent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ForEach() [2/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Function >
void ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::ForEach ( const Function &  function) const
inlineprotected

Invoke function on each ClientData object that has been created in this.

Template Parameters
Functiontakes reference to ClientData, return value is ignored
Parameters
functionof type Function

const overload only compiles with a function that takes reference to const ClientData.

Definition at line 393 of file ClientData.h.

394  {
395  auto data = GetData();
396  for( auto &pObject : data.mObject ) {
397  const auto &ptr = Dereferenceable(pObject);
398  if ( ptr ) {
399  const auto &c_ref = *ptr;
400  function( c_ref );
401  }
402  }
403  }

References ClientData::Dereferenceable(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData().

Here is the call graph for this function:

◆ Get() [1/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Subclass = ClientData>
Subclass& ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Get ( const RegisteredFactory key)
inline

Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.

Uses static_cast. Throws on failure to create it. (Lifetime of the object may depend on the host's lifetime and also on the client's use of Assign(). Site is not responsible for guarantees.)

Template Parameters
SubclassExpected actual type of attachment, assumed to be correct
Parameters
keyReference to static object created in client code

Definition at line 309 of file ClientData.h.

310  {
311  auto data = GetData();
312  return DoGet< Subclass >( data, key );
313  }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData(), and key.

Referenced by SetTrackStatusCommand::ApplyInner(), anonymous_namespace{ClipMenus.cpp}::DoClipLeftOrRight(), WaveTrack::GetFloats(), TrackPanel::GetFocusedCell(), LabelTrackView::GetSelectedIndex(), NavigationActions::Handler::OnLastTrack(), WaveTrackMenuTable::OnSwapChannels(), NavigationActions::Handler::OnToggle(), TrackActions::Handler::OnTrackClose(), TrackActions::Handler::OnTrackGain(), TrackActions::Handler::OnTrackGainDec(), TrackActions::Handler::OnTrackGainInc(), TrackActions::Handler::OnTrackMoveBottom(), TrackActions::Handler::OnTrackMoveDown(), TrackActions::Handler::OnTrackMoveTop(), TrackActions::Handler::OnTrackMoveUp(), TrackActions::Handler::OnTrackMute(), TrackActions::Handler::OnTrackPan(), TrackActions::Handler::OnTrackPanLeft(), TrackActions::Handler::OnTrackPanRight(), TrackActions::Handler::OnTrackSolo(), GetInfoCommand::SendTracks(), MuteButtonHandle::Tip(), SoloButtonHandle::Tip(), MenuButtonHandle::Tip(), and CloseButtonHandle::Tip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Get() [2/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
template<typename Subclass = const ClientData>
auto ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Get ( const RegisteredFactory key) const -> typename std::enable_if< std::is_const< Subclass >::value, Subclass & >::type
inline

Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.

Uses static_cast. Throws on failure to create it. (Lifetime of the object may depend on the host's lifetime and also on the client's use of Assign(). Site is not responsible for guarantees.)

Template Parameters
SubclassExpected actual type of attachment, assumed to be correct
Parameters
keyReference to static object created in client code

const overload returns const references only.

Definition at line 318 of file ClientData.h.

320  {
321  auto data = GetData();
322  return DoGet< Subclass >( data, key );
323  }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData(), and key.

Here is the call graph for this function:

◆ GetData() [1/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
Locked<DataContainer> ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData ( )
inlineprivate

◆ GetData() [2/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
Locked<const DataContainer> ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetData ( ) const
inlineprivate

Definition at line 519 of file ClientData.h.

520  {
521  return Locked< const DataContainer >{ mData };
522  }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::mData.

◆ GetFactories()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
static Locked< DataFactories > ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetFactories ( )
inlinestaticprivate

Definition at line 503 of file ClientData.h.

504  {
505  // C++11 does not need extra thread synch for static initialization
506  // Note that linker eliminates duplicates of this function
507  static DataFactories factories;
508 
509  // But give back a scoped lock to the user of this function, in case
510  // there is contention to resize the vector
511  return Locked< DataFactories >{ factories };
512  }

Referenced by ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Build(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::BuildAll(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::RegisteredFactory::RegisteredFactory(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Site(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::slots(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::RegisteredFactory::~RegisteredFactory().

Here is the caller graph for this function:

◆ GetIterator()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
static DataContainer::iterator ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetIterator ( Locked< DataContainer > &  data,
size_t  index 
)
inlinestaticprivate

Definition at line 531 of file ClientData.h.

532  {
533  // This function might help generalize Site with different kinds of
534  // containers for pointers to ClientData that are not random-access.
535  // Perhaps non-relocation of elements will be needed.
536  // Perhaps another template-template parameter could vary the kind of
537  // container.
538  auto result = data.mObject.begin();
539  std::advance( result, index );
540  return result;
541  }

References ClientData::Locked< Lockable >::mObject.

Referenced by ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Assign(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::BuildAll().

Here is the caller graph for this function:

◆ operator=() [1/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
Site& ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::operator= ( const Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy > &  other)
inline

◆ operator=() [2/2]

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
Site& ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::operator= ( Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy > &&  other)
inline

Definition at line 247 of file ClientData.h.

248  { mData = std::move(other.mData); return *this; }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::mData.

◆ size()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
size_t ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::size ( ) const
inline

◆ slots()

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
static size_t ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::slots ( )
inlinestatic

How many static factories have been registered with this specialization of Site.

Usually agrees with the size() of each site unless some registrations happened later than some Site's construction.

Definition at line 258 of file ClientData.h.

258 { return GetFactories().mObject.size(); }

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::GetFactories().

Referenced by Append().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mData

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
DataContainer ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::mData
private

◆ Slot

template<typename Host , typename ClientData = Base, CopyingPolicy ObjectCopyingPolicy = SkipCopying, template< typename > class Pointer = UniquePtr, LockingPolicy ObjectLockingPolicy = NoLocking, LockingPolicy RegistryLockingPolicy = NoLocking>
decltype( Dereferenceable( std::declval<DataPointer&>() ) ) ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Slot(Locked< DataContainer > &data, const RegisteredFactory &key, bool create)
inlineprivate

Definition at line 473 of file ClientData.h.

474  {
475  auto index = key.mIndex;
476  EnsureIndex( data, index );
477  auto iter = GetIterator( data, index );
478  auto &pointer = create ? Build( data, iter, index ) : *iter;
479  return Dereferenceable( pointer );
480  }

Referenced by ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DoFind(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::DoGet().


The documentation for this class was generated from the following file:
ClientData::Site::GetIterator
static DataContainer::iterator GetIterator(Locked< DataContainer > &data, size_t index)
Definition: ClientData.h:531
ClientData::Site::ForEach
void ForEach(const Function &function)
Invoke function on each ClientData object that has been created in this.
Definition: ClientData.h:380
ClientData::Site::size
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:251
ClientData::Site::RegisteredFactory::mIndex
size_t mIndex
Definition: ClientData.h:294
ClientData::Site::mData
DataContainer mData
Container of pointers returned by factories, per instance of Host class.
Definition: ClientData.h:563
ClientData::Site::EnsureIndex
static void EnsureIndex(Locked< DataContainer > &data, size_t index)
Definition: ClientData.h:524
factory
static RegisteredToolbarFactory factory
Definition: ControlToolBar.cpp:807
ClientData::Site::Slot
decltype(Dereferenceable(std::declval< DataPointer & >())) Slot(Locked< DataContainer > &data, const RegisteredFactory &key, bool create)
Definition: ClientData.h:473
ClientData::Site
Utility to register hooks into a host class that attach client data.
Definition: ClientData.h:220
THROW_INCONSISTENCY_EXCEPTION
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
Definition: InconsistencyException.h:79
ClientData::Site::GetFactories
static Locked< DataFactories > GetFactories()
Definition: ClientData.h:503
ClientData::Site::GetData
Locked< DataContainer > GetData()
Definition: ClientData.h:514
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: CommandManager.cpp:196
ClientData::Site::BuildAll
void BuildAll()
For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it.
Definition: ClientData.h:441
ClientData::Site::Build
DataPointer & Build(Locked< DataContainer > &, typename DataContainer::iterator iter, size_t index)
Definition: ClientData.h:543
ClientData::Site::DataPointer
Pointer< ClientData > DataPointer
Definition: ClientData.h:229
ClientData::Site::DataFactories
Lockable< std::vector< DataFactory >, RegistryLockingPolicy > DataFactories
Definition: ClientData.h:465
ClientData::Dereferenceable
static const Ptr & Dereferenceable(Ptr &p)
Conversion allowing operator * on any Pointer parameter of ClientData::Site.
Definition: ClientDataHelpers.h:48