// The command stream: what the adapter writes, the renderer process reads back the same. #include #include #include "t5de/protocol/commands.hpp" using namespace t5de::protocol; namespace { int failures = 0; void check(bool ok, const char* what) { if (!ok) { std::printf("FAIL: %s\n", what); ++failures; } } } // namespace int main() { Writer writer; writer.add(Op::Clear, Clear{3, 0xff131313}); const unsigned char pixels[] = {1, 2, 3, 4, 5, 6, 7, 8}; std::memcpy(writer.add(Op::CreateTexture, CreateTexture{7, 2, 1, 6}, sizeof(pixels)), pixels, sizeof(pixels)); std::byte* odd = writer.add(Op::UpdateBuffer, UpdateBuffer{9, 1, 3}, 3); // padded to 4 std::memset(odd, 0xab, 3); writer.add(Op::EndFrame, EndFrame{}); check(writer.size() % 4 == 0, "commands stay 4-byte aligned"); Reader reader(writer.bytes()); auto clear = reader.next(); check(clear && clear->op() == Op::Clear && clear->body()->color == 0xff131313, "clear"); auto texture = reader.next(); check(texture && texture->op() == Op::CreateTexture && texture->body()->id == 7, "texture"); check(texture && texture->payload().size() == sizeof(pixels) && std::memcmp(texture->payload().data(), pixels, sizeof(pixels)) == 0, "texture pixels"); auto update = reader.next(); check(update && update->payload().size() == 4, "payload padded"); auto end = reader.next(); check(end && end->op() == Op::EndFrame, "end of frame"); check(!reader.next(), "nothing after"); // A truncated stream (a chunk cut short) yields only whole commands. Reader truncated(writer.bytes().first(writer.size() - 2)); int count = 0; while (truncated.next()) { ++count; } check(count == 3, "truncated: whole commands only"); if (failures == 0) { std::printf("ok\n"); } return failures == 0 ? 0 : 1; }