const std = @import("std"); const Interface = @import("./Interface.zig"); /// const Sequence = struct { /// const Self = @This(); /// commands: []Interface, /// pub fn init(alloc: std.mem.Allocator, commands: []const Interface) !Interface { const list = try alloc.dupe(Interface, commands); errdefer alloc.free(list); return try Interface.make(alloc, Self { .commands = list, }); } /// pub fn deinit(self: *Self, alloc: std.mem.Allocator) void { for (self.commands) |command| { command.deinit(); } alloc.free(self.commands); } /// pub fn apply(self: *Self, _: std.mem.Allocator) Interface.Error!void { for (self.commands) |command| { try command.apply(); } } /// pub fn revert(self: *Self, _: std.mem.Allocator) Interface.Error!void { var i = self.commands.len; while (i > 0) { i -= 1; try self.commands[i].revert(); } } }; test { var value1: i32 = 0; var value2: i32 = 0; var value3: i32 = 0; var finished1 = false; var finished2 = false; var finished3 = false; { var seq = blk: { const alloc = std.testing.allocator; var cmd1 = try Interface.Mock.init(alloc, &value1, &finished1); errdefer cmd1.deinit(); var cmd2 = try Interface.Mock.init(alloc, &value2, &finished2); errdefer cmd2.deinit(); var cmd3 = try Interface.Mock.init(alloc, &value3, &finished3); errdefer cmd3.deinit(); break :blk try Sequence.init(std.testing.allocator, &[_]Interface { cmd1, cmd2, cmd3, }); }; defer seq.deinit(); try seq.apply(); try std.testing.expectEqual(1, value1); try std.testing.expectEqual(1, value2); try std.testing.expectEqual(1, value3); try seq.revert(); try std.testing.expectEqual(0, value1); try std.testing.expectEqual(0, value2); try std.testing.expectEqual(0, value3); } try std.testing.expect(finished1); try std.testing.expect(finished2); try std.testing.expect(finished3); }