Trending
Opinion: How will Project 2025 impact game developers?
The Heritage Foundation's manifesto for the possible next administration could do great harm to many, including large portions of the game development community.
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.
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:
You May Also Like