混合解析系统¶
解析循环的第三种变体可能是前两种的混合,在函数调用后使用 switch() 语句。这是另一个假设函数:
void processNextPacket()
{
if (!network->packetReady()) return;
auto packet = network->getPacket();
auto data = packet->decrypt();
dispatchPacket(data);
void dispatchPacket(data)
{
switch (data->getType()) {
case PACKET_HEALTH_CHANGE:
processHealthChangePacket(data->getMessage()
);
break;
case PACKET_MANA_CHANGE:
processManaChangePacket(data->getMessage());
break;
// 更多数据类型
}
}
processNextPacket() 函数获取新数据包并调用 dispatchPacket() 处理数据。这种情况下,dispatchPacket() 函数存在于每个处理程序的调用栈中,但不在 recv() 函数的调用栈中。例如,看看表 10-2 中的假设栈。
recv() 栈onHealthChange() 栈onManaChange() 栈
虽然这三个函数在调用栈中有相同的前四个地址,但只有两个处理程序还有一个公共地址(同样用粗体显示)。那是 0x00ABCDEF,它是 dispatchPacket() 函数的地址。同样,你可以想象它们以树视图排列,如图 10-2 所示。
0x101E1337 ─ onHealthChange() 0x14141414 ─
onManaChange()
0x0BADF00D - recv()
0x40404040 - network->getPacket() 0x0ABCDEF -
dispatchPacket()
0xDEADBEEF - parseNextPacket()
0x20202020 - executeFrame()
0x10101010 - main()
图 10-2 三个调用栈的树视图