diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /public/tier1/utlobjectreference.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'public/tier1/utlobjectreference.h')
| -rw-r--r-- | public/tier1/utlobjectreference.h | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/public/tier1/utlobjectreference.h b/public/tier1/utlobjectreference.h new file mode 100644 index 0000000..da9d303 --- /dev/null +++ b/public/tier1/utlobjectreference.h @@ -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 + + + + + |