//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // //===========================================================================// #include "tier1/utlsymbol.h" #include "tier1/UtlStringMap.h" #include "tier2/tier2.h" #include "datacache/iprecachesystem.h" #include "datacache/iresourceaccesscontrol.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" //----------------------------------------------------------------------------- // Implementation class //----------------------------------------------------------------------------- class CPrecacheSystem : public CTier2AppSystem< IPrecacheSystem > { typedef CTier2AppSystem< IPrecacheSystem > BaseClass; // Inherited from IAppSystem public: // Inherited from IResourceAccessControl public: void Register( IResourcePrecacher *pResourcePrecacherFirst, PrecacheSystem_t nSystem ); // Precaches/uncaches all resources used by a particular system void Cache( IPrecacheHandler *pPrecacheHandler, PrecacheSystem_t nSystem, const char *pName, bool bPrecache, ResourceList_t hResourceList, bool bBuildResourceList ); void UncacheAll( IPrecacheHandler *pPrecacheHandler ); // Limits resource access to only resources used by this particular system // Use GLOBAL system, and NULL name to disable limited resource access void LimitResourceAccess( PrecacheSystem_t nSystem, const char *pName ); void EndLimitedResourceAccess(); private: IResourcePrecacher *m_pFirstPrecacher[PRECACHE_SYSTEM_COUNT]; CUtlStringMap< ResourceList_t > m_ResourceList[ PRECACHE_SYSTEM_COUNT ]; }; //----------------------------------------------------------------------------- // String names corresponding to resource types //----------------------------------------------------------------------------- static const char *s_pResourceSystemName[] = { "global client resource", "global server resource", "vgui panel", "dispatch effect", "shared system", }; //----------------------------------------------------------------------------- // Singleton //----------------------------------------------------------------------------- CPrecacheSystem g_PrecacheSystem; EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPrecacheSystem, IPrecacheSystem, PRECACHE_SYSTEM_INTERFACE_VERSION, g_PrecacheSystem ); //----------------------------------------------------------------------------- // Precaches/uncaches all resources used by a particular system //----------------------------------------------------------------------------- void CPrecacheSystem::Cache( IPrecacheHandler *pPrecacheHandler, PrecacheSystem_t nSystem, const char *pName, bool bPrecache, ResourceList_t hResourceList, bool bBuildResourceList ) { COMPILE_TIME_ASSERT( ARRAYSIZE( s_pResourceSystemName ) == PRECACHE_SYSTEM_COUNT ); IResourcePrecacher *pPrecacher = m_pFirstPrecacher[nSystem]; for( ; pPrecacher; pPrecacher = pPrecacher->GetNext() ) { if ( pName && Q_stricmp( pName, pPrecacher->GetName() ) ) continue; if ( bBuildResourceList && g_pResourceAccessControl ) { Assert( hResourceList == RESOURCE_LIST_INVALID ); UtlSymId_t idx = m_ResourceList[ nSystem ].Find( pName ); if ( idx != UTL_INVAL_SYMBOL ) { hResourceList = m_ResourceList[ nSystem ][ idx ]; } else { char pDebugName[256]; Q_snprintf( pDebugName, sizeof(pDebugName), "%s \"%s\"", s_pResourceSystemName[nSystem], pName ); hResourceList = g_pResourceAccessControl->CreateResourceList( pDebugName ); m_ResourceList[ nSystem ][ pName ] = hResourceList; } } pPrecacher->Cache( pPrecacheHandler, bPrecache, hResourceList, false ); if ( !bPrecache ) { m_ResourceList[ nSystem ][ pName ] = NULL; } } } //----------------------------------------------------------------------------- // Uncaches everything //----------------------------------------------------------------------------- void CPrecacheSystem::UncacheAll( IPrecacheHandler *pPrecacheHandler ) { int nSystem; for ( nSystem = 0; nSystem < PRECACHE_SYSTEM_COUNT; nSystem ++ ) { IResourcePrecacher *pPrecacher = m_pFirstPrecacher[nSystem]; for( ; pPrecacher; pPrecacher = pPrecacher->GetNext() ) { pPrecacher->Cache( pPrecacheHandler, false, RESOURCE_LIST_INVALID, false ); } m_ResourceList[nSystem].Purge(); } } //----------------------------------------------------------------------------- // Called to register a list of resource precachers for a given system //----------------------------------------------------------------------------- void CPrecacheSystem::Register( IResourcePrecacher *pResourcePrecacherFirst, PrecacheSystem_t nSystem ) { // do we already have any precachers registered for this system? IResourcePrecacher *pCur = m_pFirstPrecacher[nSystem]; if ( pCur ) { while ( pCur->GetNext() != NULL ) { pCur = pCur->GetNext(); } // add the head of the new list to the tail of the existing list pCur->SetNext( pResourcePrecacherFirst ); } else { m_pFirstPrecacher[nSystem] = pResourcePrecacherFirst; } } //----------------------------------------------------------------------------- // Limits resource access to only resources used by this particular system // Use GLOBAL system, and NULL name to disable limited resource access //----------------------------------------------------------------------------- void CPrecacheSystem::LimitResourceAccess( PrecacheSystem_t nSystem, const char *pName ) { if ( g_pResourceAccessControl ) { UtlSymId_t nSym = ( pName != NULL ) ? m_ResourceList[nSystem].Find( pName ) : UTL_INVAL_SYMBOL; if ( nSym != UTL_INVAL_SYMBOL ) { g_pResourceAccessControl->LimitAccess( m_ResourceList[nSystem][nSym] ); } else { g_pResourceAccessControl->LimitAccess( RESOURCE_LIST_INVALID ); } } } void CPrecacheSystem::EndLimitedResourceAccess() { if ( g_pResourceAccessControl ) { g_pResourceAccessControl->LimitAccess( RESOURCE_LIST_INVALID ); } }