Counter Strike : Global Offensive Source Code
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.

156 lines
4.9 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "datamodel/dmelementfactoryhelper.h"
  7. #include "tier0/dbg.h"
  8. // memdbgon must be the last include file in a .cpp file!!!
  9. #include "tier0/memdbgon.h"
  10. CDmElementFactoryHelper *CDmElementFactoryHelper::s_pHelpers[2] = { NULL, NULL };
  11. //-----------------------------------------------------------------------------
  12. // Constructor
  13. //-----------------------------------------------------------------------------
  14. CDmElementFactoryHelper::CDmElementFactoryHelper( const char *classname, CDmElementFactoryInternal *pFactory, bool bIsStandardFactory )
  15. : m_pParent( NULL ), m_pChild( NULL ), m_pSibling( NULL )
  16. {
  17. m_pNext = s_pHelpers[bIsStandardFactory];
  18. s_pHelpers[bIsStandardFactory] = this;
  19. // Set attributes
  20. Assert( pFactory );
  21. m_pFactory = pFactory;
  22. Assert( classname );
  23. m_pszClassname = classname;
  24. }
  25. //-----------------------------------------------------------------------------
  26. // Installs all factories into the datamodel system
  27. //-----------------------------------------------------------------------------
  28. // NOTE: The name of this extern is defined by the macro IMPLEMENT_ELEMENT_FACTORY
  29. extern CDmElementFactoryHelper g_CDmElement_Helper;
  30. void CDmElementFactoryHelper::InstallFactories()
  31. {
  32. static bool s_bInstalled = false;
  33. if ( s_bInstalled )
  34. return;
  35. s_bInstalled = true;
  36. // Just set up the type symbols of the other factories
  37. for ( CDmElementFactoryHelper *pHelper = s_pHelpers[ 0 ]; pHelper; pHelper = pHelper->GetNext() )
  38. {
  39. CDmElementFactoryInternal *pFactory = pHelper->GetFactory();
  40. g_pDataModel->AddElementFactory( pHelper );
  41. // Set up the type symbol. Note this can't be done at
  42. // constructor time since we don't have a DataModel pointer then
  43. pFactory->SetElementTypeSymbol( g_pDataModel->GetSymbol( pHelper->GetClassname() ) );
  44. }
  45. for ( CDmElementFactoryHelper *pHelper = s_pHelpers[ 1 ]; pHelper; pHelper = pHelper->GetNext() )
  46. {
  47. // Add factories to database, but not if they've been overridden
  48. if ( !g_pDataModel->HasElementFactory( pHelper->GetClassname() ) )
  49. {
  50. CDmElementFactoryInternal *pFactory = pHelper->GetFactory();
  51. g_pDataModel->AddElementFactory( pHelper );
  52. // Set up the type symbol. Note this can't be done at
  53. // constructor time since we don't have a DataModel pointer then
  54. // Backward compat--don't let the type symbol be 'DmeElement'
  55. if ( Q_stricmp( pHelper->GetClassname(), "DmeElement" ) )
  56. {
  57. pFactory->SetElementTypeSymbol( g_pDataModel->GetSymbol( pHelper->GetClassname() ) );
  58. }
  59. }
  60. }
  61. // Also install the DmElement factory as the default factory
  62. g_pDataModel->SetDefaultElementFactory( g_CDmElement_Helper.GetFactory() );
  63. for ( int i = 0; i < 2; ++i )
  64. {
  65. for ( CDmElementFactoryHelper *pHelper = s_pHelpers[ i ]; pHelper; pHelper = pHelper->GetNext() )
  66. {
  67. CDmElementFactoryInternal *pFactory = pHelper->GetFactory();
  68. CUtlSymbolLarge parentElementTypeSym = pFactory->GetParentElementTypeSymbol();
  69. if ( !parentElementTypeSym.IsValid() )
  70. continue; // helper has no parent, and therefore no sibling
  71. const char *pParentFactoryName = parentElementTypeSym.String();
  72. CDmElementFactoryHelper *pParent = g_pDataModel->GetElementFactoryHelper( pParentFactoryName );
  73. if ( !pParent )
  74. continue;
  75. const char *pClassName = pHelper->GetClassname();
  76. CDmElementFactoryHelper *pSibling = pParent->GetChild();
  77. if ( !pSibling || V_stricmp( pClassName, pSibling->GetClassname() ) < 0 )
  78. {
  79. pParent->m_pChild = pHelper;
  80. pHelper->m_pSibling = pSibling;
  81. Assert( pHelper->m_pSibling != pHelper );
  82. }
  83. else
  84. {
  85. while ( true )
  86. {
  87. CDmElementFactoryHelper *pNext = pSibling->GetSibling();
  88. if ( !pNext || V_stricmp( pClassName, pNext->GetClassname() ) < 0 )
  89. break;
  90. pSibling = pNext;
  91. }
  92. pHelper->m_pSibling = pSibling->m_pSibling;
  93. Assert( pHelper->m_pSibling != pHelper );
  94. pSibling->m_pSibling = pHelper;
  95. Assert( pSibling->m_pSibling != pSibling );
  96. }
  97. }
  98. }
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Installs all DmElement factories
  102. //-----------------------------------------------------------------------------
  103. void InstallDmElementFactories()
  104. {
  105. CDmElementFactoryHelper::InstallFactories();
  106. }
  107. //-----------------------------------------------------------------------------
  108. void CDmElementFactoryInternal::AddOnElementCreatedCallback( IDmeElementCreated *pCallback )
  109. {
  110. if ( m_CallBackList.Find( pCallback ) == m_CallBackList.InvalidIndex() )
  111. {
  112. m_CallBackList.AddToTail( pCallback );
  113. }
  114. }
  115. void CDmElementFactoryInternal::RemoveOnElementCreatedCallback( IDmeElementCreated *pCallback )
  116. {
  117. m_CallBackList.FindAndRemove( pCallback );
  118. }
  119. void CDmElementFactoryInternal::OnElementCreated( CDmElement* pElement )
  120. {
  121. for ( int i = 0; i < m_CallBackList.Count(); i++ )
  122. {
  123. m_CallBackList[i]->OnElementCreated( pElement );
  124. }
  125. }