Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "stringregistry.h"
  9. #include "ai_namespaces.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. //-----------------------------------------------------------------------------
  13. // CAI_GlobalNamespace
  14. //
  15. CAI_GlobalNamespace::CAI_GlobalNamespace()
  16. : m_pSymbols( new CStringRegistry ),
  17. m_NextGlobalBase( GLOBAL_IDS_BASE )
  18. {
  19. }
  20. //-------------------------------------
  21. CAI_GlobalNamespace::~CAI_GlobalNamespace()
  22. {
  23. delete m_pSymbols;
  24. }
  25. //-------------------------------------
  26. void CAI_GlobalNamespace::Clear()
  27. {
  28. m_pSymbols->ClearStrings();
  29. m_NextGlobalBase = GLOBAL_IDS_BASE;
  30. }
  31. //-------------------------------------
  32. void CAI_GlobalNamespace::AddSymbol( const char *pszSymbol, int symbolID )
  33. {
  34. MEM_ALLOC_CREDIT();
  35. AssertMsg( symbolID != -1, "Invalid symbol id passed to CAI_GlobalNamespace::AddSymbol()" );
  36. if (symbolID == -1 )
  37. return;
  38. AssertMsg( AI_IdIsGlobal( symbolID ), ("Local symbol ID passed to CAI_GlobalNamespace::AddSymbol()") );
  39. AssertMsg( !IdToSymbol( symbolID ) , ("Duplicate symbol ID passed to CAI_GlobalNamespace::AddSymbol()") );
  40. AssertMsg( SymbolToId( pszSymbol ) == -1, ("Duplicate symbol passed to CAI_GlobalNamespace::AddSymbol()") );
  41. m_pSymbols->AddString( pszSymbol, symbolID );
  42. if ( m_NextGlobalBase < symbolID + 1 )
  43. m_NextGlobalBase = symbolID + 1;
  44. }
  45. //-------------------------------------
  46. const char *CAI_GlobalNamespace::IdToSymbol( int symbolID ) const
  47. {
  48. AssertMsg( AI_IdIsGlobal( symbolID ), ("Local symbol ID passed to CAI_GlobalNamespace::IdToSymbol()") );
  49. if ( symbolID == -1 )
  50. return "<<null>>";
  51. return (const_cast<CStringRegistry *>(m_pSymbols))->GetStringText( symbolID );
  52. }
  53. //-------------------------------------
  54. int CAI_GlobalNamespace::SymbolToId( const char *pszSymbol ) const
  55. {
  56. return (const_cast<CStringRegistry *>(m_pSymbols))->GetStringID( pszSymbol );
  57. }
  58. //-------------------------------------
  59. int CAI_GlobalNamespace::NextGlobalBase() const
  60. {
  61. return m_NextGlobalBase;
  62. }
  63. //-----------------------------------------------------------------------------
  64. // CAI_LocalIdSpace
  65. //
  66. // Purpose: Maps per class IDs to global IDs, so that various classes can use
  67. // the same integer in local space to represent different globally
  68. // unique integers. Used for schedules, tasks, conditons and squads
  69. //
  70. CAI_LocalIdSpace::CAI_LocalIdSpace( bool fIsRoot )
  71. : m_pGlobalNamespace( NULL ),
  72. m_pParentIDSpace( NULL ),
  73. m_globalBase( (fIsRoot) ? 0 : -1 ),
  74. m_localBase( (fIsRoot) ? 0 : MAX_STRING_INDEX ),
  75. m_localTop( -1 ),
  76. m_globalTop( -1 )
  77. {
  78. };
  79. //-------------------------------------
  80. bool CAI_LocalIdSpace::Init( CAI_GlobalNamespace *pGlobalNamespace, CAI_LocalIdSpace *pParentIDSpace )
  81. {
  82. if ( m_globalTop != -1 )
  83. {
  84. m_localBase = (!pParentIDSpace) ? 0 : MAX_STRING_INDEX;
  85. m_localTop = -1;
  86. m_globalTop = -1;
  87. }
  88. m_pParentIDSpace = pParentIDSpace;
  89. m_pGlobalNamespace = pGlobalNamespace;
  90. m_globalBase = m_pGlobalNamespace->NextGlobalBase();
  91. return true;
  92. }
  93. //-------------------------------------
  94. bool CAI_LocalIdSpace::AddSymbol( const char *pszSymbol, int localId, const char *pszDebugSymbolType, const char *pszDebugOwner )
  95. {
  96. AssertMsg( AI_IdIsLocal( localId ), ("Global symbol ID passed to CAI_LocalIdSpace::AddSymbol()") );
  97. if ( !m_pGlobalNamespace )
  98. {
  99. DevMsg( "ERROR: Adding symbol to uninitialized table %s\n", pszDebugOwner );
  100. return false;
  101. }
  102. if ( !IsLocalBaseSet() && !SetLocalBase( localId ) )
  103. {
  104. DevMsg( "ERROR: Bad %s LOCALID for %s\n", pszDebugSymbolType, pszDebugOwner );
  105. return false;
  106. }
  107. else if (localId < GetLocalBase() )
  108. {
  109. DevMsg("ERROR: %s First added %s must be first LOCALID!\n", pszDebugSymbolType, pszDebugOwner);
  110. return false;
  111. }
  112. AssertMsg3( LocalToGlobal( localId ) == -1 || !m_pGlobalNamespace->IdToSymbol( LocalToGlobal( localId ) ) , "Duplicate symbol ID passed to CAI_LocalIdSpace::AddSymbol(): %s (%d), had %s", pszSymbol, localId, m_pGlobalNamespace->IdToSymbol( LocalToGlobal( localId ) ) );
  113. AssertMsg( m_pGlobalNamespace->SymbolToId( pszSymbol ) == -1, "Duplicate symbol passed to CAI_LocalIdSpace::AddSymbol()" );
  114. if ( m_localTop != -1 )
  115. {
  116. if ( localId > m_localTop )
  117. {
  118. m_localTop = localId;
  119. m_globalTop = ( m_localTop - m_localBase ) + m_globalBase;
  120. }
  121. }
  122. else
  123. {
  124. m_localTop = m_localBase;
  125. m_globalTop = m_globalBase;
  126. }
  127. m_pGlobalNamespace->AddSymbol( pszSymbol, LocalToGlobal( localId ) );
  128. return true;
  129. }
  130. //-------------------------------------
  131. bool CAI_LocalIdSpace::SetLocalBase( int newBase )
  132. {
  133. AssertMsg( AI_IdIsLocal( newBase ), ("Global symbol ID passed to CAI_LocalIdSpace::SetLocalBase()") );
  134. if (m_localBase == MAX_STRING_INDEX)
  135. {
  136. // UNDONE: Make sure this is the largest Index in the list so far??
  137. m_localBase = newBase;
  138. if ( !m_pParentIDSpace || !m_pParentIDSpace->IsLocalBaseSet() || m_localBase > m_pParentIDSpace->m_localBase )// @Note (toml 08-20-02): this doesn't actually catch namespace collisions, only woefully bad situations where a derived class' offset is less than the base
  139. return true;
  140. }
  141. return false;
  142. }
  143. //-------------------------------------
  144. int CAI_LocalIdSpace::GlobalToLocal( int globalID ) const
  145. {
  146. if ( globalID == -1 )
  147. return -1;
  148. AssertMsg( AI_IdIsGlobal( globalID ), ("Local symbol ID passed to CAI_LocalIdSpace::GlobalToLocal()") );
  149. const CAI_LocalIdSpace *pCurrentMap = this;
  150. do
  151. {
  152. if ( pCurrentMap->IsLocalBaseSet() && globalID >= pCurrentMap->GetGlobalBase() && globalID <= pCurrentMap->GetGlobalTop() )
  153. return ( globalID - pCurrentMap->GetGlobalBase() + pCurrentMap->GetLocalBase() );
  154. pCurrentMap = pCurrentMap->m_pParentIDSpace;
  155. } while ( pCurrentMap != NULL );
  156. // AssertMsg( 0, ("Invalid ID passed to CAI_LocalIdSpace::GlobalToLocal()") );
  157. return -1;
  158. }
  159. //-------------------------------------
  160. int CAI_LocalIdSpace::LocalToGlobal( int localID ) const
  161. {
  162. if ( localID == -1 )
  163. return -1;
  164. AssertMsg( AI_IdIsLocal( localID ), ("Global symbol ID passed to CAI_LocalIdSpace::LocalToGlobal()") );
  165. const CAI_LocalIdSpace *pCurrentMap = this;
  166. do
  167. {
  168. if ( pCurrentMap->IsLocalBaseSet() && localID >= pCurrentMap->GetLocalBase() && localID <= pCurrentMap->GetLocalTop() )
  169. return ( localID + pCurrentMap->GetGlobalBase() - pCurrentMap->GetLocalBase() );
  170. pCurrentMap = pCurrentMap->m_pParentIDSpace;
  171. } while ( pCurrentMap != NULL );
  172. // AssertMsg( 0, ("Invalid ID passed to CAI_LocalIdSpace::LocalToGlobal()") );
  173. return -1;
  174. }
  175. //-----------------------------------------------------------------------------