restructuring
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const container = @import("root.zig");
|
||||
|
||||
const Allocator = mem.Allocator;
|
||||
const Rect = container.Rect;
|
||||
const Rowable = container.Rowable;
|
||||
const Point = container.Point;
|
||||
const SubMatrix = container.SubMatrix;
|
||||
const Error = container.Error;
|
||||
const RowIterator = container.RowIterator;
|
||||
|
||||
/// Matrix is a part of the game board
|
||||
pub fn Matrix(comptime T: type) type {
|
||||
return struct {
|
||||
/// data is the game board itself.
|
||||
data: []T,
|
||||
|
||||
/// defines the size of the matrix
|
||||
size: Rect,
|
||||
|
||||
/// Specifies the zero value to display when reseting the matrix
|
||||
zero: T,
|
||||
|
||||
rowable: Rowable(T),
|
||||
|
||||
/// init creates the chunk, storing the bytes in memory.
|
||||
pub fn initZero(gpa: Allocator, size: Rect) !@This() {
|
||||
return @This().init(gpa, mem.zeroes(T), size);
|
||||
}
|
||||
|
||||
/// init creates the chunk, storing the bytes in memory.
|
||||
pub fn init(gpa: Allocator, zero: T, size: Rect) !@This() {
|
||||
const data = try gpa.alloc(T, size.area());
|
||||
@memset(data, zero);
|
||||
var val = @This(){ .data = data, .size = size, .zero = zero, .rowable = .{ .rowFn = Matrix(T).row } };
|
||||
val.reset();
|
||||
return val;
|
||||
}
|
||||
|
||||
/// reset sets all values in the matrix back to the zero value.
|
||||
pub fn reset(self: *@This()) void {
|
||||
@memset(self.data, self.zero);
|
||||
}
|
||||
|
||||
/// deinit frees the memory utilized to create the chunk
|
||||
pub fn deinit(self: *const @This(), gpa: Allocator) void {
|
||||
gpa.free(self.data);
|
||||
}
|
||||
|
||||
// set sets the value of the specified location in memory
|
||||
pub fn set(self: *@This(), loc: Point, val: T) !void {
|
||||
(try self.getPtr(loc)).* = val;
|
||||
}
|
||||
|
||||
// set sets the value of the specified location in memory
|
||||
pub fn getPtr(self: *const @This(), loc: Point) !*T {
|
||||
if (loc.x >= self.size.width or loc.y >= self.size.height) {
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
const index = (self.size.width * loc.y) + loc.x;
|
||||
return &self.data[index];
|
||||
}
|
||||
|
||||
pub fn get(self: *const @This(), loc: Point) !T {
|
||||
return (try self.getPtr(loc)).*;
|
||||
}
|
||||
|
||||
/// submatrix returns a [SubMatrix]
|
||||
pub fn submatrix(self: *@This(), loc: Point, area: Rect) SubMatrix(T) {
|
||||
return SubMatrix(T).init(self, loc, area);
|
||||
}
|
||||
|
||||
// TODO: you were in the middle of debugging this
|
||||
pub fn row(interface: *Rowable(T), line: usize) ![]T {
|
||||
var self: *@This() = @fieldParentPtr("rowable", interface);
|
||||
const index = line * self.size.width;
|
||||
if (index >= self.data.len) {
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
return self.data[index .. index + self.size.width];
|
||||
}
|
||||
|
||||
pub fn row_iterator(self: *@This()) RowIterator(T) {
|
||||
return .init(&self.rowable);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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 },
|
||||
};
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
const container = @import("root.zig");
|
||||
|
||||
const Rect = container.Rect;
|
||||
|
||||
/// Point is a location within the matrix, (x,y)
|
||||
pub const Point = struct {
|
||||
x: usize,
|
||||
y: usize,
|
||||
|
||||
/// index returns the index in a flat array of the point givent he
|
||||
/// provided width.
|
||||
pub fn index(self: *const Point, width: usize) usize {
|
||||
return (self.y * width) + self.x;
|
||||
}
|
||||
|
||||
// add two points together and return the subsiquent point
|
||||
pub fn add(self: *const Point, b: Point) Point {
|
||||
return .{
|
||||
.x = self.x + b.x,
|
||||
.y = self.y + b.y,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn bottom_right(self: *const Point, area: Rect) Point {
|
||||
return .{
|
||||
.x = self.x + area.width,
|
||||
.y = self.y + area.height,
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
/// Rect is a rectangle
|
||||
pub const Rect = struct {
|
||||
width: usize,
|
||||
height: usize,
|
||||
|
||||
pub fn area(self: *const @This()) usize {
|
||||
return self.width * self.height;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
pub const Point = @import("point.zig").Point;
|
||||
pub const Rect = @import("rect.zig").Rect;
|
||||
pub const Rowable = @import("rowable.zig").Rowable;
|
||||
pub const Matrix = @import("matrix.zig").Matrix;
|
||||
pub const SubMatrix = @import("sub_matrix.zig").SubMatrix;
|
||||
pub const RowIterator = @import("row_iterator.zig").RowIterator;
|
||||
|
||||
// Error are all the errors that can exist for Container
|
||||
// types.
|
||||
pub const Error = error{
|
||||
OutOfBounds,
|
||||
};
|
||||
|
||||
test {
|
||||
@import("std").testing.refAllDecls(@This());
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const container = @import("root.zig");
|
||||
|
||||
const Rowable = container.Rowable;
|
||||
const Matrix = container.Matrix;
|
||||
const Rect = container.Rect;
|
||||
|
||||
pub fn RowIterator(comptime T: type) type {
|
||||
return struct {
|
||||
current: usize,
|
||||
/// data is a reference to the board game data, now we will return it as
|
||||
/// each row
|
||||
rows: *Rowable(T),
|
||||
|
||||
pub fn init(rowable: *Rowable(T)) @This() {
|
||||
return .{ .rows = rowable, .current = 0 };
|
||||
}
|
||||
|
||||
/// next returns the next row until we have exhausted the Rowable
|
||||
pub fn next(self: *@This()) ?[]T {
|
||||
defer self.current += 1;
|
||||
return self.rows.row(self.current) catch null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "TestRowIterator" {
|
||||
const testing = std.testing;
|
||||
|
||||
var m = try Matrix(usize).initZero(testing.allocator, Rect{ .height = 10, .width = 10 });
|
||||
defer m.deinit(testing.allocator);
|
||||
|
||||
for (0..10) |x| {
|
||||
try m.set(.{ .x = x, .y = x }, x);
|
||||
}
|
||||
|
||||
var iter = m.row_iterator();
|
||||
var x: usize = 0;
|
||||
while (iter.next()) |row| {
|
||||
const v: @Vector(10, usize) = row[0..10].*;
|
||||
try testing.expectEqual(x, @reduce(.Add, v));
|
||||
x += 1;
|
||||
}
|
||||
try testing.expectEqual(10, x);
|
||||
|
||||
var sub = m.submatrix(.{ .x = 5, .y = 5 }, .{ .width = 5, .height = 5 });
|
||||
var sub_iter = sub.row_iterator();
|
||||
x = 0;
|
||||
while (sub_iter.next()) |row| {
|
||||
const v: @Vector(5, usize) = row[0..5].*;
|
||||
try testing.expectEqual(x + 5, @reduce(.Add, v));
|
||||
x += 1;
|
||||
}
|
||||
try testing.expectEqual(5, x);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
const container = @import("root.zig");
|
||||
|
||||
const Error = container.Error;
|
||||
|
||||
/// Rowable is a type which can return a row at a time.
|
||||
pub fn Rowable(comptime T: type) type {
|
||||
return struct {
|
||||
rowFn: *const fn (self: *@This(), line: usize) Error![]T,
|
||||
|
||||
pub fn row(self: *@This(), line: usize) Error![]T {
|
||||
return self.rowFn(self, line);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const container = @import("root.zig");
|
||||
|
||||
const Rect = container.Rect;
|
||||
const Rowable = container.Rowable;
|
||||
const Point = container.Point;
|
||||
const Matrix = container.Matrix;
|
||||
const Error = container.Error;
|
||||
const RowIterator = container.RowIterator;
|
||||
|
||||
// SubMatrix is a subset of a matrix which you can traverse to
|
||||
pub fn SubMatrix(comptime T: type) type {
|
||||
return struct {
|
||||
// Data is made up of different sections of the
|
||||
_m: *Matrix(T),
|
||||
_offset: Point,
|
||||
_mask: Rect,
|
||||
//_width: usize,
|
||||
rowable: Rowable(T),
|
||||
|
||||
/// init takes the underlying data from the upstream matrix and creates
|
||||
/// a submatrix of it
|
||||
pub fn init(m: *Matrix(T), loc: Point, size: Rect) @This() {
|
||||
return .{ ._m = m, ._offset = loc, ._mask = size, .rowable = Rowable(T){ .rowFn = SubMatrix(T).row } };
|
||||
}
|
||||
|
||||
pub fn get(self: *const @This(), loc: Point) !T {
|
||||
return (try self.getPtr(loc)).*;
|
||||
}
|
||||
|
||||
pub fn getPtr(self: *const @This(), loc: Point) !*T {
|
||||
if (loc.x >= self._mask.width or loc.y >= self._mask.height) {
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
return self._m.getPtr(self._offset.add(loc));
|
||||
}
|
||||
|
||||
pub fn set(self: *@This(), loc: Point, val: T) !void {
|
||||
(try self.getPtr(loc)).* = val;
|
||||
}
|
||||
|
||||
pub fn row(interface: *Rowable(T), line: usize) ![]T {
|
||||
var self: *@This() = @fieldParentPtr("rowable", interface);
|
||||
if (line >= self._mask.height) {
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
// TODO: This can index out of bound
|
||||
// we need to checkt to make sure everything is copesedic
|
||||
var r = try self._m.rowable.row(line + self._offset.y);
|
||||
return r[self._offset.x .. self._offset.x + self._mask.width];
|
||||
}
|
||||
|
||||
pub fn row_iterator(self: *@This()) RowIterator(T) {
|
||||
return .init(&self.rowable);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "SubMatrix" {
|
||||
const testing = std.testing;
|
||||
|
||||
// create our matrix and submatrix
|
||||
var m = try Matrix(u8).initZero(testing.allocator, .{ .height = 10, .width = 10 });
|
||||
defer m.deinit(testing.allocator);
|
||||
var sub = m.submatrix(.{ .x = 4, .y = 4 }, .{ .height = 5, .width = 5 });
|
||||
try sub.set(.{ .x = 0, .y = 0 }, 'a');
|
||||
|
||||
// we should see the value updated in the Matrix
|
||||
try testing.expectEqual('a', try m.get(.{ .x = 4, .y = 4 }));
|
||||
}
|
||||
@@ -1,266 +0,0 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
pub const Error = error{
|
||||
OutOfBounds,
|
||||
};
|
||||
|
||||
/// Rowable is a type which can return a row at a time.
|
||||
fn Rowable(comptime T: type) type {
|
||||
return struct {
|
||||
rowFn: *const fn (self: *@This(), line: usize) Error![]T,
|
||||
|
||||
pub fn row(self: *@This(), line: usize) Error![]T {
|
||||
return self.rowFn(self, line);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Point is a location within the matrix, (x,y)
|
||||
pub const Point = struct {
|
||||
x: usize,
|
||||
y: usize,
|
||||
|
||||
/// index returns the index in a flat array of the point givent he
|
||||
/// provided width.
|
||||
pub fn index(self: *const Point, width: usize) usize {
|
||||
return (self.y * width) + self.x;
|
||||
}
|
||||
|
||||
// add two points together and return the subsiquent point
|
||||
pub fn add(self: *const Point, b: Point) Point {
|
||||
return .{
|
||||
.x = self.x + b.x,
|
||||
.y = self.y + b.y,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn bottom_right(self: *const Point, area: Rect) Point {
|
||||
return .{
|
||||
.x = self.x + area.width,
|
||||
.y = self.y + area.height,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Rect is a rectangle
|
||||
pub const Rect = struct {
|
||||
width: usize,
|
||||
height: usize,
|
||||
|
||||
pub fn area(self: *const @This()) usize {
|
||||
return self.width * self.height;
|
||||
}
|
||||
};
|
||||
|
||||
/// Matrix is a part of the game board
|
||||
pub fn Matrix(comptime T: type) type {
|
||||
return struct {
|
||||
/// data is the game board itself.
|
||||
data: []T,
|
||||
|
||||
/// defines the size of the matrix
|
||||
size: Rect,
|
||||
|
||||
/// Specifies the zero value to display when reseting the matrix
|
||||
zero: T,
|
||||
|
||||
rowable: Rowable(T),
|
||||
|
||||
/// init creates the chunk, storing the bytes in memory.
|
||||
pub fn initZero(gpa: Allocator, size: Rect) !@This() {
|
||||
return @This().init(gpa, mem.zeroes(T), size);
|
||||
}
|
||||
|
||||
/// init creates the chunk, storing the bytes in memory.
|
||||
pub fn init(gpa: Allocator, zero: T, size: Rect) !@This() {
|
||||
const data = try gpa.alloc(T, size.area());
|
||||
@memset(data, zero);
|
||||
var val = @This(){ .data = data, .size = size, .zero = zero, .rowable = .{ .rowFn = Matrix(T).row } };
|
||||
val.reset();
|
||||
return val;
|
||||
}
|
||||
|
||||
/// reset sets all values in the matrix back to the zero value.
|
||||
pub fn reset(self: *@This()) void {
|
||||
@memset(self.data, self.zero);
|
||||
}
|
||||
|
||||
/// deinit frees the memory utilized to create the chunk
|
||||
pub fn deinit(self: *const @This(), gpa: Allocator) void {
|
||||
gpa.free(self.data);
|
||||
}
|
||||
|
||||
// set sets the value of the specified location in memory
|
||||
pub fn set(self: *@This(), loc: Point, val: T) !void {
|
||||
(try self.getPtr(loc)).* = val;
|
||||
}
|
||||
|
||||
// set sets the value of the specified location in memory
|
||||
pub fn getPtr(self: *const @This(), loc: Point) !*T {
|
||||
if (loc.x >= self.size.width or loc.y >= self.size.height) {
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
const index = (self.size.width * loc.y) + loc.x;
|
||||
return &self.data[index];
|
||||
}
|
||||
|
||||
pub fn get(self: *const @This(), loc: Point) !T {
|
||||
return (try self.getPtr(loc)).*;
|
||||
}
|
||||
|
||||
/// submatrix returns a [SubMatrix]
|
||||
pub fn submatrix(self: *@This(), loc: Point, area: Rect) SubMatrix(T) {
|
||||
return SubMatrix(T).init(self, loc, area);
|
||||
}
|
||||
|
||||
// TODO: you were in the middle of debugging this
|
||||
pub fn row(interface: *Rowable(T), line: usize) ![]T {
|
||||
var self: *@This() = @fieldParentPtr("rowable", interface);
|
||||
const index = line * self.size.width;
|
||||
if (index >= self.data.len) {
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
return self.data[index .. index + self.size.width];
|
||||
}
|
||||
|
||||
pub fn row_iterator(self: *@This()) RowIterator(T) {
|
||||
return .init(&self.rowable);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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 },
|
||||
};
|
||||
|
||||
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
|
||||
pub fn SubMatrix(comptime T: type) type {
|
||||
return struct {
|
||||
// Data is made up of different sections of the
|
||||
_m: *Matrix(T),
|
||||
_offset: Point,
|
||||
_mask: Rect,
|
||||
//_width: usize,
|
||||
rowable: Rowable(T),
|
||||
|
||||
/// init takes the underlying data from the upstream matrix and creates
|
||||
/// a submatrix of it
|
||||
pub fn init(m: *Matrix(T), loc: Point, size: Rect) @This() {
|
||||
return .{ ._m = m, ._offset = loc, ._mask = size, .rowable = Rowable(T){ .rowFn = SubMatrix(T).row } };
|
||||
}
|
||||
|
||||
pub fn get(self: *const @This(), loc: Point) !T {
|
||||
return (try self.getPtr(loc)).*;
|
||||
}
|
||||
|
||||
pub fn getPtr(self: *const @This(), loc: Point) !*T {
|
||||
if (loc.x >= self._mask.width or loc.y >= self._mask.height) {
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
return self._m.getPtr(self._offset.add(loc));
|
||||
}
|
||||
|
||||
pub fn set(self: *@This(), loc: Point, val: T) !void {
|
||||
(try self.getPtr(loc)).* = val;
|
||||
}
|
||||
|
||||
pub fn row(interface: *Rowable(T), line: usize) ![]T {
|
||||
var self: *@This() = @fieldParentPtr("rowable", interface);
|
||||
if (line >= self._mask.height) {
|
||||
return Error.OutOfBounds;
|
||||
}
|
||||
|
||||
// TODO: This can index out of bound
|
||||
// we need to checkt to make sure everything is copesedic
|
||||
var r = try self._m.rowable.row(line + self._offset.y);
|
||||
return r[self._offset.x .. self._offset.x + self._mask.width];
|
||||
}
|
||||
|
||||
pub fn row_iterator(self: *@This()) RowIterator(T) {
|
||||
return .init(&self.rowable);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "SubMatrix" {
|
||||
const testing = std.testing;
|
||||
|
||||
// create our matrix and submatrix
|
||||
var m = try Matrix(u8).initZero(testing.allocator, .{ .height = 10, .width = 10 });
|
||||
defer m.deinit(testing.allocator);
|
||||
var sub = m.submatrix(.{ .x = 4, .y = 4 }, .{ .height = 5, .width = 5 });
|
||||
try sub.set(.{ .x = 0, .y = 0 }, 'a');
|
||||
|
||||
// we should see the value updated in the Matrix
|
||||
try testing.expectEqual('a', try m.get(.{ .x = 4, .y = 4 }));
|
||||
}
|
||||
|
||||
pub fn RowIterator(comptime T: type) type {
|
||||
return struct {
|
||||
current: usize,
|
||||
/// data is a reference to the board game data, now we will return it as
|
||||
/// each row
|
||||
rows: *Rowable(T),
|
||||
|
||||
fn init(rowable: *Rowable(T)) @This() {
|
||||
return .{ .rows = rowable, .current = 0 };
|
||||
}
|
||||
|
||||
/// next returns the next row until we have exhausted the Rowable
|
||||
pub fn next(self: *@This()) ?[]T {
|
||||
defer self.current += 1;
|
||||
return self.rows.row(self.current) catch null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "TestRowIterator" {
|
||||
const testing = std.testing;
|
||||
|
||||
var m = try Matrix(usize).initZero(testing.allocator, Rect{ .height = 10, .width = 10 });
|
||||
defer m.deinit(testing.allocator);
|
||||
|
||||
for (0..10) |x| {
|
||||
try m.set(.{ .x = x, .y = x }, x);
|
||||
}
|
||||
|
||||
var iter = m.row_iterator();
|
||||
var x: usize = 0;
|
||||
while (iter.next()) |row| {
|
||||
const v: @Vector(10, usize) = row[0..10].*;
|
||||
try testing.expectEqual(x, @reduce(.Add, v));
|
||||
x += 1;
|
||||
}
|
||||
try testing.expectEqual(10, x);
|
||||
|
||||
var sub = m.submatrix(.{ .x = 5, .y = 5 }, .{ .width = 5, .height = 5 });
|
||||
var sub_iter = sub.row_iterator();
|
||||
x = 0;
|
||||
while (sub_iter.next()) |row| {
|
||||
const v: @Vector(5, usize) = row[0..5].*;
|
||||
try testing.expectEqual(x + 5, @reduce(.Add, v));
|
||||
x += 1;
|
||||
}
|
||||
try testing.expectEqual(5, x);
|
||||
}
|
||||
+2
-2
@@ -2,8 +2,8 @@ const std = @import("std");
|
||||
const grome = @import("root.zig");
|
||||
|
||||
const Io = std.Io;
|
||||
const Rect = grome.matrix.Rect;
|
||||
const DoubleBuffer = grome.draw.DoubleBuffer;
|
||||
const Rect = grome.container.Rect;
|
||||
const DoubleBuffer = grome.view.DoubleBuffer;
|
||||
const Duration = Io.Duration;
|
||||
const Clock = Io.Clock;
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
const std = @import("std");
|
||||
pub const matrix = @import("grome/matrix.zig");
|
||||
pub const draw = @import("view/draw.zig");
|
||||
pub const container = @import("container/root.zig");
|
||||
pub const view = @import("view/root.zig");
|
||||
|
||||
test {
|
||||
std.testing.refAllDecls(@This());
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
|
||||
// Cell is a single cell in the [DoubleBuffer].
|
||||
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;
|
||||
}
|
||||
|
||||
pub fn render(self: *const @This(), w: *std.Io.Writer) !void {
|
||||
_ = try w.write(self.char[0..self.width]);
|
||||
}
|
||||
};
|
||||
@@ -4,10 +4,11 @@ const mem = std.mem;
|
||||
const grome = @import("../root.zig");
|
||||
|
||||
const Allocator = mem.Allocator;
|
||||
const Matrix = grome.matrix.Matrix;
|
||||
const SubMatrix = grome.matrix.SubMatrix;
|
||||
const Point = grome.matrix.Point;
|
||||
const Rect = grome.matrix.Rect;
|
||||
const Matrix = grome.container.Matrix;
|
||||
const SubMatrix = grome.container.SubMatrix;
|
||||
const Point = grome.container.Point;
|
||||
const Rect = grome.container.Rect;
|
||||
const Cell = grome.view.Cell;
|
||||
|
||||
/// DoubleBuffer manages two buffers for efficient rendering: a display buffer
|
||||
/// showing the current screen state, and a write buffer for accumulating changes
|
||||
@@ -98,17 +99,3 @@ pub const DoubleBuffer = struct {
|
||||
self.swap();
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
pub fn render(self: *const @This(), w: *std.Io.Writer) !void {
|
||||
_ = try w.write(self.char[0..self.width]);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
pub const DoubleBuffer = @import("double_buffer.zig").DoubleBuffer;
|
||||
pub const Cell = @import("cell.zig").Cell;
|
||||
|
||||
test {
|
||||
@import("std").testing.refAllDecls(@This());
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
const std = @import("std");
|
||||
const grome = @import("../root.zig");
|
||||
|
||||
const DoubleBuffer = grome.draw.DoubleBuffer;
|
||||
|
||||
pub const Viewport = struct {
|
||||
buffer: DoubleBuffer,
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
|
||||
const grome = @import("../root.zig");
|
||||
|
||||
/// A widget is an intrusive interface that allows the implementor to draw
|
||||
/// a specific item to a frame.
|
||||
pub const Widget = struct {};
|
||||
Reference in New Issue
Block a user