15 std::optional<clock::time_point> received_at;
16 bool fresh(clock::time_point now, clock::duration timeout)
const {
17 return received_at && now >= *received_at && now - *received_at <= timeout;
19 void set(T next, clock::time_point now) { value = next; received_at = now; }
27 std::uint8_t robot_id {}, level {};
28 std::uint16_t hp {}, max_hp {}, cooling_rate {}, cooling_limit {}, chassis_power_limit {};
29 bool gimbal_power {}, chassis_power {}, shooter_power {};
53 bool accept(
const frame& input, clock::time_point now) {
54 const bytes p{input.payload};
55 switch (input.command) {
57 if (p.size() != 11 || (u8(p[0]) >> 4) > 5)
return false;
58 game.set({
static_cast<std::uint8_t
>(u8(p[0]) & 0x0f),
59 static_cast<std::uint8_t
>(u8(p[0]) >> 4), u16(p, 1),
60 u32(p, 3) | (std::uint64_t{u32(p, 7)} << 32)}, now);
63 if (p.size() != 1 || u8(p[0]) > 2)
return false;
64 winner.set(u8(p[0]), now);
67 if (p.size() != 32)
return false;
68 std::array<std::uint16_t, 16> hp{};
69 for (std::size_t i = 0; i < hp.size(); ++i) hp[i] = u16(p, i * 2);
70 robot_hp.set(hp, now);
74 if (p.size() != 3)
return false;
75 warning.set({u8(p[0]), u8(p[1]), u8(p[2])}, now);
78 if (p.size() != 13 || u8(p[0]) == 0 || (u8(p[12]) & 0xf8))
return false;
79 robot.set({u8(p[0]), u8(p[1]), u16(p, 2), u16(p, 4), u16(p, 6),
80 u16(p, 8), u16(p, 10), bool(u8(p[12]) & 1), bool(u8(p[12]) & 2),
81 bool(u8(p[12]) & 4)}, now);
85 if (p.size() != 16)
return false;
86 power.set({u16(p, 8), u16(p, 10), u16(p, 12), u16(p, 14)}, now);
89 if (p.size() != 12)
return false;
91 std::bit_cast<float>(u32(p, 4)), std::bit_cast<float>(u32(p, 8))};
92 if (!std::isfinite(next.x) || !std::isfinite(next.y) || !std::isfinite(next.yaw))
return false;
93 position.set(next, now);
97 if (p.size() != 7)
return false;
98 const auto speed = std::bit_cast<float>(u32(p, 3));
99 if (!std::isfinite(speed) || speed < 0 || u8(p[0]) < 1 || u8(p[0]) > 2)
return false;
100 shot.set({u8(p[0]), u8(p[1]), u8(p[2]), speed}, now);
104 if (p.size() != 6)
return false;
105 ammunition.set({u16(p, 0), u16(p, 2), u16(p, 4)}, now);