Added different textures for each ptolemaic camel rank
[0ad.git] / source / network / NMTCreator.h
blobf4ad582751e7165c735d0a538c5780c7e13cc136
1 /* Copyright (C) 2010 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #include "Serialization.h"
19 #include <vector>
21 // If included from within the NMT Creation process, perform a pass
22 #ifdef CREATING_NMT
24 #include NMT_CREATE_HEADER_NAME
26 #undef START_NMTS
27 #undef END_NMTS
28 #undef START_NMT_CLASS
29 #undef START_NMT_CLASS_DERIVED
30 #undef NMT_FIELD_INT
31 #undef NMT_FIELD
32 #undef NMT_START_ARRAY
33 #undef NMT_END_ARRAY
34 #undef END_NMT_CLASS
36 #else
37 // If not within the creation process, and called with argument, perform the
38 // creation process with the header specified
39 #ifdef NMT_CREATE_HEADER_NAME
41 #ifndef ARRAY_STRUCT_PREFIX
42 #define ARRAY_STRUCT_PREFIX(_nm) S_##_nm
43 #endif
45 #define CREATING_NMT
47 #ifndef NMT_CREATOR_IMPLEMENT
49 /*************************************************************************/
50 // Pass 1, class definition
51 #define NMT_CREATOR_PASS_CLASSDEF
52 #define START_NMTS()
53 #define END_NMTS()
55 #define START_NMT_CLASS(_nm, _tp) \
56 START_NMT_CLASS_DERIVED(CNetMessage, _nm, _tp)
58 /**
59 * Start the definition of a network message type.
61 * @param _base The name of the base class of the message
62 * @param _nm The name of the class
63 * @param _tp The NetMessageType associated with the class. It is *not* safe to
64 * have several classes with the same value of _tp in the same executable
66 #define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
67 CNetMessage *Deserialize##_nm(const u8 *, size_t); \
68 class _nm: public _base \
69 { \
70 protected: \
71 _nm(NetMessageType type): _base(type) {}\
73 /* This one is for subclasses that want to use the base class' string */ \
74 /* converters to get SubMessage { <parent fields>, ... } */ \
75 CStr ToStringRaw() const;\
76 public: \
77 _nm(): _base(_tp) {} \
78 virtual size_t GetSerializedLength() const; \
79 virtual u8 *Serialize(u8 *buffer) const; \
80 virtual const u8 *Deserialize(const u8 *pos, const u8 *end); \
81 virtual CStr ToString() const; \
82 inline operator CStr () const \
83 { return ToString(); }
85 /**
86 * Add an integer field to the message type.
88 * @param _nm The name of the field
89 * @param _hosttp The local type of the field (the data type used in the field
90 * definition)
91 * @param _netsz The number of bytes that should be serialized. If the variable
92 * has a value larger than the maximum value of the specified network size,
93 * higher order bytes will be discarded.
94 */
95 #define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
96 _hosttp _nm;
98 /**
99 * Add a generic field to the message type. The data type must be a class
100 * implementing the ISerializable interface
102 * @param _tp The local data type of the field
103 * @param _nm The name of the field
104 * @see ISerializable
106 #define NMT_FIELD(_tp, _nm) \
107 _tp _nm;
109 #define NMT_START_ARRAY(_nm) \
110 struct ARRAY_STRUCT_PREFIX(_nm); \
111 std::vector <ARRAY_STRUCT_PREFIX(_nm)> _nm; \
112 struct ARRAY_STRUCT_PREFIX(_nm) {
114 #define NMT_END_ARRAY() \
117 #define END_NMT_CLASS() };
119 #include "NMTCreator.h"
120 #undef NMT_CREATOR_PASS_CLASSDEF
122 #else // NMT_CREATOR_IMPLEMENT
124 #include "StringConverters.h"
126 /*************************************************************************/
127 // Pass 2, GetSerializedLength
128 #define NMT_CREATOR_PASS_GETLENGTH
129 #define START_NMTS()
130 #define END_NMTS()
132 #define START_NMT_CLASS(_nm, _tp) \
133 START_NMT_CLASS_DERIVED(CNetMessage, _nm, _tp)
134 #define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
135 size_t _nm::GetSerializedLength() const \
137 size_t ret=_base::GetSerializedLength(); \
138 const _nm *thiz=this;\
139 UNUSED2(thiz); // preempt any "unused" warning
141 #define NMT_START_ARRAY(_nm) \
142 std::vector <ARRAY_STRUCT_PREFIX(_nm)>::const_iterator it=_nm.begin(); \
143 while (it != _nm.end()) \
145 const ARRAY_STRUCT_PREFIX(_nm) *thiz=&*it;\
146 UNUSED2(thiz); // preempt any "unused" warning
148 #define NMT_END_ARRAY() \
149 ++it; \
152 #define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
153 ret += _netsz;
155 #define NMT_FIELD(_tp, _nm) \
156 ret += thiz->_nm.GetSerializedLength();
158 #define END_NMT_CLASS() \
159 return ret; \
162 #include "NMTCreator.h"
163 #undef NMT_CREATOR_PASS_GETLENGTH
165 /*************************************************************************/
166 // Pass 3, Serialize
168 #define NMT_CREATOR_PASS_SERIALIZE
170 #define START_NMTS()
171 #define END_NMTS()
173 #define START_NMT_CLASS(_nm, _tp) \
174 START_NMT_CLASS_DERIVED(CNetMessage, _nm, _tp)
175 #define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
176 u8 *_nm::Serialize(u8 *buffer) const \
178 /*printf("In " #_nm "::Serialize()\n");*/ \
179 u8 *pos=_base::Serialize(buffer); \
180 const _nm *thiz=this;\
181 UNUSED2(thiz); // preempt any "unused" warning
183 #define NMT_START_ARRAY(_nm) \
184 std::vector <ARRAY_STRUCT_PREFIX(_nm)>::const_iterator it=_nm.begin(); \
185 while (it != _nm.end()) \
187 const ARRAY_STRUCT_PREFIX(_nm) *thiz=&*it;\
188 UNUSED2(thiz); // preempt any "unused" warning
190 #define NMT_END_ARRAY() \
191 ++it; \
194 #define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
195 Serialize_int_##_netsz(pos, thiz->_nm); \
197 #define NMT_FIELD(_tp, _nm) \
198 pos=thiz->_nm.Serialize(pos);
200 #define END_NMT_CLASS() \
201 return pos; \
204 #include "NMTCreator.h"
206 #undef NMT_CREATOR_PASS_SERIALIZE
208 /*************************************************************************/
209 // Pass 4, Deserialize
211 #define NMT_CREATOR_PASS_DESERIALIZE
213 #define START_NMTS()
214 #define END_NMTS()
216 #define BAIL_DESERIALIZER return NULL
218 #define START_NMT_CLASS(_nm, _tp) \
219 START_NMT_CLASS_DERIVED(CNetMessage, _nm, _tp)
220 #define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
221 const u8 *_nm::Deserialize(const u8 *pos, const u8 *end) \
223 pos=_base::Deserialize(pos, end); \
224 _nm *thiz=this; \
225 /*printf("In Deserialize" #_nm "\n"); */\
226 UNUSED2(thiz); // preempt any "unused" warning
229 #define NMT_START_ARRAY(_nm) \
230 while (pos < end) \
232 ARRAY_STRUCT_PREFIX(_nm) *thiz=&*_nm.insert(_nm.end(), ARRAY_STRUCT_PREFIX(_nm)());\
233 UNUSED2(thiz); // preempt any "unused" warning
235 #define NMT_END_ARRAY() \
238 #define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
239 if (pos+_netsz > end) BAIL_DESERIALIZER; \
240 Deserialize_int_##_netsz(pos, thiz->_nm); \
241 /*printf("\t" #_nm " == 0x%x\n", thiz->_nm);*/
243 #define NMT_FIELD(_tp, _nm) \
244 if ((pos=thiz->_nm.Deserialize(pos, end)) == NULL) BAIL_DESERIALIZER;
246 #define END_NMT_CLASS() \
247 return pos; \
250 #include "NMTCreator.h"
252 #undef BAIL_DESERIALIZER
254 #undef NMT_CREATOR_PASS_DESERIALIZE
256 /*************************************************************************/
257 // Pass 5, String Representation
259 #define START_NMTS()
260 #define END_NMTS()
262 #define START_NMT_CLASS(_nm, _tp) \
263 CStr _nm::ToString() const \
265 CStr ret=#_nm " { "; \
266 return ret + ToStringRaw() + " }"; \
268 CStr _nm::ToStringRaw() const \
270 CStr ret; \
271 const _nm *thiz=this;\
272 UNUSED2(thiz); // preempt any "unused" warning
274 #define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
275 CStr _nm::ToString() const \
277 CStr ret=#_nm " { "; \
278 return ret + ToStringRaw() + " }"; \
280 CStr _nm::ToStringRaw() const \
282 CStr ret=_base::ToStringRaw() + ", "; \
283 const _nm *thiz=this;\
284 UNUSED2(thiz); // preempt any "unused" warning
286 #define NMT_START_ARRAY(_nm) \
287 ret+=#_nm ": { "; \
288 std::vector < ARRAY_STRUCT_PREFIX(_nm) >::const_iterator it=_nm.begin(); \
289 while (it != _nm.end()) \
291 ret+=" { "; \
292 const ARRAY_STRUCT_PREFIX(_nm) *thiz=&*it;\
293 UNUSED2(thiz); // preempt any "unused" warning
295 #define NMT_END_ARRAY() \
296 ++it; \
297 ret=ret.substr(0, ret.length()-2)+" }, "; \
299 ret=ret.substr(0, ret.length()-2)+" }, ";
301 #define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
302 ret += #_nm ": "; \
303 ret += NetMessageStringConvert(thiz->_nm); \
304 ret += ", ";
306 #define NMT_FIELD(_tp, _nm) \
307 ret += #_nm ": "; \
308 ret += NetMessageStringConvert(thiz->_nm); \
309 ret += ", ";
311 #define END_NMT_CLASS() \
312 return ret.substr(0, ret.length()-2); \
315 #include "NMTCreator.h"
317 #endif // #ifdef NMT_CREATOR_IMPLEMENT
319 /*************************************************************************/
320 // Cleanup
321 #undef NMT_CREATE_HEADER_NAME
322 #undef NMT_CREATOR_IMPLEMENT
323 #undef CREATING_NMT
325 #endif // #ifdef NMT_CREATE_HEADER_NAME
326 #endif // #ifndef CREATING_NMT