this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

screen: use unmanager arraylists for InternalStreen

Why didn't I do this earlier? This results in about a 20% memory savings
when testing out the examples. We have 3 arraylists per Cell, so for
each cell we now save usize * 3 = 192 bytes, for my typical full screen
terminal I have 239 x 47 cells. That's a total of 2.1Mb!

+21 -20
+18 -18
src/InternalScreen.zig
··· 10 10 const InternalScreen = @This(); 11 11 12 12 pub const InternalCell = struct { 13 - char: std.ArrayList(u8) = undefined, 13 + char: std.ArrayListUnmanaged(u8) = .empty, 14 14 style: Style = .{}, 15 - uri: std.ArrayList(u8) = undefined, 16 - uri_id: std.ArrayList(u8) = undefined, 15 + uri: std.ArrayListUnmanaged(u8) = .empty, 16 + uri_id: std.ArrayListUnmanaged(u8) = .empty, 17 17 // if we got skipped because of a wide character 18 18 skipped: bool = false, 19 19 default: bool = true, ··· 32 32 } 33 33 }; 34 34 35 + arena: *std.heap.ArenaAllocator = undefined, 35 36 width: u16 = 0, 36 37 height: u16 = 0, 37 38 ··· 46 47 47 48 /// sets each cell to the default cell 48 49 pub fn init(alloc: std.mem.Allocator, w: u16, h: u16) !InternalScreen { 50 + const arena = try alloc.create(std.heap.ArenaAllocator); 51 + arena.* = .init(alloc); 49 52 var screen = InternalScreen{ 50 - .buf = try alloc.alloc(InternalCell, @as(usize, @intCast(w)) * h), 53 + .arena = arena, 54 + .buf = try arena.allocator().alloc(InternalCell, @as(usize, @intCast(w)) * h), 51 55 }; 52 56 for (screen.buf, 0..) |_, i| { 53 57 screen.buf[i] = .{ 54 - .char = try std.ArrayList(u8).initCapacity(alloc, 1), 55 - .uri = std.ArrayList(u8).init(alloc), 56 - .uri_id = std.ArrayList(u8).init(alloc), 58 + .char = try std.ArrayListUnmanaged(u8).initCapacity(arena.allocator(), 1), 59 + .uri = .empty, 60 + .uri_id = .empty, 57 61 }; 58 - try screen.buf[i].char.append(' '); 62 + screen.buf[i].char.appendAssumeCapacity(' '); 59 63 } 60 64 screen.width = w; 61 65 screen.height = h; ··· 63 67 } 64 68 65 69 pub fn deinit(self: *InternalScreen, alloc: std.mem.Allocator) void { 66 - for (self.buf, 0..) |_, i| { 67 - self.buf[i].char.deinit(); 68 - self.buf[i].uri.deinit(); 69 - self.buf[i].uri_id.deinit(); 70 - } 71 - 72 - alloc.free(self.buf); 70 + self.arena.deinit(); 71 + alloc.destroy(self.arena); 72 + self.* = undefined; 73 73 } 74 74 75 75 /// writes a cell to a location. 0 indexed ··· 90 90 const i = (@as(usize, @intCast(row)) * self.width) + col; 91 91 assert(i < self.buf.len); 92 92 self.buf[i].char.clearRetainingCapacity(); 93 - self.buf[i].char.appendSlice(cell.char.grapheme) catch { 93 + self.buf[i].char.appendSlice(self.arena.allocator(), cell.char.grapheme) catch { 94 94 log.warn("couldn't write grapheme", .{}); 95 95 }; 96 96 self.buf[i].uri.clearRetainingCapacity(); 97 - self.buf[i].uri.appendSlice(cell.link.uri) catch { 97 + self.buf[i].uri.appendSlice(self.arena.allocator(), cell.link.uri) catch { 98 98 log.warn("couldn't write uri", .{}); 99 99 }; 100 100 self.buf[i].uri_id.clearRetainingCapacity(); 101 - self.buf[i].uri_id.appendSlice(cell.link.params) catch { 101 + self.buf[i].uri_id.appendSlice(self.arena.allocator(), cell.link.params) catch { 102 102 log.warn("couldn't write uri_id", .{}); 103 103 }; 104 104 self.buf[i].style = cell.style;
+1
src/Screen.zig
··· 44 44 @memset(self.buf, base_cell); 45 45 return self; 46 46 } 47 + 47 48 pub fn deinit(self: *Screen, alloc: std.mem.Allocator) void { 48 49 alloc.free(self.buf); 49 50 }
+2 -2
src/Vaxis.zig
··· 51 51 screen: Screen, 52 52 /// The last screen we drew. We keep this so we can efficiently update on 53 53 /// the next render 54 - screen_last: InternalScreen = undefined, 54 + screen_last: InternalScreen, 55 55 56 56 caps: Capabilities = .{}, 57 57 ··· 103 103 return .{ 104 104 .opts = opts, 105 105 .screen = .{}, 106 - .screen_last = .{}, 106 + .screen_last = try .init(alloc, 80, 24), 107 107 .unicode = try Unicode.init(alloc), 108 108 }; 109 109 }