Sponsored By

Switches & Enumerations Shortcut

A programming shortcut when dealing with a large enumeration, processed by a switch statement. A rare corner case, but I thought it might be useful to somebody.

Kayne Ruse, Blogger

February 27, 2015

2 Min Read
Game Developer logo in a gray background | Game Developer

This is a crosspost from my dev blog KR Game Studios. I've edited it for grammar and clarity.

This is a rare situration that not many programmers will come across, but since I did, I figured I'd write up a solution for those who do.

I had an enumeration with roughly 40 unique values, representing the type of message sent across a game network. To determine how to process the different types, I was using a massive switch statement like this:


switch(packet->type) {
  case PacketType::CHARACTER_CREATE:
  case PacketType::CHARACTER_DELETE:
  case PacketType::CHARACTER_LOAD:
  case PacketType::CHARACTER_UNLOAD:
  ...
    serializeCharacter(packet);
  break;
  case SerialPacketType::MONSTER_CREATE:
  ...
}

You get the idea.

The problem was that every time I added to the enumeration, I had to update the switch statements to match; that's plural, by the way, becuase I had a second nearly identical switch statement for deserializing the messages on the other end.

I had been working with this pattern for roughly a year and a half; iterating on the code as I went along, until I was struck with a realization: I could simply add boundry indicators to the enumeration to highlight groups of packet types.

Once I had these, I could add new packet types to the enumeration without modifying any massive switch statements; I only had to modify the pseudo-switch statements when I add a new group of packet types.

Enough talk, here's the example:


//DOCS: FORMAT_* is for internal use
enum PacketType {
  //login/logout protocol
  FORMAT_LOGIN,

  LOGIN_REQUEST,
  LOGIN_RESPONSE,
  LOGIN_REJECTION,
  LOGOUT_REQUEST,
  LOGOUT_RESPONSE,

  FORMAT_END_LOGIN,

  //character protocol
  FORMAT_CHARACTER,

  CHARACTER_CREATE,
  CHARACTER_DELETE,
  CHARACTER_LOAD,
  CHARACTER_UNLOAD,
  ...

  FORMAT_END_CHARACTER,

  //monster protocol
  FORMAT_MONSTER,

  MONSTER_CREATE,
  MONSTER_DELETE,
  ...

  FORMAT_END_MONSTER,

  ...
};

int serialize(Packet packet) {
  //login/logout protocol
  if (packet->type > PacketType::FORMAT_LOGIN &&
      packet->type < PacketType::FORMAT_END_LOGIN) {
    return serializeLogin(packet);
  }

  //chacacter protocol
  if (packet->type > PacketType::FORMAT_CHARACTER &&
      packet->type < PacketType::FORMAT_END_CHARACTER) {
    return serializeCharacter(packet);
  }

  //monster protocol
  if (packet->type > PacketType::FORMAT_MONSTER &&
      packet->type < PacketType::FORMAT_END_MONSTER) {
    return serializeMonster(packet);
  }

  //there's an error somewhere
  return -1;
}

When not wrestling with the markdown editor, I'm programming an MMORPG from scrach called Tortuga, which can be found at krgamestudios.com. You can follow the major updates here: @KRGameStudios.

P.S. If you want to see the actual code (which might be clearer), here they are:

Read more about:

2015Blogs

About the Author

Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like