Tag-dispatch consume loop
Description
Tag-dispatch consume loop.
- Push one Event and one Sensor into a mixed-type list.
- Pop each node, check its tag.
- Recover the typed pointer with identifyNodeAs, process it.
- Free every item; count events and sensors separately.
Diagram
alloc.create (Event) ──► list
alloc.create (Sensor) ──► list
│ list.popFirst
▼
tag check ──► EventPolyHelper.identifyNodeAs or SensorPolyHelper.identifyNodeAs
│ freeItem per node
Source
pub fn tag_dispatch_consume_loop(allocator: std.mem.Allocator, io: std.Io) !void {
_ = io;
var list: std.DoublyLinkedList = .{};
defer freeRemaining(&list, allocator);
{
var slot: Slot = null;
try items.Event.EventPolyHelper.create(allocator, &slot);
items.Event.EventPolyHelper.mustIdentifySlotAs(&slot).code = 7;
list.append(&slot.?.*.node);
slot = null;
}
{
var slot: Slot = null;
try items.Sensor.SensorPolyHelper.create(allocator, &slot);
items.Sensor.SensorPolyHelper.mustIdentifySlotAs(&slot).value = 2.71;
list.append(&slot.?.*.node);
slot = null;
}
var processed_events: usize = 0;
var processed_sensors: usize = 0;
while (list.popFirst()) |node| {
const poly: *polynode.PolyNode = @fieldParentPtr("node", node);
if (items.Event.EventPolyHelper.identifyNodeAs(poly)) |recovered_ev| {
try helpers.expect(error.TagDispatchFailed, recovered_ev.*.code == 7, "wrong event code");
processed_events += 1;
items.freeItem(poly, allocator);
} else if (items.Sensor.SensorPolyHelper.identifyNodeAs(poly)) |recovered_sn| {
try helpers.expect(error.TagDispatchFailed, recovered_sn.*.value == 2.71, "wrong sensor value");
processed_sensors += 1;
items.freeItem(poly, allocator);
} else {
return error.UnknownTag;
}
}
try helpers.expect(error.TagDispatchFailed, processed_events == 1, "wrong event count");
try helpers.expect(error.TagDispatchFailed, processed_sensors == 1, "wrong sensor count");
}
fn freeRemaining(list: *std.DoublyLinkedList, alloc: std.mem.Allocator) void {
while (list.popFirst()) |node| {
const poly: *polynode.PolyNode = @fieldParentPtr("node", node);
items.freeItem(poly, alloc);
}
}
const items = @import("../items/items.zig");
const helpers = @import("../helpers/helpers.zig");
const polynode = @import("matryoshka").polynode;
const std = @import("std");
const Slot = polynode.Slot;