diff options
Diffstat (limited to 'materialsystem/cmaterialdict.cpp')
| -rw-r--r-- | materialsystem/cmaterialdict.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/materialsystem/cmaterialdict.cpp b/materialsystem/cmaterialdict.cpp new file mode 100644 index 0000000..9eb8f0b --- /dev/null +++ b/materialsystem/cmaterialdict.cpp @@ -0,0 +1,171 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "pch_materialsystem.h" + +#define MATSYS_INTERNAL + +#include "cmaterialdict.h" + +#include "materialsystem_global.h" +#include "filesystem.h" +#include "imaterialinternal.h" + +// NOTE: This must be the last file included!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// sort function +//----------------------------------------------------------------------------- +bool CMaterialDict::MaterialLessFunc( const MaterialLookup_t& src1, + const MaterialLookup_t& src2 ) +{ + Assert( ThreadInMainThread() ); + // Always sort manually-created materials to the front + if ( src1.m_bManuallyCreated != src2.m_bManuallyCreated ) + return src1.m_bManuallyCreated; + + return src1.m_Name < src2.m_Name; +} + +//----------------------------------------------------------------------------- +// sort function for missing materials +//----------------------------------------------------------------------------- +bool CMaterialDict::MissingMaterialLessFunc( const MissingMaterial_t& src1, + const MissingMaterial_t& src2 ) +{ + Assert( ThreadInMainThread() ); + return src1.m_Name < src2.m_Name; +} + +void CMaterialDict::Shutdown( ) +{ + Assert( ThreadInMainThread() ); + // Clean up all materials.. + RemoveAllMaterials(); + + // FIXME: Could dump list here... + if ( m_MissingList.Count() ) + DevMsg( "%s m_MissingList count: %d\n", __FUNCTION__, m_MissingList.Count() ); + m_MissingList.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Adds/removes the material to the list of all materials +//----------------------------------------------------------------------------- +void CMaterialDict::AddMaterialToMaterialList( IMaterialInternal *pMaterial ) +{ + Assert( ThreadInMainThread() ); + MaterialLookup_t lookup; + lookup.m_pMaterial = pMaterial; + lookup.m_Name = pMaterial->GetName(); + lookup.m_bManuallyCreated = pMaterial->IsManuallyCreated(); + + m_MaterialDict.Insert( lookup ); +} + +void CMaterialDict::RemoveMaterialFromMaterialList( IMaterialInternal *pMaterial ) +{ + Assert( ThreadInMainThread() ); + // Gotta iterate over this manually; name-based lookup is bogus if there are two + // materials with the same name, which can happen for procedural materials + // First remove all the subrect materials, because they'll point at their material pages. + MaterialHandle_t i; + MaterialHandle_t iNext = InvalidMaterial(); + for (i = FirstMaterial(); i != InvalidMaterial(); i = iNext ) + { + iNext = NextMaterial(i); + if ( m_MaterialDict[i].m_pMaterial == pMaterial ) + { + m_MaterialDict.RemoveAt( i ); + break; + } + } + + Assert( i != InvalidMaterial() ); + +#ifdef _DEBUG + for ( i = iNext; i != InvalidMaterial(); i = NextMaterial(i) ) + { + Assert( m_MaterialDict[i].m_pMaterial != pMaterial ); + } +#endif +} + + +//----------------------------------------------------------------------------- +// Adds, removes materials +//----------------------------------------------------------------------------- +IMaterialInternal* CMaterialDict::AddMaterial( char const* pName, const char *pTextureGroupName ) +{ + Assert( ThreadInMainThread() ); + IMaterialInternal *pMaterial = IMaterialInternal::CreateMaterial( pName, pTextureGroupName ); + Assert( pMaterial && pMaterial->IsRealTimeVersion() ); + AddMaterialToMaterialList( pMaterial ); + return pMaterial; +} + +void CMaterialDict::RemoveMaterial( IMaterialInternal* pMaterial ) +{ + Assert( ThreadInMainThread() ); + Assert( (pMaterial == NULL) || pMaterial->IsRealTimeVersion() ); + RemoveMaterialFromMaterialList( pMaterial ); +} + +IMaterialInternal *CMaterialDict::AddMaterialSubRect( const char *pName, const char *pTextureGroupName, KeyValues *pKeyValues, KeyValues *pPatchKeyValues ) +{ + Assert( ThreadInMainThread() ); + IMaterialInternal *pMaterial = IMaterialInternal::CreateMaterialSubRect( pName, pTextureGroupName, pKeyValues, pPatchKeyValues, true ); + Assert( pMaterial ); + AddMaterialToMaterialList( pMaterial ); + return pMaterial; +} + +void CMaterialDict::RemoveMaterialSubRect( IMaterialInternal *pMaterial ) +{ + Assert( ThreadInMainThread() ); + RemoveMaterialFromMaterialList( pMaterial ); + IMaterialInternal::DestroyMaterialSubRect( pMaterial ); +} + +void CMaterialDict::RemoveMaterialFromMaterialList( MaterialHandle_t h ) +{ + Assert( ThreadInMainThread() ); + m_MaterialDict.RemoveAt( h ); +} + +void CMaterialDict::RemoveAllMaterialsFromMaterialList() +{ + Assert( ThreadInMainThread() ); + m_MaterialDict.RemoveAll(); +} + +void CMaterialDict::RemoveAllMaterials() +{ + Assert( ThreadInMainThread() ); + + // First remove all the subrect materials, because they'll point at their material pages. + MaterialHandle_t i, iNext; + for (i = FirstMaterial(); i != InvalidMaterial(); i = iNext ) + { + iNext = NextMaterial(i); + IMaterialInternal *pMaterial = GetMaterialInternal( i ); + if ( pMaterial->InMaterialPage() ) + { + IMaterialInternal::DestroyMaterialSubRect( pMaterial ); + RemoveMaterialFromMaterialList( i ); + } + } + + // Now get rid of the rest of the materials, including the pages. + for (i = FirstMaterial(); i != InvalidMaterial(); i = NextMaterial(i) ) + { + IMaterialInternal::DestroyMaterial( GetMaterialInternal( i ) ); + } + + RemoveAllMaterialsFromMaterialList(); +} + |