mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-13 12:19:13 +00:00
1
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef UTLOBJECTREFERENCE_H
|
||||
#define UTLOBJECTREFERENCE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/utlintrusivelist.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
|
||||
// Purpose: class for keeping track of all the references that exist to an object. When the object
|
||||
// being referenced is freed, all of the references pointing at it will become null.
|
||||
//
|
||||
// To Use:
|
||||
// Add a DECLARE_REFERENCED_CLASS to the class that you want to use CutlReferences with.
|
||||
// Replace pointers to that class with CUtlReferences.
|
||||
// Check these references for null in appropriate places.
|
||||
//
|
||||
// NOTE : You can still happily use pointers instead of references where you want to - these
|
||||
// pointers will not magically become null like references would, but if you know no one is going
|
||||
// to delete the underlying object during a partcular section of code, it doesn't
|
||||
// matter. Basically, CUtlReferences don't rely on every use of an object using one.
|
||||
|
||||
|
||||
|
||||
|
||||
template<class T> class CUtlReference
|
||||
{
|
||||
public:
|
||||
FORCEINLINE CUtlReference(void)
|
||||
{
|
||||
m_pNext = m_pPrev = NULL;
|
||||
m_pObject = NULL;
|
||||
}
|
||||
|
||||
FORCEINLINE CUtlReference(T *pObj)
|
||||
{
|
||||
m_pNext = m_pPrev = NULL;
|
||||
AddRef( pObj );
|
||||
}
|
||||
|
||||
FORCEINLINE ~CUtlReference(void)
|
||||
{
|
||||
KillRef();
|
||||
}
|
||||
|
||||
FORCEINLINE void Set(T *pObj)
|
||||
{
|
||||
if ( m_pObject != pObj )
|
||||
{
|
||||
KillRef();
|
||||
AddRef( pObj );
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE T * operator()(void) const
|
||||
{
|
||||
return m_pObject;
|
||||
}
|
||||
|
||||
FORCEINLINE operator T*()
|
||||
{
|
||||
return m_pObject;
|
||||
}
|
||||
|
||||
FORCEINLINE operator const T*() const
|
||||
{
|
||||
return m_pObject;
|
||||
}
|
||||
|
||||
FORCEINLINE T* operator->()
|
||||
{
|
||||
return m_pObject;
|
||||
}
|
||||
|
||||
FORCEINLINE const T* operator->() const
|
||||
{
|
||||
return m_pObject;
|
||||
}
|
||||
|
||||
FORCEINLINE CUtlReference &operator=( const CUtlReference& otherRef )
|
||||
{
|
||||
Set( otherRef.m_pObject );
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCEINLINE CUtlReference &operator=( T *pObj )
|
||||
{
|
||||
Set( pObj );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
FORCEINLINE bool operator==( const CUtlReference& o ) const
|
||||
{
|
||||
return ( o.m_pObject == m_pObject );
|
||||
}
|
||||
|
||||
public:
|
||||
CUtlReference *m_pNext;
|
||||
CUtlReference *m_pPrev;
|
||||
|
||||
T *m_pObject;
|
||||
|
||||
FORCEINLINE void AddRef( T *pObj )
|
||||
{
|
||||
m_pObject = pObj;
|
||||
if ( pObj )
|
||||
{
|
||||
pObj->m_References.AddToHead( this );
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE void KillRef(void)
|
||||
{
|
||||
if ( m_pObject )
|
||||
{
|
||||
m_pObject->m_References.RemoveNode( this );
|
||||
m_pObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class T> class CUtlReferenceList : public CUtlIntrusiveDList< CUtlReference<T> >
|
||||
{
|
||||
public:
|
||||
~CUtlReferenceList( void )
|
||||
{
|
||||
CUtlReference<T> *i = CUtlIntrusiveDList<CUtlReference<T> >::m_pHead;
|
||||
while( i )
|
||||
{
|
||||
CUtlReference<T> *n = i->m_pNext;
|
||||
i->m_pNext = NULL;
|
||||
i->m_pPrev = NULL;
|
||||
i->m_pObject = NULL;
|
||||
i = n;
|
||||
}
|
||||
CUtlIntrusiveDList<CUtlReference<T> >::m_pHead = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Put this macro in classes that are referenced by CUtlReference
|
||||
//-----------------------------------------------------------------------------
|
||||
#define DECLARE_REFERENCED_CLASS( _className ) \
|
||||
private: \
|
||||
CUtlReferenceList< _className > m_References; \
|
||||
template<class T> friend class CUtlReference;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user