working on things
This commit is contained in:
+16
-6
@@ -87,6 +87,7 @@ pub fn Matrix(comptime T: type) type {
|
||||
// set sets the value of the specified location in memory
|
||||
pub fn set(self: *@This(), loc: Point, val: T) !void {
|
||||
if (loc.x >= self.size.width or loc.y >= self.size.height) {
|
||||
std.debug.print("loc.x ({d}) >= self.size.width ({d}) or loc.y ({d}) >= self.size.height ({d})", .{ loc.x, self.size.width, loc.y, self.size.height });
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
@@ -128,13 +129,22 @@ pub fn Matrix(comptime T: type) type {
|
||||
|
||||
test "TestMatrix" {
|
||||
const testing = std.testing;
|
||||
const tests = [_]struct {
|
||||
name: []const u8,
|
||||
size: Rect,
|
||||
point: Point,
|
||||
value: u64,
|
||||
}{
|
||||
.{ .name = "small", .size = .{ .width = 10, .height = 10 }, .point = .{ .x = 1, .y = 1 }, .value = 100 },
|
||||
.{ .name = "big", .size = .{ .width = 1000, .height = 1000 }, .point = .{ .x = 546, .y = 45 }, .value = 3472834 },
|
||||
};
|
||||
|
||||
var mat = try Matrix(u64).initZero(testing.allocator, Rect{ .width = 10, .height = 10 });
|
||||
defer mat.deinit(testing.allocator);
|
||||
|
||||
try mat.set(Point{ .x = 1, .y = 1 }, 100);
|
||||
try testing.expectEqualSlices(u64, ([_]u64{ 0, 100 } ++ ([_]u64{0} ** 8))[0..], try mat.rowable.row(1));
|
||||
try testing.expectEqual(100, try mat.get(Point{ .x = 1, .y = 1 }));
|
||||
inline for (tests) |case| {
|
||||
var mat = try Matrix(u64).initZero(testing.allocator, case.size);
|
||||
defer mat.deinit(testing.allocator);
|
||||
try mat.set(case.point, case.value);
|
||||
try testing.expectEqual(case.value, try mat.get(case.point));
|
||||
}
|
||||
}
|
||||
|
||||
// SubMatrix is a subset of a matrix which you can traverse to
|
||||
|
||||
+15
-26
@@ -1,9 +1,11 @@
|
||||
const std = @import("std");
|
||||
const grome = @import("grome");
|
||||
const grome = @import("root.zig");
|
||||
|
||||
const Io = std.Io;
|
||||
const Rect = grome.matrix.Rect;
|
||||
const DoubleBuffer = grome.draw.DoubleBuffer;
|
||||
const Duration = Io.Duration;
|
||||
const Clock = Io.Clock;
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
// This is appropriate for anything that lives as long as the process.
|
||||
@@ -12,34 +14,21 @@ pub fn main(init: std.process.Init) !void {
|
||||
// Initialize the stdout writer
|
||||
var stdout_buffer: [1024]u8 = undefined;
|
||||
var stdout_file_writer: Io.File.Writer = .init(.stdout(), init.io, &stdout_buffer);
|
||||
const stdout_writer = &stdout_file_writer.interface;
|
||||
|
||||
// alright lets play with the matrix
|
||||
const size = Rect{ .height = 20, .width = 50 };
|
||||
var matrix = try DoubleBuffer.init(arena, size);
|
||||
var double_buf = try DoubleBuffer.init(arena, size);
|
||||
|
||||
const density = (width * height) / 100;
|
||||
for (0..density) |_| {
|
||||
var buf: [3]u8 = undefined;
|
||||
init.io.random(&buf);
|
||||
matrix.set(@intCast(buf[0] % width), @intCast(buf[1] % height), @intCast((buf[2] % 50) + 93));
|
||||
const density = size.area() / 100;
|
||||
while (true) {
|
||||
var frame = double_buf.frame(.{ .x = 0, .y = 0 }, size);
|
||||
for (0..density) |_| {
|
||||
var buf: [3]u8 = undefined;
|
||||
init.io.random(&buf);
|
||||
try frame.set(.{ .x = @intCast(buf[0] % size.width), .y = @intCast(buf[1] % size.height) }, .{ .char = [_]u8{@intCast((buf[2] % 50) + 93)} ** 8, .width = 1 });
|
||||
}
|
||||
|
||||
_ = try double_buf.render(&stdout_file_writer.interface);
|
||||
try init.io.sleep(Duration.fromMilliseconds(100), Clock.real);
|
||||
}
|
||||
|
||||
_ = try stdout_writer.write(" ┌─");
|
||||
for (0..width) |_| {
|
||||
_ = try stdout_writer.write("─");
|
||||
}
|
||||
_ = try stdout_writer.write("─┐ \n");
|
||||
|
||||
while (iter.next()) |row| {
|
||||
_ = try stdout_writer.print(" │ {s} │ \n", .{row});
|
||||
}
|
||||
|
||||
_ = try stdout_writer.write(" └─");
|
||||
for (0..width) |_| {
|
||||
_ = try stdout_writer.write("─");
|
||||
}
|
||||
_ = try stdout_writer.write("─┘ \n");
|
||||
|
||||
try stdout_writer.flush();
|
||||
}
|
||||
|
||||
+33
-18
@@ -1,7 +1,7 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
|
||||
const grome = @import("root");
|
||||
const grome = @import("../root.zig");
|
||||
|
||||
const Allocator = mem.Allocator;
|
||||
const Matrix = grome.matrix.Matrix;
|
||||
@@ -15,20 +15,27 @@ const Rect = grome.matrix.Rect;
|
||||
/// approach minimizes unnecessary updates by only diffing changed cells.
|
||||
pub const DoubleBuffer = struct {
|
||||
// display holds the existing data.
|
||||
display: Matrix(Cell),
|
||||
a: Matrix(Cell),
|
||||
// write is where we are writing the active changes which will be commited
|
||||
// on the next rendering
|
||||
write: Matrix(Cell),
|
||||
b: Matrix(Cell),
|
||||
|
||||
// Front and back hold pointers to a and b, they will switch back and forth
|
||||
// based on what is needed.
|
||||
front: *Matrix(Cell),
|
||||
back: *Matrix(Cell),
|
||||
|
||||
pub fn init(gpa: Allocator, size: Rect) !DoubleBuffer {
|
||||
const display = try gpa.alloc(Cell, size.area());
|
||||
errdefer gpa.free(display);
|
||||
var a = try Matrix(Cell).init(gpa, .{ .char = [_]u8{' '} ** 8, .width = 1 }, size);
|
||||
errdefer a.deinit(gpa);
|
||||
|
||||
const write = try gpa.alloc(Cell, size.area());
|
||||
var b = try Matrix(Cell).init(gpa, .{ .char = [_]u8{' '} ** 8, .width = 1 }, size);
|
||||
|
||||
return .{
|
||||
.display = display,
|
||||
.write = write,
|
||||
.a = a,
|
||||
.b = b,
|
||||
.front = &a,
|
||||
.back = &b,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -37,19 +44,23 @@ pub const DoubleBuffer = struct {
|
||||
gpa.free(self.write);
|
||||
}
|
||||
|
||||
pub fn frame(m: Matrix, loc: Point, size: Rect) Frame {
|
||||
return .init(m, loc, size);
|
||||
pub fn frame(self: *@This(), loc: Point, size: Rect) SubMatrix(Cell) {
|
||||
return .init(self.back, loc, size);
|
||||
}
|
||||
};
|
||||
|
||||
/// Frame is a location in the matrix so you can change things if you want
|
||||
pub const Frame = struct {
|
||||
data: SubMatrix(Cell),
|
||||
pub fn render(self: *@This(), w: *std.Io.Writer) !usize {
|
||||
std.mem.swap(*Matrix(Cell), &self.front, &self.back);
|
||||
|
||||
pub fn init(m: Matrix, loc: Point, size: Rect) Frame {
|
||||
return .{
|
||||
.data = SubMatrix(Cell).init(m, loc, size),
|
||||
};
|
||||
var i = try w.write("\\033[H\\033[2J");
|
||||
var iter = self.front.row_iterator();
|
||||
while (iter.next()) |row| {
|
||||
for (row) |cell| {
|
||||
i += try cell.render(w);
|
||||
}
|
||||
i += try w.write("\n");
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -61,4 +72,8 @@ pub const Cell = struct {
|
||||
pub fn eql(self: *const Cell, b: *const Cell) bool {
|
||||
return mem.eql(u8, self.char, b.char) and self.width == b.width;
|
||||
}
|
||||
|
||||
pub fn render(self: *const @This(), w: *std.Io.Writer) !usize {
|
||||
return w.write(self.char[0..self.width]);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user