Я пишу программу с архитектурой сервер-клиент, которая общается в основном через пакеты. Мне трудно придумать более красноречивый способ добиться этого.
Вот что у меня есть на данный момент:
namespace Packet {
enum class TCP {
PLAYER_JOINED,
PLAYER_QUIT,
MESSAGE_SENT
};
}
Наряду с этими функциями для преобразования типов в целочисленные коды и наоборот:
constexpr auto toInt(Packet::TCP _t) {
return static_cast<std::underlying_type_t<Packet::TCP>>(_t);
}
constexpr Packet::TCP toTCPType(int _i) {
return static_cast<Packet::TCP>(_i);
}
В моем коде менеджера сети в настоящее время у меня есть ужасный оператор switch, которого я хочу избежать. Вместо того, чтобы быть таким, как сейчас:
void sendPacket(Packet::TCP _type) {
int code{Packet::toInt(_type);
Packet p;
p << code;
switch (_type) {
case Packet::TCP::PLAYER_JOINED:
//do stuff and operate on p
break;
case Packet::TCP::PLAYER_QUIT:
//do stuff and operate on p
break;
//etc.
}
}
Я бы предпочел, чтобы это было что-то вроде этого:
void preparePacket(Packet::TCP _type) {
//common behaviour that has to be done no matter the type
int code{Packet::toInt(_type);
Packet p;
p << code;
sendPacket(_type, p);
}
Хотя я сталкиваюсь с несколькими препятствиями. Очевидно, я не могу перегрузить sendPacket значением перечисления TCP. Я мог бы заставить каждый перечислитель печатать свою собственную структуру, но затем я терял способность быстро преобразовывать Пакеты в int, что жизненно важно для получателя, чтобы знать, что это за пакет. Эту проблему можно решить, добавив виртуальную функцию getId (), но тогда это только одностороннее преобразование (Packet в int), тогда как мне также нужно каким-то образом преобразовать из int в Packet.