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.

246 lines
9.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Additional shared object cache functionality for the GC
  4. //
  5. //=============================================================================
  6. #ifndef GCCLIENT_SHAREDOBJECTCACHE_H
  7. #define GCCLIENT_SHAREDOBJECTCACHE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "sharedobjectcache.h"
  12. class CMsgSOCacheSubscribed;
  13. class CMsgSOCacheSubscribed_SubscribedType;
  14. namespace GCSDK
  15. {
  16. /// Enumerate different events that might trigger a callback to an ISharedObjectListener
  17. enum ESOCacheEvent
  18. {
  19. /// Dummy sentinel value
  20. eSOCacheEvent_None = 0,
  21. /// We received a our first update from the GC and are subscribed
  22. eSOCacheEvent_Subscribed = 1,
  23. /// We lost connection to GC or GC notified us that we are no longer subscribed.
  24. /// Objects stay in the cache, but we no longer receive updates
  25. eSOCacheEvent_Unsubscribed = 2,
  26. /// We received a full update from the GC on a cache for which we were already subscribed.
  27. /// This can happen if connectivity is lost, and then restored before we realized it was lost.
  28. eSOCacheEvent_Resubscribed = 3,
  29. /// We received an incremental update from the GC about specific object(s) being
  30. /// added, updated, or removed from the cache
  31. eSOCacheEvent_Incremental = 4,
  32. /// A lister was added to the cache
  33. /// @see CGCClientSharedObjectCache::AddListener
  34. eSOCacheEvent_ListenerAdded = 5,
  35. /// A lister was removed from the cache
  36. /// @see CGCClientSharedObjectCache::RemoveListener
  37. eSOCacheEvent_ListenerRemoved = 6,
  38. };
  39. //----------------------------------------------------------------------------
  40. // Purpose: Allow game components to register themselves to hear about inventory
  41. // changes when they are received from the server
  42. //----------------------------------------------------------------------------
  43. class ISharedObjectListener
  44. {
  45. public:
  46. /// Called when a new object is created in a cache we are currently subscribed to, or when we are added
  47. /// as a listener to a cache which already has objects in it
  48. ///
  49. /// eEvent will be one of:
  50. /// - eSOCacheEvent_Subscribed
  51. /// - eSOCacheEvent_Resubscribed
  52. /// - eSOCacheEvent_Incremental
  53. /// - eSOCacheEvent_ListenerAdded
  54. virtual void SOCreated( const CSteamID & steamIDOwner, const CSharedObject *pObject, ESOCacheEvent eEvent ) = 0;
  55. /// Called when we are about to update objects in our cache but haven't done any of the work yet.
  56. ///
  57. /// eEvent will be one of:
  58. /// - eSOCacheEvent_Resubscribed
  59. /// - eSOCacheEvent_Incremental
  60. virtual void PreSOUpdate( const CSteamID & steamIDOwner, ESOCacheEvent eEvent ) = 0;
  61. /// Called when an object is updated in a cache we are currently subscribed to.
  62. ///
  63. /// eEvent will be one of:
  64. /// - eSOCacheEvent_Resubscribed
  65. /// - eSOCacheEvent_Incremental
  66. virtual void SOUpdated( const CSteamID & steamIDOwner, const CSharedObject *pObject, ESOCacheEvent eEvent ) = 0;
  67. /// Called when we're finished updating objects in our cache for this batch.
  68. ///
  69. /// eEvent will be one of:
  70. /// - eSOCacheEvent_Resubscribed
  71. /// - eSOCacheEvent_Incremental
  72. virtual void PostSOUpdate( const CSteamID & steamIDOwner, ESOCacheEvent eEvent ) = 0;
  73. /// Called when an object is about to be deleted in a cache we are currently subscribed to.
  74. /// The object will have already been removed from the cache, but is still valid.
  75. ///
  76. /// eEvent will be one of:
  77. /// - eSOCacheEvent_Incremental
  78. /// - eSOCacheEvent_Resubscribed
  79. virtual void SODestroyed( const CSteamID & steamIDOwner, const CSharedObject *pObject, ESOCacheEvent eEvent ) = 0;
  80. /// Called to notify a listener that he is subscribed to the cache.
  81. ///
  82. /// eEvent will be one of:
  83. /// - eSOCacheEvent_Subscribed
  84. /// - eSOCacheEvent_Resubscribed
  85. /// - eSOCacheEvent_ListenerAdded
  86. ///
  87. /// A listener is guaranteed that it will not receive incremental updates (SOCreated,
  88. /// SOUpdated, SODestroyed) while not subscribed. (Before the SOCacheSubscribed or
  89. /// after SOCacheUnsubscribed.) However, note that it may be possible to receive
  90. /// an SOCacheSubscribed message while already subscribed. This can happen if the
  91. /// GC loses and restores connection, or otherwise decides that a full update is
  92. /// necessary.
  93. virtual void SOCacheSubscribed( const CSteamID & steamIDOwner, ESOCacheEvent eEvent ) = 0;
  94. /// Called to notify a listener that he is no longer subscribed to the cache.
  95. /// if he is being removed as a listener, then he will no longer receive
  96. /// updates. Otherwise, he might receive another SOCacheSubscribed
  97. /// message, followed by further update notifications.
  98. ///
  99. /// eEvent will be one of:
  100. /// - eSOCacheEvent_Unsubscribed
  101. /// - eSOCacheEvent_ListenerRemoved
  102. virtual void SOCacheUnsubscribed( const CSteamID & steamIDOwner, ESOCacheEvent eEvent ) = 0;
  103. };
  104. //----------------------------------------------------------------------------
  105. // Purpose: The part of a shared object cache that handles all objects of a
  106. // single type.
  107. //----------------------------------------------------------------------------
  108. class CGCClientSharedObjectContext
  109. {
  110. public:
  111. CGCClientSharedObjectContext( const CSteamID & steamIDOwner );
  112. bool BAddListener( ISharedObjectListener *pListener );
  113. bool BRemoveListener( ISharedObjectListener *pListener );
  114. void SOCreated( const CSharedObject *pObject, ESOCacheEvent eEvent ) const;
  115. void PreSOUpdate( GCSDK::ESOCacheEvent eEvent ) const;
  116. void SOUpdated( const CSharedObject *pObject, ESOCacheEvent eEvent ) const;
  117. void PostSOUpdate( GCSDK::ESOCacheEvent eEvent ) const;
  118. void SODestroyed( const CSharedObject *pObject, ESOCacheEvent eEvent ) const;
  119. void SOCacheSubscribed( const CSteamID & steamIDOwner, ESOCacheEvent eEvent ) const;
  120. void SOCacheUnsubscribed( const CSteamID & steamIDOwner, ESOCacheEvent eEvent ) const;
  121. const CSteamID & GetOwner() const { return m_steamIDOwner; }
  122. const CUtlVector< ISharedObjectListener * > & GetListeners() const { return m_vecListeners; }
  123. private:
  124. CSteamID m_steamIDOwner;
  125. CUtlVector<ISharedObjectListener *> m_vecListeners;
  126. };
  127. //----------------------------------------------------------------------------
  128. // Purpose: The part of a shared object cache that handles all objects of a
  129. // single type.
  130. //----------------------------------------------------------------------------
  131. class CGCClientSharedObjectTypeCache : public CSharedObjectTypeCache
  132. {
  133. public:
  134. CGCClientSharedObjectTypeCache( int nTypeID, const CGCClientSharedObjectContext & context );
  135. virtual ~CGCClientSharedObjectTypeCache();
  136. bool BParseCacheSubscribedMsg( const CMsgSOCacheSubscribed_SubscribedType & msg, CUtlVector<CSharedObject*> &vecCreatedObjects, CUtlVector<CSharedObject*> &vecUpdatedObjects, CUtlVector<CSharedObject*> &vecObjectsToDestroy );
  137. CSharedObject *BCreateFromMsg( const void *pvData, uint32 unSize, bool *bUpdatedExisting );
  138. bool BDestroyFromMsg( const void *pvData, uint32 unSize );
  139. bool BUpdateFromMsg( const void *pvData, uint32 unSize );
  140. void RemoveAllObjects( CUtlVector<CSharedObject*> &vecObjects );
  141. private:
  142. const CGCClientSharedObjectContext & m_context;
  143. };
  144. //----------------------------------------------------------------------------
  145. // Purpose: A cache of a bunch of shared objects of different types. This class
  146. // is shared between clients, gameservers, and the GC and is
  147. // responsible for sending messages from the GC to cause object
  148. // creation/destruction/updating on the clients/gameservers.
  149. //----------------------------------------------------------------------------
  150. class CGCClientSharedObjectCache : public CSharedObjectCache
  151. {
  152. friend class CGCSOUpdateMultipleJob;
  153. public:
  154. CGCClientSharedObjectCache( const CSteamID & steamIDOwner = CSteamID() );
  155. virtual ~CGCClientSharedObjectCache();
  156. /// Have we received at least one update from the GC?
  157. bool BIsInitialized() const { return m_bInitialized; }
  158. /// Are we currently subscribed to updates from the GC?
  159. bool BIsSubscribed() const { return m_bSubscribed; }
  160. /// Who owns this cache?
  161. virtual const CSteamID & GetOwner() const { return m_context.GetOwner(); }
  162. /// Adds a listener interface to the object. A call to re-add
  163. /// a listener that's already listening is harmlessly ignored.
  164. ///
  165. /// If the cache is currently subscribed, then the listener will
  166. /// immediately receive a SOCacheSubscribed call.
  167. void AddListener( ISharedObjectListener *pListener );
  168. /// Removes a listener interface on the object. Returns true
  169. /// if we were listening and removed OK, false if we were not
  170. /// previously listening and the call was ignored
  171. ///
  172. /// If the cache is currently subscribed and we were listening,
  173. /// then the listener will immediately receive a SOCacheUnsubscribed
  174. /// call.
  175. bool RemoveListener( ISharedObjectListener *pListener );
  176. CGCClientSharedObjectTypeCache *FindTypeCache( int nClassID ) { return (CGCClientSharedObjectTypeCache *)FindBaseTypeCache( nClassID ); }
  177. CGCClientSharedObjectTypeCache *CreateTypeCache( int nClassID ) { return (CGCClientSharedObjectTypeCache *)CreateBaseTypeCache( nClassID ); }
  178. bool BParseCacheSubscribedMsg( const CMsgSOCacheSubscribed & msg );
  179. void NotifyUnsubscribe();
  180. void NotifyResubscribedUpToDate();
  181. bool BCreateFromMsg( int nTypeID, const void *pvData, uint32 unSize );
  182. bool BDestroyFromMsg( int nTypeID, const void *pvData, uint32 unSize );
  183. bool BUpdateFromMsg( int nTypeID, const void *pvData, uint32 unSize );
  184. #ifdef DBGFLAG_VALIDATE
  185. virtual void Validate( CValidator &validator, const char *pchName );
  186. #endif
  187. protected:
  188. private:
  189. virtual CSharedObjectTypeCache *AllocateTypeCache( int nClassID ) const OVERRIDE { return new CGCClientSharedObjectTypeCache( nClassID, m_context ); }
  190. CGCClientSharedObjectTypeCache *GetTypeCacheByIndex( int nIndex ) { return (CGCClientSharedObjectTypeCache *)CSharedObjectCache::GetTypeCacheByIndex( nIndex ); }
  191. CGCClientSharedObjectContext m_context;
  192. bool m_bInitialized;
  193. bool m_bSubscribed;
  194. };
  195. } // namespace GCSDK
  196. #endif //GCCLIENT_SHAREDOBJECTCACHE_H