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.

921 lines
22 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // GameEventManager.cpp: implementation of the CGameEventManager class.
  9. //
  10. //////////////////////////////////////////////////////////////////////
  11. #include "GameEventManager.h"
  12. #include "filesystem_engine.h"
  13. #include "server.h"
  14. #include "client.h"
  15. #include "tier0/vprof.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. //////////////////////////////////////////////////////////////////////
  19. // Construction/Destruction
  20. //////////////////////////////////////////////////////////////////////
  21. static CGameEventManager s_GameEventManager;
  22. CGameEventManager &g_GameEventManager = s_GameEventManager;
  23. static const char *s_GameEnventTypeMap[] =
  24. { "local", // 0 : don't network this field
  25. "string", // 1 : zero terminated ASCII string
  26. "float", // 2 : float 32 bit
  27. "long", // 3 : signed int 32 bit
  28. "short", // 4 : signed int 16 bit
  29. "byte", // 5 : unsigned int 8 bit
  30. "bool", // 6 : unsigned int 1 bit
  31. NULL };
  32. static ConVar net_showevents( "net_showevents", "0", FCVAR_CHEAT, "Dump game events to console (1=client only, 2=all)." );
  33. // Expose CVEngineServer to the engine.
  34. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CGameEventManager, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2, s_GameEventManager );
  35. CGameEvent::CGameEvent( CGameEventDescriptor *descriptor )
  36. {
  37. Assert( descriptor );
  38. m_pDescriptor = descriptor;
  39. m_pDataKeys = new KeyValues( descriptor->name );
  40. }
  41. CGameEvent::~CGameEvent()
  42. {
  43. m_pDataKeys->deleteThis();
  44. }
  45. bool CGameEvent::GetBool( const char *keyName, bool defaultValue)
  46. {
  47. return m_pDataKeys->GetInt( keyName, defaultValue ) != 0;
  48. }
  49. int CGameEvent::GetInt( const char *keyName, int defaultValue)
  50. {
  51. return m_pDataKeys->GetInt( keyName, defaultValue );
  52. }
  53. float CGameEvent::GetFloat( const char *keyName, float defaultValue )
  54. {
  55. return m_pDataKeys->GetFloat( keyName, defaultValue );
  56. }
  57. const char *CGameEvent::GetString( const char *keyName, const char *defaultValue )
  58. {
  59. return m_pDataKeys->GetString( keyName, defaultValue );
  60. }
  61. void CGameEvent::SetBool( const char *keyName, bool value )
  62. {
  63. m_pDataKeys->SetInt( keyName, value?1:0 );
  64. }
  65. void CGameEvent::SetInt( const char *keyName, int value )
  66. {
  67. m_pDataKeys->SetInt( keyName, value );
  68. }
  69. void CGameEvent::SetFloat( const char *keyName, float value )
  70. {
  71. m_pDataKeys->SetFloat( keyName, value );
  72. }
  73. void CGameEvent::SetString( const char *keyName, const char *value )
  74. {
  75. m_pDataKeys->SetString( keyName, value );
  76. }
  77. bool CGameEvent::IsEmpty( const char *keyName )
  78. {
  79. return m_pDataKeys->IsEmpty( keyName );
  80. }
  81. const char *CGameEvent::GetName() const
  82. {
  83. return m_pDataKeys->GetName();
  84. }
  85. bool CGameEvent::IsLocal() const
  86. {
  87. return m_pDescriptor->local;
  88. }
  89. bool CGameEvent::IsReliable() const
  90. {
  91. return m_pDescriptor->reliable;
  92. }
  93. CGameEventManager::CGameEventManager()
  94. {
  95. Reset();
  96. }
  97. CGameEventManager::~CGameEventManager()
  98. {
  99. Reset();
  100. }
  101. bool CGameEventManager::Init()
  102. {
  103. Reset();
  104. LoadEventsFromFile( "resource/serverevents.res" );
  105. return true;
  106. }
  107. void CGameEventManager::Shutdown()
  108. {
  109. Reset();
  110. }
  111. void CGameEventManager::Reset()
  112. {
  113. int number = m_GameEvents.Count();
  114. for (int i = 0; i<number; i++)
  115. {
  116. CGameEventDescriptor &e = m_GameEvents.Element( i );
  117. if ( e.keys )
  118. {
  119. e.keys->deleteThis(); // free the value keys
  120. e.keys = NULL;
  121. }
  122. e.listeners.Purge(); // remove listeners
  123. }
  124. m_GameEvents.Purge();
  125. m_Listeners.PurgeAndDeleteElements();
  126. m_EventFiles.RemoveAll();
  127. m_EventFileNames.RemoveAll();
  128. m_bClientListenersChanged = true;
  129. Assert( m_GameEvents.Count() == 0 );
  130. }
  131. bool CGameEventManager::HasClientListenersChanged( bool bReset /* = true */)
  132. {
  133. if ( !m_bClientListenersChanged )
  134. return false;
  135. if ( bReset )
  136. m_bClientListenersChanged = false;
  137. return true;
  138. }
  139. void CGameEventManager::WriteEventList(SVC_GameEventList *msg)
  140. {
  141. // reset event ids to -1 first
  142. msg->m_nNumEvents = 0;
  143. for (int i=0; i < m_GameEvents.Count(); i++ )
  144. {
  145. CGameEventDescriptor &descriptor = m_GameEvents[i];
  146. if ( descriptor.local )
  147. continue;
  148. Assert( descriptor.eventid >= 0 && descriptor.eventid < MAX_EVENT_NUMBER );
  149. msg->m_DataOut.WriteUBitLong( descriptor.eventid, MAX_EVENT_BITS );
  150. msg->m_DataOut.WriteString( descriptor.name );
  151. KeyValues *key = descriptor.keys->GetFirstSubKey();
  152. while ( key )
  153. {
  154. int type = key->GetInt();
  155. if ( type != TYPE_LOCAL )
  156. {
  157. msg->m_DataOut.WriteUBitLong( type, 3 );
  158. msg->m_DataOut.WriteString( key->GetName() );
  159. }
  160. key = key->GetNextKey();
  161. }
  162. msg->m_DataOut.WriteUBitLong( TYPE_LOCAL, 3 ); // end marker
  163. msg->m_nNumEvents++;
  164. }
  165. }
  166. bool CGameEventManager::ParseEventList(SVC_GameEventList *msg)
  167. {
  168. int i;
  169. // reset eventids to -1 first
  170. for ( i=0; i < m_GameEvents.Count(); i++ )
  171. {
  172. CGameEventDescriptor &descriptor = m_GameEvents[i];
  173. descriptor.eventid = -1;
  174. }
  175. // map server event IDs
  176. for (i = 0; i<msg->m_nNumEvents; i++)
  177. {
  178. int id = msg->m_DataIn.ReadUBitLong( MAX_EVENT_BITS );
  179. char name[MAX_EVENT_NAME_LENGTH];
  180. msg->m_DataIn.ReadString( name, sizeof(name) );
  181. CGameEventDescriptor *descriptor = GetEventDescriptor( name );
  182. if ( !descriptor )
  183. {
  184. // event unknown to client, skip data
  185. while ( msg->m_DataIn.ReadUBitLong( 3 ) )
  186. msg->m_DataIn.ReadString( name, sizeof(name) );
  187. continue;
  188. }
  189. // remove old definition list
  190. if ( descriptor->keys )
  191. descriptor->keys->deleteThis();
  192. descriptor->keys = new KeyValues("descriptor");
  193. int datatype = msg->m_DataIn.ReadUBitLong( 3 );
  194. while ( datatype != TYPE_LOCAL )
  195. {
  196. msg->m_DataIn.ReadString( name, sizeof(name) );
  197. descriptor->keys->SetInt( name, datatype );
  198. datatype = msg->m_DataIn.ReadUBitLong( 3 );
  199. }
  200. descriptor->eventid = id;
  201. }
  202. // force client to answer what events he listens to
  203. m_bClientListenersChanged = true;
  204. return true;
  205. }
  206. void CGameEventManager::WriteListenEventList(CLC_ListenEvents *msg)
  207. {
  208. msg->m_EventArray.ClearAll();
  209. // and know tell the server what events we want to listen to
  210. for (int i=0; i < m_GameEvents.Count(); i++ )
  211. {
  212. CGameEventDescriptor &descriptor = m_GameEvents[i];
  213. bool bHasClientListener = false;
  214. for ( int j=0; j<descriptor.listeners.Count(); j++ )
  215. {
  216. CGameEventCallback *listener = descriptor.listeners[j];
  217. if ( listener->m_nListenerType == CGameEventManager::CLIENTSIDE ||
  218. listener->m_nListenerType == CGameEventManager::CLIENTSIDE_OLD )
  219. {
  220. // if we have a client side listener and server knows this event, add it
  221. bHasClientListener = true;
  222. break;
  223. }
  224. }
  225. if ( !bHasClientListener )
  226. continue;
  227. if ( descriptor.eventid == -1 )
  228. {
  229. DevMsg("Warning! Client listens to event '%s' unknown by server.\n", descriptor.name );
  230. continue;
  231. }
  232. msg->m_EventArray.Set( descriptor.eventid );
  233. }
  234. }
  235. IGameEvent *CGameEventManager::CreateEvent( CGameEventDescriptor *descriptor )
  236. {
  237. return new CGameEvent ( descriptor );
  238. }
  239. IGameEvent *CGameEventManager::CreateEvent( const char *name, bool bForce )
  240. {
  241. if ( !name || !name[0] )
  242. return NULL;
  243. CGameEventDescriptor *descriptor = GetEventDescriptor( name );
  244. // check if this event name is known
  245. if ( !descriptor )
  246. {
  247. DevMsg( "CreateEvent: event '%s' not registered.\n", name );
  248. return NULL;
  249. }
  250. // event is known but no one listen to it
  251. if ( descriptor->listeners.Count() == 0 && !bForce )
  252. {
  253. return NULL;
  254. }
  255. // create & return the new event
  256. return new CGameEvent ( descriptor );
  257. }
  258. bool CGameEventManager::FireEvent( IGameEvent *event, bool bServerOnly )
  259. {
  260. return FireEventIntern( event, bServerOnly, false );
  261. }
  262. bool CGameEventManager::FireEventClientSide( IGameEvent *event )
  263. {
  264. return FireEventIntern( event, false, true );
  265. }
  266. IGameEvent *CGameEventManager::DuplicateEvent( IGameEvent *event )
  267. {
  268. CGameEvent *gameEvent = dynamic_cast<CGameEvent*>(event);
  269. if ( !gameEvent )
  270. return NULL;
  271. // create new instance
  272. CGameEvent *newEvent = new CGameEvent ( gameEvent->m_pDescriptor );
  273. // free keys
  274. newEvent->m_pDataKeys->deleteThis();
  275. // and make copy
  276. newEvent->m_pDataKeys = gameEvent->m_pDataKeys->MakeCopy();
  277. return newEvent;
  278. }
  279. void CGameEventManager::ConPrintEvent( IGameEvent *event)
  280. {
  281. CGameEventDescriptor *descriptor = GetEventDescriptor( event );
  282. if ( !descriptor )
  283. return;
  284. KeyValues *key = descriptor->keys->GetFirstSubKey();
  285. while ( key )
  286. {
  287. const char * keyName = key->GetName();
  288. int type = key->GetInt();
  289. switch ( type )
  290. {
  291. case TYPE_LOCAL : ConMsg( "- \"%s\" = \"%s\" (local)\n", keyName, event->GetString(keyName) ); break;
  292. case TYPE_STRING : ConMsg( "- \"%s\" = \"%s\"\n", keyName, event->GetString(keyName) ); break;
  293. case TYPE_FLOAT : ConMsg( "- \"%s\" = \"%.2f\"\n", keyName, event->GetFloat(keyName) ); break;
  294. default: ConMsg( "- \"%s\" = \"%i\"\n", keyName, event->GetInt(keyName) ); break;
  295. }
  296. key = key->GetNextKey();
  297. }
  298. }
  299. bool CGameEventManager::FireEventIntern( IGameEvent *event, bool bServerOnly, bool bClientOnly )
  300. {
  301. if ( event == NULL )
  302. return false;
  303. Assert( !(bServerOnly && bClientOnly) ); // it can't be both
  304. VPROF_("CGameEventManager::FireEvent", 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false,
  305. bClientOnly ? BUDGETFLAG_CLIENT : ( bServerOnly ? BUDGETFLAG_SERVER : BUDGETFLAG_OTHER ) );
  306. CGameEventDescriptor *descriptor = GetEventDescriptor( event );
  307. if ( descriptor == NULL )
  308. {
  309. DevMsg( "FireEvent: event '%s' not registered.\n", event->GetName() );
  310. FreeEvent( event );
  311. return false;
  312. }
  313. tmZoneFiltered( TELEMETRY_LEVEL0, 50, TMZF_NONE, "%s (name: %s listeners: %d)", __FUNCTION__, tmDynamicString( TELEMETRY_LEVEL0, event->GetName() ), descriptor->listeners.Count() );
  314. // show game events in console
  315. if ( net_showevents.GetInt() > 0 )
  316. {
  317. if ( bClientOnly )
  318. {
  319. ConMsg( "Game event \"%s\", Tick %i:\n", descriptor->name, cl.GetClientTickCount() );
  320. ConPrintEvent( event );
  321. }
  322. else if ( net_showevents.GetInt() > 1 )
  323. {
  324. ConMsg( "Server event \"%s\", Tick %i:\n", descriptor->name, sv.GetTick() );
  325. ConPrintEvent( event );
  326. }
  327. }
  328. for ( int i = 0; i < descriptor->listeners.Count(); i++ )
  329. {
  330. CGameEventCallback *listener = descriptor->listeners.Element( i );
  331. Assert ( listener );
  332. // don't trigger server listners for clientside only events
  333. if ( ( listener->m_nListenerType == SERVERSIDE ||
  334. listener->m_nListenerType == SERVERSIDE_OLD ) &&
  335. bClientOnly )
  336. continue;
  337. // don't trigger clientside events, if not explicit a clientside event
  338. if ( ( listener->m_nListenerType == CLIENTSIDE ||
  339. listener->m_nListenerType == CLIENTSIDE_OLD ) &&
  340. !bClientOnly )
  341. continue;
  342. // don't broadcast events if server side only
  343. if ( listener->m_nListenerType == CLIENTSTUB && (bServerOnly || bClientOnly) )
  344. continue;
  345. // TODO optimized the serialize event for clients, call only once and not per client
  346. // fire event in this listener module
  347. if ( listener->m_nListenerType == CLIENTSIDE_OLD ||
  348. listener->m_nListenerType == SERVERSIDE_OLD )
  349. {
  350. tmZone( TELEMETRY_LEVEL1, TMZF_NONE, "FireGameEvent (i: %d, listenertype: %d (old))", i, listener->m_nListenerType );
  351. // legacy support for old system
  352. IGameEventListener *pCallback = static_cast<IGameEventListener*>(listener->m_pCallback);
  353. CGameEvent *pEvent = static_cast<CGameEvent*>(event);
  354. pCallback->FireGameEvent( pEvent->m_pDataKeys );
  355. }
  356. else
  357. {
  358. tmZone( TELEMETRY_LEVEL1, TMZF_NONE, "FireGameEvent (i: %d, listenertype: %d (new))", i, listener->m_nListenerType );
  359. // new system
  360. IGameEventListener2 *pCallback = static_cast<IGameEventListener2*>(listener->m_pCallback);
  361. pCallback->FireGameEvent( event );
  362. }
  363. }
  364. // free event resources
  365. FreeEvent( event );
  366. return true;
  367. }
  368. bool CGameEventManager::SerializeEvent( IGameEvent *event, bf_write* buf )
  369. {
  370. CGameEventDescriptor *descriptor = GetEventDescriptor( event );
  371. Assert( descriptor );
  372. buf->WriteUBitLong( descriptor->eventid, MAX_EVENT_BITS );
  373. // now iterate trough all fields described in gameevents.res and put them in the buffer
  374. KeyValues * key = descriptor->keys->GetFirstSubKey();
  375. if ( net_showevents.GetInt() > 2 )
  376. {
  377. DevMsg("Serializing event '%s' (%i):\n", descriptor->name, descriptor->eventid );
  378. }
  379. while ( key )
  380. {
  381. const char * keyName = key->GetName();
  382. int type = key->GetInt();
  383. if ( net_showevents.GetInt() > 2 )
  384. {
  385. DevMsg(" - %s (%i)\n", keyName, type );
  386. }
  387. //Make sure every key is used in the event
  388. // Assert( event->FindKey(keyName) && "GameEvent field not found in passed KeyValues" );
  389. // see s_GameEnventTypeMap for index
  390. switch ( type )
  391. {
  392. case TYPE_LOCAL : break; // don't network this guy
  393. case TYPE_STRING: buf->WriteString( event->GetString( keyName, "") ); break;
  394. case TYPE_FLOAT : buf->WriteFloat( event->GetFloat( keyName, 0.0f) ); break;
  395. case TYPE_LONG : buf->WriteLong( event->GetInt( keyName, 0) ); break;
  396. case TYPE_SHORT : buf->WriteShort( event->GetInt( keyName, 0) ); break;
  397. case TYPE_BYTE : buf->WriteByte( event->GetInt( keyName, 0) ); break;
  398. case TYPE_BOOL : buf->WriteOneBit( event->GetInt( keyName, 0) ); break;
  399. default: DevMsg(1, "CGameEventManager: unkown type %i for key '%s'.\n", type, key->GetName() ); break;
  400. }
  401. key = key->GetNextKey();
  402. }
  403. return !buf->IsOverflowed();
  404. }
  405. IGameEvent *CGameEventManager::UnserializeEvent( bf_read *buf)
  406. {
  407. char databuf[MAX_EVENT_BYTES];
  408. // read event id
  409. int eventid = buf->ReadUBitLong( MAX_EVENT_BITS );
  410. // get event description
  411. CGameEventDescriptor *descriptor = GetEventDescriptor( eventid );
  412. if ( descriptor == NULL )
  413. {
  414. DevMsg( "CGameEventManager::UnserializeEvent:: unknown event id %i.\n", eventid );
  415. return NULL;
  416. }
  417. // create new event
  418. IGameEvent *event = CreateEvent( descriptor );
  419. if ( !event )
  420. {
  421. DevMsg( "CGameEventManager::UnserializeEvent:: failed to create event %s.\n", descriptor->name );
  422. return NULL;
  423. }
  424. KeyValues * key = descriptor->keys->GetFirstSubKey();
  425. while ( key )
  426. {
  427. const char * keyName = key->GetName();
  428. int type = key->GetInt();
  429. switch ( type )
  430. {
  431. case TYPE_LOCAL : break; // ignore
  432. case TYPE_STRING : if ( buf->ReadString( databuf, sizeof(databuf) ) )
  433. event->SetString( keyName, databuf );
  434. break;
  435. case TYPE_FLOAT : event->SetFloat( keyName, buf->ReadFloat() ); break;
  436. case TYPE_LONG : event->SetInt( keyName, buf->ReadLong() ); break;
  437. case TYPE_SHORT : event->SetInt( keyName, buf->ReadShort() ); break;
  438. case TYPE_BYTE : event->SetInt( keyName, buf->ReadByte() ); break;
  439. case TYPE_BOOL : event->SetInt( keyName, buf->ReadOneBit() ); break;
  440. default: DevMsg(1, "CGameEventManager: unknown type %i for key '%s'.\n", type, key->GetName() ); break;
  441. }
  442. key = key->GetNextKey();
  443. }
  444. return event;
  445. }
  446. // returns true if this listener is listens to given event
  447. bool CGameEventManager::FindListener( IGameEventListener2 *listener, const char *name )
  448. {
  449. CGameEventDescriptor *pDescriptor = GetEventDescriptor( name );
  450. if ( !pDescriptor )
  451. return false; // event is unknown
  452. CGameEventCallback *pCallback = FindEventListener( listener );
  453. if ( !pCallback )
  454. return false; // listener is unknown
  455. // see if listener is in the list for this event
  456. return pDescriptor->listeners.IsValidIndex( pDescriptor->listeners.Find( pCallback ) );
  457. }
  458. CGameEventCallback* CGameEventManager::FindEventListener( void* pCallback )
  459. {
  460. for (int i=0; i < m_Listeners.Count(); i++ )
  461. {
  462. CGameEventCallback *listener = m_Listeners.Element(i);
  463. if ( listener->m_pCallback == pCallback )
  464. {
  465. return listener;
  466. }
  467. }
  468. return NULL;
  469. }
  470. void CGameEventManager::RemoveListener(IGameEventListener2 *listener)
  471. {
  472. CGameEventCallback *pCallback = FindEventListener( listener );
  473. if ( pCallback == NULL )
  474. {
  475. return;
  476. }
  477. // remove reference from events
  478. for (int i=0; i < m_GameEvents.Count(); i++ )
  479. {
  480. CGameEventDescriptor &et = m_GameEvents.Element( i );
  481. et.listeners.FindAndRemove( pCallback );
  482. }
  483. // and from global list
  484. m_Listeners.FindAndRemove( pCallback );
  485. if ( pCallback->m_nListenerType == CLIENTSIDE )
  486. {
  487. m_bClientListenersChanged = true;
  488. }
  489. delete pCallback;
  490. }
  491. int CGameEventManager::LoadEventsFromFile( const char * filename )
  492. {
  493. if ( UTL_INVAL_SYMBOL == m_EventFiles.Find( filename ) )
  494. {
  495. CUtlSymbol id = m_EventFiles.AddString( filename );
  496. m_EventFileNames.AddToTail( id );
  497. }
  498. KeyValues * key = new KeyValues(filename);
  499. KeyValues::AutoDelete autodelete_key( key );
  500. if ( !key->LoadFromFile( g_pFileSystem, filename, "GAME" ) )
  501. return false;
  502. int count = 0; // number new events
  503. KeyValues * subkey = key->GetFirstSubKey();
  504. while ( subkey )
  505. {
  506. if ( subkey->GetDataType() == KeyValues::TYPE_NONE )
  507. {
  508. RegisterEvent( subkey );
  509. count++;
  510. }
  511. subkey = subkey->GetNextKey();
  512. }
  513. if ( net_showevents.GetBool() )
  514. DevMsg( "Event System loaded %i events from file %s.\n", m_GameEvents.Count(), filename );
  515. return m_GameEvents.Count();
  516. }
  517. void CGameEventManager::ReloadEventDefinitions()
  518. {
  519. for ( int i=0; i< m_EventFileNames.Count(); i++ )
  520. {
  521. const char *filename = m_EventFiles.String( m_EventFileNames[i] );
  522. LoadEventsFromFile( filename );
  523. }
  524. // we are the server, build string table now
  525. int number = m_GameEvents.Count();
  526. for (int j = 0; j<number; j++)
  527. {
  528. m_GameEvents[j].eventid = j;
  529. }
  530. }
  531. bool CGameEventManager::AddListener( IGameEventListener2 *listener, const char *event, bool bServerSide )
  532. {
  533. if ( !event )
  534. return false;
  535. // look for the event descriptor
  536. CGameEventDescriptor *descriptor = GetEventDescriptor( event );
  537. if ( !descriptor )
  538. {
  539. DevMsg( "CGameEventManager::AddListener: event '%s' unknown.\n", event );
  540. return false; // that should not happen
  541. }
  542. return AddListener( listener, descriptor, bServerSide ? SERVERSIDE : CLIENTSIDE );
  543. }
  544. bool CGameEventManager::AddListener( void *listener, CGameEventDescriptor *descriptor, int nListenerType )
  545. {
  546. if ( !listener || !descriptor )
  547. return false; // bahh
  548. // check if we already know this listener
  549. CGameEventCallback *pCallback = FindEventListener( listener );
  550. if ( pCallback == NULL )
  551. {
  552. // add new callback
  553. pCallback = new CGameEventCallback;
  554. m_Listeners.AddToTail( pCallback );
  555. pCallback->m_nListenerType = nListenerType;
  556. pCallback->m_pCallback = listener;
  557. }
  558. else
  559. {
  560. // make sure that it hasn't changed:
  561. Assert( pCallback->m_nListenerType == nListenerType );
  562. Assert( pCallback->m_pCallback == listener );
  563. }
  564. // add to event listeners list if not already in there
  565. if ( descriptor->listeners.Find( pCallback ) == descriptor->listeners.InvalidIndex() )
  566. {
  567. descriptor->listeners.AddToTail( pCallback );
  568. if ( nListenerType == CLIENTSIDE || nListenerType == CLIENTSIDE_OLD )
  569. m_bClientListenersChanged = true;
  570. }
  571. return true;
  572. }
  573. bool CGameEventManager::RegisterEvent( KeyValues * event)
  574. {
  575. if ( event == NULL )
  576. return false;
  577. if ( m_GameEvents.Count() == MAX_EVENT_NUMBER )
  578. {
  579. DevMsg( "CGameEventManager: couldn't register event '%s', limit reached (%i).\n",
  580. event->GetName(), MAX_EVENT_NUMBER );
  581. return false;
  582. }
  583. CGameEventDescriptor *descriptor = GetEventDescriptor( event->GetName() );
  584. if ( !descriptor )
  585. {
  586. // event not known yet, create new one
  587. int index = m_GameEvents.AddToTail();
  588. descriptor = &m_GameEvents.Element(index);
  589. AssertMsg2( V_strlen( event->GetName() ) <= MAX_EVENT_NAME_LENGTH, "Event named '%s' exceeds maximum name length %d", event->GetName(), MAX_EVENT_NAME_LENGTH );
  590. Q_strncpy( descriptor->name, event->GetName(), MAX_EVENT_NAME_LENGTH );
  591. }
  592. else
  593. {
  594. // descriptor already know, but delete old definitions
  595. descriptor->keys->deleteThis();
  596. }
  597. // create new descriptor keys
  598. descriptor->keys = new KeyValues("descriptor");
  599. KeyValues *subkey = event->GetFirstSubKey();
  600. // interate through subkeys
  601. while ( subkey )
  602. {
  603. const char *keyName = subkey->GetName();
  604. // ok, check it's data type
  605. const char * type = subkey->GetString();
  606. if ( !Q_strcmp( "local", keyName) )
  607. {
  608. descriptor->local = Q_atoi( type ) != 0;
  609. }
  610. else if ( !Q_strcmp( "reliable", keyName) )
  611. {
  612. descriptor->reliable = Q_atoi( type ) != 0;
  613. }
  614. else
  615. {
  616. int i;
  617. for (i = TYPE_LOCAL; i <= TYPE_BOOL; i++ )
  618. {
  619. if ( !Q_strcmp( type, s_GameEnventTypeMap[i]) )
  620. {
  621. // set data type
  622. descriptor->keys->SetInt( keyName, i ); // set data type
  623. break;
  624. }
  625. }
  626. if ( i > TYPE_BOOL )
  627. {
  628. descriptor->keys->SetInt( keyName, 0 ); // unknown
  629. DevMsg( "CGameEventManager:: unknown type '%s' for key '%s'.\n", type, subkey->GetName() );
  630. }
  631. }
  632. subkey = subkey->GetNextKey();
  633. }
  634. return true;
  635. }
  636. CGameEventDescriptor *CGameEventManager::GetEventDescriptor(IGameEvent *event)
  637. {
  638. CGameEvent *gameevent = dynamic_cast<CGameEvent*>(event);
  639. if ( !gameevent )
  640. return NULL;
  641. return gameevent->m_pDescriptor;
  642. }
  643. CGameEventDescriptor *CGameEventManager::GetEventDescriptor(int eventid) // returns event name or NULL
  644. {
  645. if ( eventid < 0 )
  646. return NULL;
  647. for ( int i = 0; i < m_GameEvents.Count(); i++ )
  648. {
  649. CGameEventDescriptor *descriptor = &m_GameEvents[i];
  650. if ( descriptor->eventid == eventid )
  651. return descriptor;
  652. }
  653. return NULL;
  654. }
  655. void CGameEventManager::FreeEvent( IGameEvent *event )
  656. {
  657. if ( !event )
  658. return;
  659. delete event;
  660. }
  661. CGameEventDescriptor *CGameEventManager::GetEventDescriptor(const char * name)
  662. {
  663. if ( !name || !name[0] )
  664. return NULL;
  665. for (int i=0; i < m_GameEvents.Count(); i++ )
  666. {
  667. CGameEventDescriptor *descriptor = &m_GameEvents[i];
  668. if ( Q_strcmp( descriptor->name, name ) == 0 )
  669. return descriptor;
  670. }
  671. return NULL;
  672. }
  673. bool CGameEventManager::AddListenerAll( void *listener, int nListenerType )
  674. {
  675. if ( !listener )
  676. return false;
  677. for (int i=0; i < m_GameEvents.Count(); i++ )
  678. {
  679. CGameEventDescriptor *descriptor = &m_GameEvents[i];
  680. AddListener( listener, descriptor, nListenerType );
  681. }
  682. DevMsg("Warning! Game event listener registerd for all events. Use newer game event interface.\n");
  683. return true;
  684. }
  685. void CGameEventManager::RemoveListenerOld( void *listener)
  686. {
  687. CGameEventCallback *pCallback = FindEventListener( listener );
  688. if ( pCallback == NULL )
  689. {
  690. DevMsg("RemoveListenerOld: couldn't find listener\n");
  691. return;
  692. }
  693. // remove reference from events
  694. for (int i=0; i < m_GameEvents.Count(); i++ )
  695. {
  696. CGameEventDescriptor &et = m_GameEvents.Element( i );
  697. et.listeners.FindAndRemove( pCallback );
  698. }
  699. // and from global list
  700. m_Listeners.FindAndRemove( pCallback );
  701. if ( pCallback->m_nListenerType == CLIENTSIDE_OLD )
  702. {
  703. m_bClientListenersChanged = true;
  704. }
  705. delete pCallback;
  706. }