fixed the "leak". We were de-initializing the allocator before we de-initialized the things allocated with it.

This commit is contained in:
Vicente Ferrari Smith 2026-01-23 00:04:13 +01:00
parent fd71b631c4
commit 1140905a4f
7 changed files with 123 additions and 69 deletions

19
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Launch",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/zig-out/bin/client",
"args": [],
"cwd": "${workspaceFolder}",
"internalConsoleOptions": "openOnSessionStart",
"preLaunchTask": "build",
"sourceLanguages": ["zig"]
}
]
}

17
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,17 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "zig build",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

View File

@ -59,9 +59,13 @@ pub fn build(b: *std.Build) void {
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
.imports = &.{ .imports = &.{
.{ .name = "shared", .module = shared }, .{
.name = "shared",
.module = shared
}, },
}) },
}),
.use_llvm = true,
}); });
const server = b.addExecutable(.{ const server = b.addExecutable(.{
@ -74,10 +78,11 @@ pub fn build(b: *std.Build) void {
.{ .name = "shared", .module = shared }, .{ .name = "shared", .module = shared },
}, },
}), }),
.use_llvm = true,
}); });
const freetype_module = b.addModule("mach-freetype", .{ const freetype_module = b.addModule("mach-freetype", .{
.root_source_file = b.path("src/freetype/freetype.zig"), .root_source_file = b.path("vendor/mach-freetype/src/freetype.zig"),
}); });
if (b.lazyDependency("freetype", .{ if (b.lazyDependency("freetype", .{
@ -115,16 +120,19 @@ pub fn build(b: *std.Build) void {
server.root_module.addImport("zmath", zmath.module("root")); server.root_module.addImport("zmath", zmath.module("root"));
shared.addImport("zmath", zmath.module("root")); shared.addImport("zmath", zmath.module("root"));
const znet_dep = b.dependency("znet", .{ const znet_dep = b.dependency(
"znet",
.{
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
}); }
);
const znet_mod = znet_dep.module("znet"); const znet_mod = znet_dep.module("znet");
const znet_artifact = znet_dep.artifact("znet"); // const znet_artifact = znet_dep.artifact("znet");
client.root_module.addImport("znet", znet_mod); client.root_module.addImport("znet", znet_mod);
client.linkLibrary(znet_artifact); // client.linkLibrary(znet_artifact);
server.root_module.addImport("znet", znet_mod); server.root_module.addImport("znet", znet_mod);
server.linkLibrary(znet_artifact); // server.linkLibrary(znet_artifact);
const bufzilla = b.dependency("bufzilla", .{}); const bufzilla = b.dependency("bufzilla", .{});
client.root_module.addImport("bufzilla", bufzilla.module("bufzilla")); client.root_module.addImport("bufzilla", bufzilla.module("bufzilla"));

View File

@ -24,45 +24,53 @@ const screen_height = 720;
var running: bool = true; var running: bool = true;
var dbg_allocator: std.heap.DebugAllocator(.{}) = undefined; var dbg_allocator = std.heap.DebugAllocator(.{}){};
const allocator = dbg_allocator.allocator();
var stdout: *std.io.Writer = undefined;
// var connection: ?std.net.Stream = undefined; // var connection: ?std.net.Stream = undefined;
pub fn main() !void { pub fn main() !void {
std.log.info("Hello Client!", .{});
try init(); const allocator = dbg_allocator.allocator();
defer {
const deinit_status = dbg_allocator.deinit();
if (deinit_status == .leak) {
@panic("LEAKED!");
} else {
// @panic("SUCCESS!");
}
}
var stdout = std.fs.File.stdout();
_ = try stdout.write("Hello, Client!\n");
try znet.init(); try znet.init();
defer znet.deinit(); defer znet.deinit();
rl.setConfigFlags(.{ .window_highdpi = true }); rl.setConfigFlags(.{ .window_highdpi = true, .vsync_hint = true });
rl.initWindow(screen_width, screen_height, "zzz"); rl.initWindow(screen_width, screen_height, "zzz");
defer rl.closeWindow(); defer rl.closeWindow();
font.ft_lib = try ft.Library.init(); font.ft_lib = try ft.Library.init();
const sizes = [_]u32{ const sizes = [_]i32{
12, 13, 14, 15, 16, 12, 14, 16, 18, 20,
18, 20, 22,
}; };
var vollkorn: [sizes.len]font.Font = undefined; var vollkorn: [sizes.len]font.Font = undefined;
// var inconsolata: [sizes.len]font.Font = undefined; var inconsolata: [sizes.len]font.Font = undefined;
// var arabic: [sizes.len]font.Font = undefined; // var arabic: [sizes.len]font.Font = undefined;
// var japanese: [sizes.len]font.Font = undefined; // var japanese: [sizes.len]font.Font = undefined;
for (sizes, 0..) |pt, i| { for (sizes, 0..) |pt, i| {
vollkorn[i] = try font.Font.init("assets/fonts/Vollkorn/static/Vollkorn-Regular.ttf", @intCast(pt), allocator); vollkorn[i] = try font.Font.init("assets/fonts/Vollkorn/static/Vollkorn-Regular.ttf", pt, allocator);
// inconsolata[i] = try font.Font.init("assets/fonts/Inconsolata/static/Inconsolata-Regular.ttf", @intCast(pt), allocator); inconsolata[i] = try font.Font.init("assets/fonts/Inconsolata/static/Inconsolata-Regular.ttf", @intCast(pt), allocator);
// arabic[i] = try font.Font.init("assets/fonts/Noto_Sans_Arabic/static/NotoSansArabic-Regular.ttf", @intCast(pt), allocator); // arabic[i] = try font.Font.init("assets/fonts/Noto_Sans_Arabic/static/NotoSansArabic-Regular.ttf", @intCast(pt), allocator);
// japanese[i] = try font.Font.init("assets/fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf", @intCast(pt), allocator); // japanese[i] = try font.Font.init("assets/fonts/Noto_Sans_JP/static/NotoSansJP-Regular.ttf", @intCast(pt), allocator);
} }
defer { defer {
for (&vollkorn) |*f| f.deinit(allocator); for (&vollkorn) |*f| f.deinit(allocator);
// for (&inconsolata) |*f| f.deinit(allocator); for (&inconsolata) |*f| f.deinit(allocator);
// for (&arabic) |*f| f.deinit(allocator); // for (&arabic) |*f| f.deinit(allocator);
// for (&japanese) |*f| f.deinit(allocator); // for (&japanese) |*f| f.deinit(allocator);
} }
@ -109,10 +117,10 @@ pub fn main() !void {
// try stdout.flush(); // try stdout.flush();
var the_chunk = try shared.chunk.initChunk(allocator); // var the_chunk = try shared.chunk.initChunk(allocator);
defer shared.chunk.deinitChunk(&the_chunk, allocator); // defer shared.chunk.deinitChunk(&the_chunk, allocator);
shared.chunk.updateChunk(&the_chunk); // shared.chunk.updateChunk(&the_chunk);
//var elf = entity.Elf.init(); //var elf = entity.Elf.init();
@ -204,7 +212,30 @@ pub fn main() !void {
for (&vollkorn) |*f| { for (&vollkorn) |*f| {
f.render_text( f.render_text(
"Whereas, disregard and contempt for human rights have resulted!fi", "Whereas, disregard and contempt for human rights have resulted!",
rl.Vector2{ .x = 0, .y = y},
true,
.white,
.blank,
false,
true
);
// const font_ascent : f32 = @floatFromInt(f.face.size().metrics().ascender >> 6);
// const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y;
// const font_descent : f32 = @floatFromInt(f.face.size().metrics().descender >> 6);
// const dpi_font_descent = font_descent / rl.getWindowScaleDPI().y;
const font_linegap : f32 = @floatFromInt(f.face.size().metrics().height >> 6);
const dpi_font_linegap = font_linegap / rl.getWindowScaleDPI().y;
y += dpi_font_linegap;
}
for (&inconsolata) |*f| {
f.render_text(
"Whereas, disregard and contempt for human rights have resulted!",
rl.Vector2{ .x = 0, .y = y}, rl.Vector2{ .x = 0, .y = y},
true, true,
.white, .white,
@ -216,26 +247,15 @@ pub fn main() !void {
const font_ascent : f32 = @floatFromInt(f.face.size().metrics().ascender >> 6); const font_ascent : f32 = @floatFromInt(f.face.size().metrics().ascender >> 6);
const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y; const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y;
y += dpi_font_ascent; const font_descent : f32 = @floatFromInt(f.face.size().metrics().descender >> 6);
const dpi_font_descent = font_descent / rl.getWindowScaleDPI().y;
const font_linegap : f32 = @floatFromInt(f.face.size().metrics().height >> 6);
const dpi_font_linegap = font_linegap / rl.getWindowScaleDPI().y;
y += dpi_font_ascent - dpi_font_descent + dpi_font_linegap;
} }
// for (&inconsolata) |*f| {
// f.render_text(
// "Whereas, disregard and contempt for human rights have resulted!fi",
// rl.Vector2{ .x = 0, .y = y},
// true,
// .white,
// .blank,
// false,
// true
// );
// const font_ascent : f32 = @floatFromInt(f.face.size().metrics().ascender >> 6);
// const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y;
// y += dpi_font_ascent;
// }
// for (&japanese) |*f| { // for (&japanese) |*f| {
// f.render_text( // f.render_text(
// "外は夜が長くて寒い", // "外は夜が長くて寒い",
@ -365,7 +385,7 @@ pub fn main() !void {
//rl.drawText("Congrats! You created your first window!", rl.getMouseX(), rl.getMouseY(), 20, .white); //rl.drawText("Congrats! You created your first window!", rl.getMouseX(), rl.getMouseY(), 20, .white);
//rl.drawRectangleLines(0, 0, 100, 100, .red); //rl.drawRectangleLines(0, 0, 100, 100, .red);
// misc.drawFPS(0, 0, frame_time, frame); misc.drawFPS(0, 0, frame_time, frame);
//elf.draw(); //elf.draw();
@ -377,18 +397,6 @@ pub fn main() !void {
rl.swapScreenBuffer(); rl.swapScreenBuffer();
} }
const deinit_status = dbg_allocator.deinit();
if (deinit_status == .leak) std.testing.expect(false) catch @panic("TEST FAIL");
}
fn init() !void {
dbg_allocator = std.heap.DebugAllocator(.{}).init;
var stdout_buffer: [1024]u8 = undefined;
var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
stdout = &stdout_writer.interface;
// font.shader = try rl.loadShader(null, "assets/test.frag");
} }
fn connect() !void { fn connect() !void {

View File

@ -5,7 +5,7 @@ const bufzilla = @import("bufzilla");
const shared = @import("shared"); const shared = @import("shared");
const server = @import("server.zig"); const server = @import("server.zig");
pub fn spawn(chunk: *shared.chunk.Chunk(), comptime T: type, allocator: std.mem.Allocator, value: T) !void { pub fn spawn(chunk: *shared.chunk.Chunk, comptime T: type, allocator: std.mem.Allocator, value: T) !void {
std.debug.assert(value.id == shared.entity.INVALID_ID); std.debug.assert(value.id == shared.entity.INVALID_ID);
const id = server.next_entity_id; const id = server.next_entity_id;
@ -14,7 +14,7 @@ pub fn spawn(chunk: *shared.chunk.Chunk(), comptime T: type, allocator: std.mem.
var entity = value; var entity = value;
entity.id = id; entity.id = id;
inline for (@typeInfo(shared.chunk.Chunk()).@"struct".fields) |field| { inline for (@typeInfo(shared.chunk.Chunk).@"struct".fields) |field| {
if (field.type == shared.chunk.Storage(T)) { if (field.type == shared.chunk.Storage(T)) {
try @field(chunk, field.name).items.append(allocator, entity); try @field(chunk, field.name).items.append(allocator, entity);
break; break;

View File

@ -26,7 +26,9 @@ pub fn Storage(comptime T: type) type {
}; };
} }
pub fn Chunk() type { pub const Chunk = _Chunk();
fn _Chunk() type {
const FieldCount = entity.EntityKinds.len; const FieldCount = entity.EntityKinds.len;
var fields: [FieldCount]std.builtin.Type.StructField = undefined; var fields: [FieldCount]std.builtin.Type.StructField = undefined;
@ -51,10 +53,10 @@ pub fn Chunk() type {
}); });
} }
pub fn initChunk(allocator: std.mem.Allocator) !Chunk() { pub fn initChunk(allocator: std.mem.Allocator) !Chunk {
var chunk: Chunk() = undefined; var chunk: Chunk = undefined;
switch (@typeInfo(Chunk())) { switch (@typeInfo(Chunk)) {
.@"struct" => |s| { .@"struct" => |s| {
inline for (s.fields) |field| { inline for (s.fields) |field| {
const StorageT = field.type; const StorageT = field.type;
@ -67,8 +69,8 @@ pub fn initChunk(allocator: std.mem.Allocator) !Chunk() {
return chunk; return chunk;
} }
pub fn deinitChunk(chunk: *Chunk(), allocator: std.mem.Allocator) void { pub fn deinitChunk(chunk: *Chunk, allocator: std.mem.Allocator) void {
switch (@typeInfo(Chunk())) { switch (@typeInfo(Chunk)) {
.@"struct" => |s| { .@"struct" => |s| {
inline for (s.fields) |field| { inline for (s.fields) |field| {
@field(chunk, field.name).deinit(allocator); @field(chunk, field.name).deinit(allocator);
@ -78,8 +80,8 @@ pub fn deinitChunk(chunk: *Chunk(), allocator: std.mem.Allocator) void {
} }
} }
pub fn updateChunk(chunk: *Chunk()) void { pub fn updateChunk(chunk: *Chunk) void {
const info = @typeInfo(Chunk()); const info = @typeInfo(Chunk);
switch (info) { switch (info) {
.@"struct" => |s| { .@"struct" => |s| {