1
0
forked from 0ad/0ad
0ad/source/ps/Network/NMTCreator.h

172 lines
4.2 KiB
C
Raw Normal View History

#include "Serialization.h"
// If included from within the NMT Creation process, perform a pass
#ifdef CREATING_NMT
#include NMT_CREATE_HEADER_NAME
#undef START_NMTS
#undef END_NMTS
#undef START_NMT_CLASS
#undef NMT_FIELD_INT
#undef NMT_FIELD
#undef END_NMT_CLASS
#else
// If not within the creation process, and called with argument, perform the
// creation process with the header specified
#ifdef NMT_CREATE_HEADER_NAME
#define CREATING_NMT
/*************************************************************************/
// Pass 1, class definition
#define START_NMTS()
#define END_NMTS()
/**
* Start the definition of a network message type.
*
* @param _nm The name of the class
* @param _tp The NetMessageType associated with the class. IT is *not* safe to
* have several classes with the same value of _tp in the same executable
*/
#define START_NMT_CLASS(_nm, _tp) \
CNetMessage *Deserialize##_nm(const u8 *, uint); \
struct _nm: public CNetMessage \
{ \
_nm(): CNetMessage(_tp) {} \
virtual uint GetSerializedLength() const; \
virtual void Serialize(u8 *buffer) const;
/**
* Add an integer field to the message type.
*
* @param _nm The name of the field
* @param _hosttp The local type of the field (the data type used in the field
* definition)
* @param _netsz The number of bytes that should be serialized. If the variable
* has a value larger than the maximum value of the specified network size,
* higher order bytes will be discarded.
*/
#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
_hosttp _nm;
/**
* Add a generic field to the message type. The data type must be a class
* implementing the ISerializable interface
*
* @param _tp The local data type of the field
* @param _nm The name of the field
* @see ISerializable
*/
#define NMT_FIELD(_tp, _nm) \
_tp _nm;
#define END_NMT_CLASS() };
#include "NMTCreator.h"
#ifdef NMT_CREATOR_IMPLEMENT
/*************************************************************************/
// Pass 2, GetSerializedLength
#define START_NMTS()
#define END_NMTS()
#define START_NMT_CLASS(_nm, _tp) \
uint _nm::GetSerializedLength() const \
{ \
uint ret=0;
#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
ret += _netsz;
#define NMT_FIELD(_tp, _nm) \
ret += _nm.GetSerializedLength();
#define END_NMT_CLASS() \
return ret; \
};
#include "NMTCreator.h"
/*************************************************************************/
// Pass 3, Serialize
#define START_NMTS()
#define END_NMTS()
#define START_NMT_CLASS(_nm, _tp) \
void _nm::Serialize(u8 *buffer) const \
{ \
/*printf("In " #_nm "::Serialize()\n");*/ \
u8 *pos=buffer; \
#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
Serialize_int_##_netsz(pos, _nm); \
#define NMT_FIELD(_tp, _nm) \
pos=_nm.Serialize(pos);
#define END_NMT_CLASS() }
#include "NMTCreator.h"
/*************************************************************************/
// Pass 4, Deserialize
#define START_NMTS()
#define END_NMTS()
#define BAIL_DESERIALIZER STMT( delete ret; return NULL; )
#define START_NMT_CLASS(_nm, _tp) \
CNetMessage *Deserialize##_nm(const u8 *buffer, uint length) \
{ \
/*printf("In Deserialize" #_nm "\n"); */\
_nm *ret=new _nm(); \
const u8 *pos=buffer; \
const u8 *end=buffer+length; \
#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
if (pos+_netsz >= end) BAIL_DESERIALIZER; \
Deserialize_int_##_netsz(pos, (ret->_nm)); \
/*printf("\t" #_nm " == 0x%x\n", ret->_nm);*/
#define NMT_FIELD(_tp, _nm) \
if ((pos=ret->_nm.Deserialize(pos, end)) == NULL) BAIL_DESERIALIZER;
#define END_NMT_CLASS() \
return ret; \
}
#include "NMTCreator.h"
#undef BAIL_DESERIALIZER
/*************************************************************************/
// Pass 5, Deserializer Registration
#define START_NMTS() SNetMessageDeserializerRegistration g_DeserializerRegistrations[] = {
#define END_NMTS() { NMT_NONE, NULL } };
#define START_NMT_CLASS(_nm, _tp) \
{ _tp, Deserialize##_nm },
#define NMT_FIELD_INT(_nm, _hosttp, _netsz)
#define NMT_FIELD(_tp, _nm)
#define END_NMT_CLASS()
#include "NMTCreator.h"
#endif // #ifdef NMT_CREATOR_IMPLEMENT
/*************************************************************************/
// Cleanup
#undef NMT_CREATE_HEADER_NAME
#undef NMT_CREATOR_IMPLEMENT
#undef CREATING_NMT
#endif // #ifdef NMT_CREATE_HEADER_NAME
#endif // #ifndef CREATING_NMT