The output: templates that describe your packets

jwatte's picture

If you run the perl script, passing in the "Headers" module, it will print the declaration of your data structures to the console output. The included rules file lets you do this automatically as part of a Microsoft Visual Studio project, but for now, try doing it on the command line. If you don't have perl installed, get it either as part of Cygwin, or from ActiveState.

Because the system remembers different data structures you've defined, and defines message codes for each structure (to use to tell the other end what kind of data to expect), a file named Msg.codes needs to exist. You can create it as an empty file to start out. If you have Cygwin installed, that is easy using "touch Msg.codes" but you can do it in plain DOS with "copy con Msg.codes" and then entering Ctrl-Z.

Here are the commands I run:

touch Msg.codes
perl -MHeader Packets.pl

The output generated will use templates to describe the data structures. This is useful, because you can separate the layout/description of data from the actions taken on that data. If later you want to create some function that, say, prints your data to XML, then that would be easy, by just writing a new visitor that uses the template in question. See the next book page for a quick introduction to this method.

And here is the output:

/*
 * This file was auto-generated on 2008-11-15 11:07:13
 */
 
#if !defined(hdr_Packets_h)
#define hdr_Packets_h
 
#include "MsgBase.h"
 
struct Msg_SystemGreeting : public MsgBase {
  enum { Code = 1 };
  int GetCode() { return 1; }
  int major;
  int minor;
  std::string host;
  Msg_SystemGreeting() {
  }
  MsgMaker *Maker() { return &reg_; }
private:
  static MsgRegistration<Msg_SystemGreeting> reg_;
};
 
template<typename Visitor> bool Visit(Msg_SystemGreeting &arg, Visitor &v) {
  if (!v.Begin(arg, 1)) return false;
  if (!v.Visit(arg.major, "major", 0, 255)) return false;
  if (!v.Visit(arg.minor, "minor", 0, 255)) return false;
  if (!v.Visit(arg.host, "host")) return false;
  if (!v.End(arg, 1)) return false;
  return true;
}
 
 
struct Msg_LoginRequest : public MsgBase {
  enum { Code = 2 };
  int GetCode() { return 2; }
  int id;
  std::string name;
  std::string password;
  Msg_LoginRequest() {
  }
  MsgMaker *Maker() { return &reg_; }
private:
  static MsgRegistration<Msg_LoginRequest> reg_;
};
 
template<typename Visitor> bool Visit(Msg_LoginRequest &arg, Visitor &v) {
  if (!v.Begin(arg, 2)) return false;
  if (!v.Visit(arg.id, "id", 0, 32767)) return false;
  if (!v.Visit(arg.name, "name")) return false;
  if (!v.Visit(arg.password, "password")) return false;
  if (!v.End(arg, 2)) return false;
  return true;
}
 
 
struct Msg_LoginResult : public MsgBase {
  enum { Code = 3 };
  int GetCode() { return 3; }
  int id;
  int player;
  int result;
  std::string text;
  Msg_LoginResult() {
  }
  MsgMaker *Maker() { return &reg_; }
private:
  static MsgRegistration<Msg_LoginResult> reg_;
};
 
template<typename Visitor> bool Visit(Msg_LoginResult &arg, Visitor &v) {
  if (!v.Begin(arg, 3)) return false;
  if (!v.Visit(arg.id, "id", 0, 32767)) return false;
  if (!v.Visit(arg.player, "player", 0, 32767)) return false;
  if (!v.Visit(arg.result, "result", 0, 1)) return false;
  if (!v.Visit(arg.text, "text")) return false;
  if (!v.End(arg, 3)) return false;
  return true;
}
 
 
#endif // hdr_Packets_h