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.

225 lines
5.7 KiB

  1. //===== Copyright � Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Defines scripting system.
  4. //
  5. //===========================================================================//
  6. #include "tier0/dbg.h"
  7. #include "gameuiscript.h"
  8. #include "gameuiscriptinterface.h"
  9. #include "gameuidefinition.h"
  10. #include "keyvalues.h"
  11. #include "fmtstr.h"
  12. static ConVar ui_script_error_path( "ui_script_error_path", "", FCVAR_DEVELOPMENTONLY );
  13. //-------------------------------------------------------------
  14. //
  15. //-------------------------------------------------------------
  16. static void ScriptOutputFunc( const char *pszText )
  17. {
  18. Msg( "%s\n", pszText );
  19. }
  20. //-------------------------------------------------------------
  21. //
  22. //-------------------------------------------------------------
  23. static bool ScriptErrorFunc( ScriptErrorLevel_t eLevel, const char *pszText )
  24. {
  25. // Attempt to parse the error for Visual Studio presentation for double-click
  26. if ( char const *pParse1 = StringAfterPrefix( pszText, "[string \"" ) )
  27. {
  28. if ( char const *pQuote = strchr( pParse1, '\"' ) )
  29. {
  30. if ( char const *pParse2 = StringAfterPrefix( pQuote, "\"]:" ) )
  31. {
  32. if ( char const *pEndNum = strchr( pParse2, ':' ) )
  33. {
  34. char const *szType = (eLevel == SCRIPT_LEVEL_WARNING) ? "WARNING" : "ERROR";
  35. Warning( "%s%.*s(%.*s): %s: %s\n",
  36. ui_script_error_path.GetString(),
  37. pQuote - pParse1, pParse1, // file name
  38. pEndNum - pParse2, pParse2, // line number
  39. szType,
  40. pEndNum + 1
  41. );
  42. return true;
  43. }
  44. }
  45. }
  46. }
  47. switch( eLevel )
  48. {
  49. case SCRIPT_LEVEL_WARNING:
  50. Warning( "WARNING: %s\n", pszText );
  51. break;
  52. case SCRIPT_LEVEL_ERROR:
  53. Warning( "ERROR: %s\n", pszText );
  54. break;
  55. }
  56. return true;
  57. }
  58. //-------------------------------------------------------------
  59. // Constructor
  60. //-------------------------------------------------------------
  61. CGameUIScript::CGameUIScript( )
  62. {
  63. m_pScriptVM = GameUIScriptSystemCreate();
  64. m_pScriptVM->SetOutputCallback( ScriptOutputFunc );
  65. m_pScriptVM->SetErrorCallback( ScriptErrorFunc );
  66. m_IsActive = false;
  67. m_pGameUIScriptInterface = NULL;
  68. m_Version = -1;
  69. m_Name = "unknown";
  70. }
  71. //-------------------------------------------------------------
  72. // Destructor
  73. //-------------------------------------------------------------
  74. CGameUIScript::~CGameUIScript( )
  75. {
  76. Shutdown();
  77. }
  78. void CGameUIScript::Shutdown()
  79. {
  80. if ( m_pGameUIScriptInterface )
  81. {
  82. delete m_pGameUIScriptInterface;
  83. m_pGameUIScriptInterface = NULL;
  84. }
  85. }
  86. //-------------------------------------------------------------
  87. // Assign this class a script file and a menu to run it on
  88. //-------------------------------------------------------------
  89. bool CGameUIScript::SetScript( const char *pszFileName, CGameUIDefinition *pDef )
  90. {
  91. ScriptVariant_t Value;
  92. m_ScriptFile = pszFileName;
  93. m_pGameUIScriptInterface = new CGameUIScriptInterface( m_pScriptVM, pDef );
  94. if ( GameUIScriptSystemRun( m_pScriptVM, m_ScriptFile, NULL, true ) == false )
  95. {
  96. return false;
  97. }
  98. if ( !m_pScriptVM->GetValue( pDef->GetName(), &Value ) )
  99. {
  100. return false;
  101. }
  102. m_Scope = Value.m_hScript;
  103. // we don't release Value as that would kill m_Scope.
  104. //GetScriptName();
  105. GetScriptVersion();
  106. #ifndef _DEBUG
  107. //if ( m_Version != build_number() && 0 )
  108. //{
  109. // Msg( "Script %s is out of date. Got %d. Expected %d.\n", pszFileName, m_Version, build_number() );
  110. // return false;
  111. //}
  112. #endif
  113. return true;
  114. }
  115. //-------------------------------------------------------------
  116. //
  117. //-------------------------------------------------------------
  118. bool CGameUIScript::GetScriptName( )
  119. {
  120. HSCRIPT ExecuteFuncProc = m_pScriptVM->LookupFunction( "Name", m_Scope );
  121. if ( ExecuteFuncProc == NULL )
  122. {
  123. return false;
  124. }
  125. ScriptVariant_t Return;
  126. m_pScriptVM->Call( ExecuteFuncProc, m_Scope, true, &Return );
  127. m_Name = Return.m_pszString;
  128. m_pScriptVM->ReleaseFunction( ExecuteFuncProc );
  129. m_pScriptVM->ReleaseValue( Return );
  130. return true;
  131. }
  132. //-------------------------------------------------------------
  133. //
  134. //-------------------------------------------------------------
  135. bool CGameUIScript::GetScriptVersion( )
  136. {
  137. HSCRIPT ExecuteFuncProc = m_pScriptVM->LookupFunction( "Version", m_Scope );
  138. if ( ExecuteFuncProc == NULL )
  139. {
  140. return false;
  141. }
  142. ScriptVariant_t Return;
  143. m_pScriptVM->Call( ExecuteFuncProc, m_Scope, true, &Return );
  144. if ( Return.m_type == FIELD_FLOAT )
  145. {
  146. m_Version = ( int )Return.m_float;
  147. }
  148. else
  149. {
  150. m_Version = Return.m_int;
  151. }
  152. m_pScriptVM->ReleaseFunction( ExecuteFuncProc );
  153. m_pScriptVM->ReleaseValue( Return );
  154. return true;
  155. }
  156. //-------------------------------------------------------------
  157. // Call a scripting function that takes an array of strings as an arg.
  158. //-------------------------------------------------------------
  159. bool CGameUIScript::Execute( KeyValues *pData, KeyValues **ppResult )
  160. {
  161. const char *eventName = pData->GetName();
  162. HSCRIPT ExecuteFuncProc = m_pScriptVM->LookupFunction( eventName, m_Scope );
  163. if ( ExecuteFuncProc == NULL )
  164. {
  165. return false;
  166. }
  167. // Transform the key values into script scope to execute
  168. HSCRIPT hParams = CGameUIScriptInterface::ScriptTableFromKeyValues( m_pScriptVM, pData );
  169. ScriptVariant_t varParams = hParams, varResult;
  170. ScriptStatus_t ret = m_pScriptVM->ExecuteFunction( ExecuteFuncProc, &varParams, 1, &varResult, m_Scope, true );
  171. if ( hParams )
  172. {
  173. m_pScriptVM->ReleaseValue( varParams );
  174. }
  175. if ( ret == SCRIPT_DONE && varResult.m_type == FIELD_HSCRIPT && ppResult )
  176. {
  177. Assert( !*ppResult ); // storing return value, might overwrite caller's keyvalues
  178. *ppResult = CGameUIScriptInterface::ScriptVmKeyValueFromVariant( m_pScriptVM, varResult );
  179. }
  180. m_pScriptVM->ReleaseValue( varResult );
  181. m_pScriptVM->ReleaseFunction( ExecuteFuncProc );
  182. return true;
  183. }