You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
407 lines
8.9 KiB
407 lines
8.9 KiB
//***************************************************************************
|
|
//
|
|
// Copyright © Microsoft Corporation. All rights reserved.
|
|
//
|
|
// RefPtrCo.h
|
|
//
|
|
// Purpose: definition of TRefPointerCollection template
|
|
//
|
|
//***************************************************************************
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#endif
|
|
|
|
#ifndef __REFPTRCOLLECTION_H__
|
|
#define __REFPTRCOLLECTION_H__
|
|
|
|
#include <chptrarr.h>
|
|
|
|
// Enumeration helpers
|
|
typedef DWORD REFPTRCOLLECTION_POSITION;
|
|
#define REFPTRCOLLECTION_START 0xFFFFFFFF;
|
|
|
|
template <class TYPED_PTR> class TRefPointerCollection : public CThreadBase
|
|
{
|
|
public:
|
|
|
|
// Construction/Destruction
|
|
TRefPointerCollection();
|
|
~TRefPointerCollection();
|
|
TRefPointerCollection(const TRefPointerCollection& trpc);
|
|
|
|
// Allows addition and enumeration of collection
|
|
BOOL Add( TYPED_PTR* ptr );
|
|
|
|
BOOL BeginEnum( REFPTRCOLLECTION_POSITION& pos );
|
|
TYPED_PTR* GetNext( REFPTRCOLLECTION_POSITION& pos );
|
|
void EndEnum( void );
|
|
|
|
void Empty( void );
|
|
int GetSize( void ) const;
|
|
|
|
protected:
|
|
|
|
// Allows easy and quick transference of data (it was =, but
|
|
// because we'll inherit classes off the template, we won't
|
|
// inherit that particular overload (some C++ thingie)
|
|
|
|
const TRefPointerCollection<TYPED_PTR>& Copy( const TRefPointerCollection<TYPED_PTR>& );
|
|
|
|
|
|
private:
|
|
|
|
CHPtrArray m_ptrArray;
|
|
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: TRefPointerCollection::TRefPointerCollection
|
|
//
|
|
// Class Constructor.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
TRefPointerCollection<TYPED_PTR>::TRefPointerCollection( void )
|
|
: CThreadBase(),
|
|
m_ptrArray()
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CRefPointerCollection::~CRefPointerCollection
|
|
//
|
|
// Class Destructor.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
TRefPointerCollection<TYPED_PTR>::~TRefPointerCollection( void )
|
|
{
|
|
Empty();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CRefPointerCollection::CRefPointerCollection
|
|
// Copy constructor
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
template <class TYPED_PTR>
|
|
TRefPointerCollection<TYPED_PTR>::TRefPointerCollection(
|
|
const TRefPointerCollection& trpc)
|
|
{
|
|
Copy(trpc);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: TRefPointerCollection::Add
|
|
//
|
|
// Adds a new referenced pointer to the collection.
|
|
//
|
|
// Inputs: T* ptr - Pointer to add.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: TRUE/FALSE Success/Failure of Add.
|
|
//
|
|
// Comments: AddRefs the pointer, then adds it to the array. We
|
|
// will need Write Access to do this.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
BOOL TRefPointerCollection<TYPED_PTR>::Add( TYPED_PTR* ptr )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
|
|
if ( NULL != ptr )
|
|
{
|
|
// Get write access
|
|
if ( BeginWrite() )
|
|
{
|
|
try
|
|
{
|
|
// If Add succeeds, the pointer will be released when it
|
|
// is removed.
|
|
|
|
ptr->AddRef();
|
|
|
|
if ( m_ptrArray.Add( (void*) ptr ) >= 0 )
|
|
{
|
|
fReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
ptr->Release(); // Add failed, so Release the AddRef
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
EndWrite() ;
|
|
throw;
|
|
}
|
|
|
|
EndWrite(); // Release the BeginWrite()
|
|
}
|
|
}
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: TRefPointerCollection::BeginEnum
|
|
//
|
|
// Gains Read Access to the collection, then returns an appropriate
|
|
// REFPTRCOLLECTION_POSITION to get the first index in the array.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: REFPTRCOLLECTION_POSITION& pos - Position we retrieved.
|
|
//
|
|
// Return: BOOL TRUE/FALSE - Access was granted
|
|
//
|
|
// Comments: We need Read Access to do this. This can effectively
|
|
// lock out other threads.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
BOOL TRefPointerCollection<TYPED_PTR>::BeginEnum( REFPTRCOLLECTION_POSITION& pos )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
|
|
if ( BeginRead() )
|
|
{
|
|
pos = REFPTRCOLLECTION_START;
|
|
fReturn = TRUE;
|
|
}
|
|
|
|
return fReturn;
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: TRefPointerCollection::EndEnum
|
|
//
|
|
// Signals the end of an enumeration.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: BOOL TRUE/FALSE - Access was granted
|
|
//
|
|
// Comments: Ends Read Access granted by calling BeginEnum().
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
void TRefPointerCollection<TYPED_PTR>::EndEnum( void )
|
|
{
|
|
EndRead();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: TRefPointerCollection::GetNext
|
|
//
|
|
// Uses the REFPTRCOLLECTION_POSITION to get the next index in the
|
|
// collection.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: REFPTRCOLLECTION_POSITION& pos - Position we retrieved.
|
|
//
|
|
// Return: T* NULL if failure.
|
|
//
|
|
// Comments: We need Read Access to do this. The pointer is AddRef'd
|
|
// on the way out. User must Release the pointer himself.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
TYPED_PTR* TRefPointerCollection<TYPED_PTR>::GetNext( REFPTRCOLLECTION_POSITION& pos )
|
|
{
|
|
TYPED_PTR* ptr = NULL;
|
|
|
|
if ( BeginRead() )
|
|
{
|
|
if ( ++pos < (DWORD) m_ptrArray.GetSize() )
|
|
{
|
|
ptr = (TYPED_PTR*) m_ptrArray.GetAt( pos );
|
|
|
|
if ( NULL != ptr )
|
|
{
|
|
ptr->AddRef();
|
|
}
|
|
}
|
|
|
|
EndRead();
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: TRefPointerCollection::Empty
|
|
//
|
|
// Empties out the collection, Releasing Pointers as it does do.
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: We need Write Access to do this.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
void TRefPointerCollection<TYPED_PTR>::Empty( void )
|
|
{
|
|
// By default this is an infinite wait, so it best come back
|
|
|
|
BeginWrite();
|
|
|
|
try
|
|
{
|
|
|
|
int nSize = m_ptrArray.GetSize();
|
|
|
|
// Only empty it if it is not empty
|
|
if ( nSize > 0 )
|
|
{
|
|
TYPED_PTR* ptr = NULL;
|
|
|
|
for ( int nCtr = 0; nCtr < nSize; nCtr++ )
|
|
{
|
|
ptr = (TYPED_PTR*) m_ptrArray[nCtr];
|
|
|
|
if ( NULL != ptr )
|
|
{
|
|
ptr->Release(); // AddRef we did when we added it
|
|
}
|
|
}
|
|
|
|
// Now dump the array
|
|
m_ptrArray.RemoveAll();
|
|
|
|
} // IF nSize > 0
|
|
|
|
}
|
|
catch ( ... )
|
|
{
|
|
EndWrite() ;
|
|
throw;
|
|
}
|
|
|
|
EndWrite();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: TRefPointerCollection::Copy
|
|
//
|
|
// Empties out the collection, copies in another one, addrefing
|
|
// pointers as we go.
|
|
//
|
|
// Inputs: const T& collection
|
|
//
|
|
// Outputs: None.
|
|
//
|
|
// Return: const T& this
|
|
//
|
|
// Comments: We need Write Access to do this.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
const TRefPointerCollection<TYPED_PTR>& TRefPointerCollection<TYPED_PTR>::Copy( const TRefPointerCollection<TYPED_PTR>& collection )
|
|
{
|
|
// By default this is an infinite wait, so it best come back
|
|
BeginWrite();
|
|
|
|
try
|
|
{
|
|
|
|
// Dump out the array
|
|
Empty();
|
|
|
|
int nSize = collection.m_ptrArray.GetSize();
|
|
|
|
for ( int nCount = 0; nCount < nSize; nCount++ )
|
|
{
|
|
TYPED_PTR* ptr = (TYPED_PTR*) collection.m_ptrArray[nCount];
|
|
|
|
// Add will automatically AddRef the pointer again.
|
|
Add( ptr );
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
EndWrite() ;
|
|
throw;
|
|
}
|
|
|
|
EndWrite();
|
|
|
|
return *this;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: TRefPointerCollection::GetSize
|
|
//
|
|
// Inputs: None.
|
|
//
|
|
// Outputs: Number of elements in the collection
|
|
//
|
|
// Return: None.
|
|
//
|
|
// Comments: None.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPED_PTR>
|
|
int TRefPointerCollection<TYPED_PTR>::GetSize(void) const
|
|
{
|
|
return m_ptrArray.GetSize();
|
|
}
|
|
|
|
|
|
#endif
|