fixing some things
This commit is contained in:
+36
-15
@@ -2,10 +2,31 @@ const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
/// Point is a location within the matrix, (x,y)
|
||||
pub const Point = struct {
|
||||
x: usize,
|
||||
y: usize,
|
||||
};
|
||||
|
||||
/// Rect is a rectangle
|
||||
pub const Rect = struct {
|
||||
width: usize,
|
||||
height: usize,
|
||||
|
||||
pub fn area(self: *const @This()) usize {
|
||||
return self.width * self.height;
|
||||
}
|
||||
};
|
||||
|
||||
/// Area is the area
|
||||
pub const Area = struct {
|
||||
location: Point,
|
||||
size: Rect,
|
||||
};
|
||||
|
||||
/// Matrix is a part of the game board
|
||||
pub fn Matrix(comptime T: type, comptime width: usize, comptime height: usize) type {
|
||||
const size = width * height;
|
||||
const MatrixRowIterator = RowIterator(T, width);
|
||||
pub fn Matrix(comptime T: type, size: Rect) type {
|
||||
const MatrixRowIterator = RowIterator(T, size.width);
|
||||
|
||||
return struct {
|
||||
/// data is the game board itself.
|
||||
@@ -13,14 +34,14 @@ pub fn Matrix(comptime T: type, comptime width: usize, comptime height: usize) t
|
||||
|
||||
/// init creates the chunk, storing the bytes in memory.
|
||||
pub fn initZero(gpa: Allocator) !@This() {
|
||||
const data = try gpa.alloc(T, size);
|
||||
const data = try gpa.alloc(T, size.area());
|
||||
@memset(data, mem.zeroes(T));
|
||||
return .{ .data = data };
|
||||
}
|
||||
|
||||
/// init creates the chunk, storing the bytes in memory.
|
||||
pub fn init(gpa: Allocator, zero: T) !@This() {
|
||||
const data = try gpa.alloc(T, size);
|
||||
const data = try gpa.alloc(T, size.area());
|
||||
@memset(data, zero);
|
||||
return .{ .data = data };
|
||||
}
|
||||
@@ -31,14 +52,14 @@ pub fn Matrix(comptime T: type, comptime width: usize, comptime height: usize) t
|
||||
}
|
||||
|
||||
// set sets the value of the specified location in memory
|
||||
pub fn set(self: *@This(), x: usize, y: usize, val: T) void {
|
||||
const index = (width * y) + x;
|
||||
pub fn set(self: *@This(), loc: Point, val: T) void {
|
||||
const index = (size.width * loc.y) + loc.x;
|
||||
self.data[index] = val;
|
||||
}
|
||||
|
||||
// set sets the value of the specified location in memory
|
||||
pub fn get(self: *const @This(), x: usize, y: usize) T {
|
||||
const index = (width * y) + x;
|
||||
pub fn get(self: *const @This(), loc: Point) T {
|
||||
const index = (size.width * loc.y) + loc.x;
|
||||
return self.data[index];
|
||||
}
|
||||
|
||||
@@ -51,14 +72,14 @@ pub fn Matrix(comptime T: type, comptime width: usize, comptime height: usize) t
|
||||
test "TestMatrix" {
|
||||
const testing = std.testing;
|
||||
|
||||
var mat = try Matrix(u64, 10, 10).init(testing.allocator);
|
||||
var mat = try Matrix(u64, Rect{ .width = 10, .height = 10 }).initZero(testing.allocator);
|
||||
defer mat.deinit(testing.allocator);
|
||||
|
||||
mat.set(1, 1, 100);
|
||||
try testing.expectEqual(100, mat.get(1, 1));
|
||||
mat.set(Point{ .x = 1, .y = 1 }, 100);
|
||||
try testing.expectEqual(100, mat.get(Point{ .x = 1, .y = 1 }));
|
||||
}
|
||||
|
||||
pub fn RowIterator(comptime T: type, comptime width: usize) type {
|
||||
pub fn RowIterator(comptime T: type, width: usize) type {
|
||||
return struct {
|
||||
_index: usize,
|
||||
/// data is a reference to the board game data, now we will return it as
|
||||
@@ -88,11 +109,11 @@ pub fn RowIterator(comptime T: type, comptime width: usize) type {
|
||||
test "TestRowIterator" {
|
||||
const testing = std.testing;
|
||||
|
||||
var chunk = try Matrix(usize, 10, 10).init(testing.allocator);
|
||||
var chunk = try Matrix(usize, Rect{ .height = 10, .width = 10 }).initZero(testing.allocator);
|
||||
defer chunk.deinit(testing.allocator);
|
||||
|
||||
for (0..10) |x| {
|
||||
chunk.set(x, x, x);
|
||||
chunk.set(Point{ .x = x, .y = x }, x);
|
||||
}
|
||||
|
||||
var iter = chunk.row_iterator();
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
|
||||
const Allocator = mem.Allocator;
|
||||
const Matrix = @import("../grome/matrix.zig").Matrix;
|
||||
|
||||
/// DoubleBufferWriter manages two buffers for efficient rendering: a display buffer
|
||||
/// showing the current screen state, and a write buffer for accumulating changes
|
||||
/// that will be committed to the display on the next render cycle. This ABO
|
||||
/// approach minimizes unnecessary updates by only diffing changed cells.
|
||||
pub fn DoubleBufferWriter(width: usize, height: usize) type {
|
||||
return struct {
|
||||
// display holds the existing data.
|
||||
display: Matrix(Cell, width, height),
|
||||
// write is where we are writing the active changes which will be commited
|
||||
// on the next rendering
|
||||
write: Matrix(Cell, width, height),
|
||||
|
||||
pub fn init(gpa: Allocator, len: usize) DoubleBufferWriter {
|
||||
const display = gpa.alloc(Cell, len);
|
||||
const write = gpa.alloc(Cell, len);
|
||||
|
||||
return .{
|
||||
.display = display,
|
||||
.write = write,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This(), gpa: Allocator) void {
|
||||
gpa.free(self.display);
|
||||
gpa.free(self.write);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub const Cell = struct {
|
||||
char: [8]u8,
|
||||
width: usize,
|
||||
|
||||
/// eql returns
|
||||
pub fn eql(self: *const Cell, b: *const Cell) bool {
|
||||
return mem.eql(u8, self.char, b.char) and self.width == b.width;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user