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