Skip to content

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;