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.

165 lines
5.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Shared object based on a CBaseRecord subclass
  4. //
  5. //=============================================================================
  6. #ifndef PROTOBUFSHAREDOBJECT_H
  7. #define PROTOBUFSHAREDOBJECT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "google/protobuf/descriptor.h"
  12. #include "tier1/KeyValues.h"
  13. #if defined( GC ) && defined( DEBUG )
  14. #include "gcbase.h"
  15. #endif
  16. namespace google
  17. {
  18. namespace protobuf
  19. {
  20. class Message;
  21. }
  22. }
  23. namespace GCSDK
  24. {
  25. //----------------------------------------------------------------------------
  26. // Purpose: Base class for CProtoBufSharedObject. This is where all the actual
  27. // code lives.
  28. //----------------------------------------------------------------------------
  29. class CProtoBufSharedObjectBase : public CSharedObject
  30. {
  31. public:
  32. typedef CSharedObject BaseClass;
  33. virtual bool BParseFromMessage( const CUtlBuffer & buffer ) OVERRIDE;
  34. virtual bool BParseFromMessage( const std::string &buffer ) OVERRIDE;
  35. virtual bool BUpdateFromNetwork( const CSharedObject & objUpdate ) OVERRIDE;
  36. virtual bool BIsKeyLess( const CSharedObject & soRHS ) const ;
  37. virtual void Copy( const CSharedObject & soRHS );
  38. virtual void Dump() const OVERRIDE;
  39. #ifdef DBGFLAG_VALIDATE
  40. virtual void Validate( CValidator &validator, const char *pchName );
  41. #endif
  42. #ifdef GC
  43. virtual bool BAddToMessage( CUtlBuffer & bufOutput ) const OVERRIDE;
  44. virtual bool BAddToMessage( std::string *pBuffer ) const OVERRIDE;
  45. virtual bool BAddDestroyToMessage( CUtlBuffer & bufDestroy ) const OVERRIDE;
  46. virtual bool BAddDestroyToMessage( std::string *pBuffer ) const OVERRIDE;
  47. virtual bool BParseFromMemcached( CUtlBuffer & buffer ) OVERRIDE;
  48. virtual bool BAddToMemcached( CUtlBuffer & bufOutput ) const OVERRIDE;
  49. static bool SerializeToBuffer( const ::google::protobuf::Message & msg, CUtlBuffer & bufOutput );
  50. #endif //GC
  51. // Static helpers
  52. static void Dump( const ::google::protobuf::Message & msg );
  53. static KeyValues *CreateKVFromProtoBuf( const ::google::protobuf::Message & msg );
  54. static void RecursiveAddProtoBufToKV( KeyValues *pKVDest, const ::google::protobuf::Message & msg );
  55. protected:
  56. virtual ::google::protobuf::Message *GetPObject() = 0;
  57. const ::google::protobuf::Message *GetPObject() const { return const_cast<CProtoBufSharedObjectBase *>(this)->GetPObject(); }
  58. private:
  59. #ifdef GC
  60. static ::google::protobuf::Message *BuildDestroyToMessage( const ::google::protobuf::Message & msg );
  61. #endif //GC
  62. };
  63. //----------------------------------------------------------------------------
  64. // Purpose: Template for making a shared object that uses a specific protobuf
  65. // message class for its wire protocol and in-memory representation.
  66. //----------------------------------------------------------------------------
  67. template< typename Message_t, int nTypeID, bool bPublicMutable = true >
  68. class CProtoBufSharedObject : public CProtoBufSharedObjectBase
  69. {
  70. public:
  71. ~CProtoBufSharedObject()
  72. {
  73. #if defined( GC ) && defined( DEBUG )
  74. // Ensure this SO is not in any cache, or we have an error. We must provide the type since it is a virutal function otherwise
  75. Assert( !GGCBase()->IsSOCached( this, nTypeID ) );
  76. #endif
  77. }
  78. virtual int GetTypeID() const { return nTypeID; }
  79. // WHERE IS YOUR GOD NOW
  80. template< typename T >
  81. using Public_Message_t = typename std::enable_if< bPublicMutable && std::is_same< T, Message_t >::value, Message_t & >::type;
  82. template< typename T >
  83. using Protected_Message_t = typename std::enable_if< !bPublicMutable && std::is_same< T, Message_t >::value, Message_t & >::type;
  84. template< typename T = Message_t >
  85. Public_Message_t<T> Obj() { return m_msgObject; }
  86. const Message_t & Obj() const { return m_msgObject; }
  87. typedef Message_t SchObjectType_t;
  88. const static int k_nTypeID = nTypeID;
  89. protected:
  90. template< typename T = Message_t >
  91. Protected_Message_t<T> MutObj() { return m_msgObject; }
  92. ::google::protobuf::Message *GetPObject() { return &m_msgObject; }
  93. private:
  94. Message_t m_msgObject;
  95. };
  96. //----------------------------------------------------------------------------
  97. // Purpose: Template for making a shared object that uses a specific protobuf
  98. // message class for its wire protocol and in-memory representation.
  99. //
  100. // The wrapper version of this class wraps a message allocated and
  101. // owned elsewhere. The user of this class is in charge of
  102. // guaranteeing that lifetime.
  103. //----------------------------------------------------------------------------
  104. template< typename Message_t, int nTypeID >
  105. class CProtoBufSharedObjectWrapper : public CProtoBufSharedObjectBase
  106. {
  107. public:
  108. CProtoBufSharedObjectWrapper( Message_t *pMsgToWrap )
  109. : m_pMsgObject( pMsgToWrap )
  110. {}
  111. ~CProtoBufSharedObjectWrapper()
  112. {
  113. #if defined( GC ) && defined( DEBUG )
  114. // Ensure this SO is not in any cache, or we have an error. We must provide the type since it is a virutal function otherwise
  115. Assert( !GGCBase()->IsSOCached( this, nTypeID ) );
  116. #endif
  117. }
  118. virtual int GetTypeID() const { return nTypeID; }
  119. Message_t & Obj() { return *m_pMsgObject; }
  120. const Message_t & Obj() const { return *m_pMsgObject; }
  121. typedef Message_t SchObjectType_t;
  122. public:
  123. const static int k_nTypeID = nTypeID;
  124. protected:
  125. ::google::protobuf::Message *GetPObject() { return m_pMsgObject; }
  126. private:
  127. Message_t *m_pMsgObject;
  128. };
  129. } // GCSDK namespace
  130. #endif //PROTOBUFSHAREDOBJECT_H