source-engine/materialsystem/cmaterialdict.h

180 lines
5.2 KiB
C
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef CMATERIALDICT_H
#define CMATERIALDICT_H
#include "tier1/utlsymbol.h"
#include "tier1/utlrbtree.h"
#ifndef MATSYS_INTERNAL
#error "This file is private to the implementation of IMaterialSystem/IMaterialSystemInternal"
#endif
#if defined( _WIN32 )
#pragma once
#endif
//-----------------------------------------------------------------------------
class IMaterial;
class IMaterialInternal;
typedef unsigned short MaterialHandle_t;
//-----------------------------------------------------------------------------
// Dictionary of all known materials
//-----------------------------------------------------------------------------
class CMaterialDict
{
public:
CMaterialDict() :
m_MaterialDict( 0, 256, MaterialLessFunc ),
m_MissingList( 0, 32, MissingMaterialLessFunc )
{
Assert( ThreadInMainThread() );
}
void Shutdown();
int GetNumMaterials( void ) const;
IMaterial* GetMaterial( MaterialHandle_t h ) const;
IMaterialInternal * GetMaterialInternal( MaterialHandle_t idx ) const;
MaterialHandle_t FirstMaterial() const;
MaterialHandle_t NextMaterial( MaterialHandle_t h ) const;
MaterialHandle_t InvalidMaterial() const;
IMaterialInternal * FindMaterial( const char *pszName, bool bManuallyCreated ) const;
void AddMaterialToMaterialList( IMaterialInternal *pMaterial );
void RemoveMaterialFromMaterialList( IMaterialInternal *pMaterial );
void RemoveMaterial( IMaterialInternal *pMaterial );
void RemoveMaterialSubRect( IMaterialInternal *pMaterial );
IMaterialInternal* AddMaterial( const char* pName, const char *pTextureGroupName );
// pKeyValues and pPatchKeyValues should come from LoadVMTFile()
IMaterialInternal* AddMaterialSubRect( const char* pName, const char *pTextureGroupName, KeyValues *pKeyValues, KeyValues *pPatchKeyValues );
bool NoteMissing( const char *pszName );
protected: /*private:*/
void RemoveAllMaterials();
void RemoveAllMaterialsFromMaterialList();
void RemoveMaterialFromMaterialList( MaterialHandle_t h );
// Stores a dictionary of materials, searched by name
struct MaterialLookup_t
{
IMaterialInternal* m_pMaterial;
CUtlSymbol m_Name;
bool m_bManuallyCreated;
};
// Stores a dictionary of missing materials to cut down on redundant warning messages
// TODO: 1) Could add a counter
// 2) Could dump to file/console at exit for exact list of missing materials
struct MissingMaterial_t
{
CUtlSymbol m_Name;
};
static bool MaterialLessFunc( const MaterialLookup_t& src1,
const MaterialLookup_t& src2 );
static bool MissingMaterialLessFunc( const MissingMaterial_t& src1,
const MissingMaterial_t& src2 );
CUtlRBTree< MaterialLookup_t, MaterialHandle_t > m_MaterialDict;
CUtlRBTree< MissingMaterial_t, int > m_MissingList;
};
//-----------------------------------------------------------------------------
// Material iteration methods
//-----------------------------------------------------------------------------
inline MaterialHandle_t CMaterialDict::FirstMaterial() const
{
Assert( ThreadInMainThread() );
return m_MaterialDict.FirstInorder();
}
inline MaterialHandle_t CMaterialDict::NextMaterial( MaterialHandle_t h ) const
{
Assert( ThreadInMainThread() );
return m_MaterialDict.NextInorder(h);
}
inline int CMaterialDict::GetNumMaterials( ) const
{
Assert( ThreadInMainThread() );
return m_MaterialDict.Count();
}
//-----------------------------------------------------------------------------
// Invalid index handle....
//-----------------------------------------------------------------------------
inline MaterialHandle_t CMaterialDict::InvalidMaterial() const
{
Assert( ThreadInMainThread() );
return m_MaterialDict.InvalidIndex();
}
//-----------------------------------------------------------------------------
// Handle to material
//-----------------------------------------------------------------------------
inline IMaterial* CMaterialDict::GetMaterial( MaterialHandle_t idx ) const
{
Assert( ThreadInMainThread() );
return m_MaterialDict[idx].m_pMaterial;
}
inline IMaterialInternal* CMaterialDict::GetMaterialInternal( MaterialHandle_t idx ) const
{
Assert( ThreadInMainThread() );
Assert( (m_MaterialDict[idx].m_pMaterial == NULL) || m_MaterialDict[idx].m_pMaterial->IsRealTimeVersion() );
return m_MaterialDict[idx].m_pMaterial;
}
inline IMaterialInternal* CMaterialDict::FindMaterial( const char *pszName, bool bManuallyCreated ) const
{
Assert( ThreadInMainThread() );
MaterialLookup_t lookup;
lookup.m_Name = pszName;
lookup.m_bManuallyCreated = bManuallyCreated; // This causes the search to find only file-created materials
MaterialHandle_t h = m_MaterialDict.Find( lookup );
if ( h != m_MaterialDict.InvalidIndex() )
{
return m_MaterialDict[h].m_pMaterial;
}
return NULL;
}
inline bool CMaterialDict::NoteMissing( const char *pszName )
{
Assert( ThreadInMainThread() );
MissingMaterial_t missing;
missing.m_Name = pszName;
if ( m_MissingList.Find( missing ) != m_MissingList.InvalidIndex() )
{
return false;
}
m_MissingList.Insert( missing );
return true;
}
//-----------------------------------------------------------------------------
#endif // CMATERIALDICT_H