From be4ae4f1a71cd133dfb4ec2e3dbd588091a03e87 Mon Sep 17 00:00:00 2001 From: Szymon Nowakowski Date: Tue, 2 Dec 2025 15:58:51 +0100 Subject: [PATCH] Minor refactors and cleanups --- src/Game.zig | 18 ++-- src/assets/Blocks.zig | 16 ++-- src/assets/Chunk.zig | 2 + src/assets/Materials.zig | 16 ++-- src/assets/Textures.zig | 16 ++-- src/engine/Atom.zig | 167 +++++++++++++++++++++++++++++++++++ src/engine/Engine.zig | 2 +- src/engine/GenericBuffer.zig | 2 +- src/engine/StagingBuffer.zig | 2 +- src/engine/Swapchain.zig | 4 +- src/engine/Texture.zig | 2 +- src/engine/VkAllocator.zig | 2 +- src/engine/atoms.zig | 77 ---------------- src/main.zig | 16 +++- src/math.zig | 2 +- 15 files changed, 223 insertions(+), 121 deletions(-) create mode 100644 src/engine/Atom.zig delete mode 100644 src/engine/atoms.zig diff --git a/src/Game.zig b/src/Game.zig index a5cbd01..bd4293b 100644 --- a/src/Game.zig +++ b/src/Game.zig @@ -151,8 +151,6 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain var blocks = try Blocks.init(allocator); errdefer blocks.deinit(allocator); - blocks.loadAll(engine, &materials, &textures, allocator); - const sampler = try engine.createSampler(.{ .mag_filter = .linear, .min_filter = .linear, @@ -510,6 +508,13 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain }); engine.setObjectName(global_descriptor_set, "DS Global", .{}); + const block_grass = try blocks.getOrLoadFilename(engine, &materials, &textures, "Grass.json", allocator); + const block_dirt = try blocks.getOrLoadFilename(engine, &materials, &textures, "Dirt.json", allocator); + const block_stone = try blocks.getOrLoadFilename(engine, &materials, &textures, "Stone.json", allocator); + const block_bedrock = try blocks.getOrLoadFilename(engine, &materials, &textures, "Bedrock.json", allocator); + + // VOLATILE Load all assets before this point + const descriptor_images = try allocator.alloc(vk.DescriptorImageInfo, textures.textures.items.len); for (textures.textures.items, descriptor_images) |texture, *info| { info.* = .{ @@ -603,12 +608,7 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain const world_seed = engine.random.int(u64); std.log.info("Using world seed 0x{x:0<16}", .{world_seed}); - var it = Interator2(i16).init(-10, -10, 9, 9); - - const block_grass = blocks.getFilename("Grass.json").?; - const block_dirt = blocks.getFilename("Dirt.json").?; - const block_stone = blocks.getFilename("Stone.json").?; - const block_bedrock = blocks.getFilename("Bedrock.json").?; + var it = Interator2(i16).init(-8, -8, 7, 7); while (it.next()) |chunk_coords2| { const chunk_coords3 = chunk_coords2 ++ [_]i16{0}; @@ -729,7 +729,7 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain } pub fn deinit(self: *Game) void { - std.log.debug("Deinitializing {*}", .{self}); + std.log.scoped(.deinit).debug("Deinitializing {*}", .{self}); self.vertex_buffer.deinit(self.engine); self.index_buffer.deinit(self.engine); diff --git a/src/assets/Blocks.zig b/src/assets/Blocks.zig index fc8baa2..d9b44aa 100644 --- a/src/assets/Blocks.zig +++ b/src/assets/Blocks.zig @@ -1,7 +1,7 @@ const Blocks = @This(); const std = @import("std"); -const atoms = @import("../engine/atoms.zig"); +const Atom = @import("../engine/Atom.zig").Atom; const Engine = @import("../engine/Engine.zig"); const Materials = @import("Materials.zig"); const Textures = @import("Textures.zig"); @@ -60,7 +60,7 @@ blocks: Array, pub const capacity = std.math.maxInt(std.meta.Tag(Id)); -pub const Key = struct { atom: atoms.Atom }; +pub const Key = struct { atom: Atom }; pub const Id = enum(u12) { air = 0, _, @@ -91,20 +91,20 @@ pub fn init(allocator: std.mem.Allocator) !Blocks { } pub fn deinit(self: *Blocks, allocator: std.mem.Allocator) void { - std.log.debug("Deinitializing {*} with Allocator{{{*},{*}}}", .{ self, allocator.ptr, allocator.vtable }); + std.log.scoped(.deinit).debug("Deinitializing {*} with Allocator{{{*},{*}}}", .{ self, allocator.ptr, allocator.vtable }); self.blocks.deinit(allocator); self.map.deinit(allocator); self.* = undefined; } -pub fn getAtom(self: *const Blocks, atom: atoms.Atom) ?Id { +pub fn getAtom(self: *const Blocks, atom: Atom) ?Id { const key: Key = .{ .atom = atom }; return self.map.get(key); } pub fn getFilename(self: *const Blocks, filename: []const u8) ?Id { - const atom = atoms.getAtom(filename) orelse return null; + const atom = Atom.fromStringIfExists(filename) orelse return null; const key: Key = .{ .atom = atom }; return self.map.get(key); } @@ -119,7 +119,7 @@ pub fn getOrLoadAtom( engine: *Engine, materials: *Materials, textures: *Textures, - atom: atoms.Atom, + atom: Atom, temp_allocator: std.mem.Allocator, ) !Id { const key: Key = .{ .atom = atom }; @@ -129,7 +129,7 @@ pub fn getOrLoadAtom( return entry.value_ptr.*; } else { errdefer _ = self.map.remove(key); - const block = try loadBlock(engine, materials, textures, atoms.getString(atom), temp_allocator); + const block = try loadBlock(engine, materials, textures, Atom.toString(), temp_allocator); const id = self.nextId(); entry.value_ptr.* = id; self.blocks.appendAssumeCapacity(block); @@ -145,7 +145,7 @@ pub fn getOrLoadFilename( filename: []const u8, temp_allocator: std.mem.Allocator, ) !Id { - const atom = try atoms.getOrPutAtom(filename); + const atom = try Atom.fromString(filename); const key: Key = .{ .atom = atom }; const entry = self.map.getOrPutAssumeCapacity(key); diff --git a/src/assets/Chunk.zig b/src/assets/Chunk.zig index ff049e0..bdcad9b 100644 --- a/src/assets/Chunk.zig +++ b/src/assets/Chunk.zig @@ -98,6 +98,8 @@ pub fn init(engine: *Engine, init_info: InitInfo) !Chunk { } pub fn deinit(self: *Chunk, engine: *Engine, descriptor_pool: vk.DescriptorPool) void { + std.log.scoped(.deinit).debug("Deinitializing chunk {d} with {*} and {s}#{X}", .{ self.chunk_id, engine, @typeName(vk.DescriptorPool), @intFromEnum(descriptor_pool) }); + self.object_buffer.deinit(engine); engine.freeDescriptorSet(descriptor_pool, self.descriptor_set); diff --git a/src/assets/Materials.zig b/src/assets/Materials.zig index 3c3b60c..7b7e01f 100644 --- a/src/assets/Materials.zig +++ b/src/assets/Materials.zig @@ -3,7 +3,7 @@ const std = @import("std"); const vk = @import("vulkan"); -const atoms = @import("../engine/atoms.zig"); +const Atom = @import("../engine/Atom.zig").Atom; const Engine = @import("../engine/Engine.zig"); const GenericBuffer = @import("../engine/GenericBuffer.zig").GenericBuffer; const Textures = @import("Textures.zig"); @@ -17,7 +17,7 @@ next_id: Id, // capacity * @sizeOf(Material) = 832 kiB pub const capacity = std.math.maxInt(std.meta.Tag(Id)); -pub const Key = struct { atom: atoms.Atom }; +pub const Key = struct { atom: Atom }; pub const Id = enum(u16) { empty, _, @@ -67,25 +67,25 @@ pub fn init(engine: *Engine, allocator: std.mem.Allocator) !Materials { } pub fn deinit(self: *Materials, engine: *Engine, allocator: std.mem.Allocator) void { - std.log.debug("Deinitializing {*} with {*} and Allocator{{{*},{*}}}", .{ self, engine, allocator.ptr, allocator.vtable }); + std.log.scoped(.deinit).debug("Deinitializing {*} with {*} and Allocator{{{*},{*}}}", .{ self, engine, allocator.ptr, allocator.vtable }); self.material_buffer.deinit(engine); self.map.deinit(allocator); self.* = undefined; } -pub fn getAtom(self: *const Materials, atom: atoms.Atom) ?Id { +pub fn getAtom(self: *const Materials, atom: Atom) ?Id { const key: Key = .{ .atom = atom }; return self.map.get(key); } pub fn getFilename(self: *const Materials, filename: []const u8) ?Id { - const atom = atoms.getAtom(filename) orelse return null; + const atom = Atom.fromStringIfExists(filename) orelse return null; const key: Key = .{ .atom = atom }; return self.map.get(key); } -pub fn getOrLoadAtom(self: *Materials, engine: *Engine, textures: *Textures, atom: atoms.Atom, temp_allocator: std.mem.Allocator) !Id { +pub fn getOrLoadAtom(self: *Materials, engine: *Engine, textures: *Textures, atom: Atom, temp_allocator: std.mem.Allocator) !Id { const key: Key = .{ .atom = atom }; const entry = self.map.getOrPutAssumeCapacity(key); @@ -93,14 +93,14 @@ pub fn getOrLoadAtom(self: *Materials, engine: *Engine, textures: *Textures, ato return entry.value_ptr.*; } else { errdefer _ = self.map.remove(key); - const id = try self.loadMaterial(engine, textures, atoms.getString(atom), temp_allocator); + const id = try self.loadMaterial(engine, textures, atom.toString(), temp_allocator); entry.value_ptr.* = id; return id; } } pub fn getOrLoadFilename(self: *Materials, engine: *Engine, textures: *Textures, filename: []const u8, temp_allocator: std.mem.Allocator) !Id { - const atom = try atoms.getOrPutAtom(filename); + const atom = try Atom.fromString(filename); const key: Key = .{ .atom = atom }; const entry = self.map.getOrPutAssumeCapacity(key); diff --git a/src/assets/Textures.zig b/src/assets/Textures.zig index 0fb7dfe..93b182a 100644 --- a/src/assets/Textures.zig +++ b/src/assets/Textures.zig @@ -3,7 +3,7 @@ const std = @import("std"); const stbi = @import("zstbi"); -const atoms = @import("../engine/atoms.zig"); +const Atom = @import("../engine/Atom.zig").Atom; const Engine = @import("../engine/Engine.zig"); const Texture = @import("../engine/Texture.zig"); @@ -13,7 +13,7 @@ textures: Array, pub const capacity = std.math.maxInt(std.meta.Tag(Id)); pub const Key = struct { - atom: atoms.Atom, + atom: Atom, usage: Texture.Usage, }; @@ -93,7 +93,7 @@ pub fn init(engine: *Engine, allocator: std.mem.Allocator) !Textures { } pub fn deinit(self: *Textures, engine: *Engine, allocator: std.mem.Allocator) void { - std.log.debug("Deinitializing {*} with {*} and Allocator{{{*},{*}}}", .{ self, engine, allocator.ptr, allocator.vtable }); + std.log.scoped(.deinit).debug("Deinitializing {*} with {*} and Allocator{{{*},{*}}}", .{ self, engine, allocator.ptr, allocator.vtable }); for (self.textures.items) |*texture| { texture.deinit(engine); @@ -103,13 +103,13 @@ pub fn deinit(self: *Textures, engine: *Engine, allocator: std.mem.Allocator) vo self.* = undefined; } -pub fn getAtom(self: *const Textures, atom: atoms.Atom, usage: Texture.Usage) ?Id { +pub fn getAtom(self: *const Textures, atom: Atom, usage: Texture.Usage) ?Id { const key: Key = .{ .atom = atom, .usage = usage }; return self.map.get(key); } pub fn getFilename(self: *const Textures, filename: []const u8, usage: Texture.Usage) ?Id { - const atom = atoms.getAtom(filename) orelse return null; + const atom = Atom.fromStringIfExists(filename) orelse return null; const key: Key = .{ .atom = atom, .usage = usage }; return self.map.get(key); } @@ -119,7 +119,7 @@ pub fn getTexture(self: *const Textures, id: Id) ?*Texture { return if (index < self.textures.items.len) &self.textures.items[index] else null; } -pub fn getOrLoadAtom(self: *Textures, engine: *Engine, atom: atoms.Atom, usage: Texture.Usage, temp_allocator: std.mem.Allocator) !Id { +pub fn getOrLoadAtom(self: *Textures, engine: *Engine, atom: Atom, usage: Texture.Usage, temp_allocator: std.mem.Allocator) !Id { const key: Key = .{ .atom = atom, .usage = usage }; const entry = self.map.getOrPutAssumeCapacity(key); @@ -127,7 +127,7 @@ pub fn getOrLoadAtom(self: *Textures, engine: *Engine, atom: atoms.Atom, usage: return entry.value_ptr.*; } else { errdefer _ = self.map.remove(key); - const texture = try loadTexture(engine, atoms.getString(atom), usage, temp_allocator); + const texture = try loadTexture(engine, atom.toString(), usage, temp_allocator); const id = self.nextId(); entry.value_ptr.* = id; self.textures.appendAssumeCapacity(texture); @@ -136,7 +136,7 @@ pub fn getOrLoadAtom(self: *Textures, engine: *Engine, atom: atoms.Atom, usage: } pub fn getOrLoadFilename(self: *Textures, engine: *Engine, filename: []const u8, usage: Texture.Usage, temp_allocator: std.mem.Allocator) !Id { - const atom = try atoms.getOrPutAtom(filename); + const atom = try Atom.fromString(filename); const key: Key = .{ .atom = atom, .usage = usage }; const entry = self.map.getOrPutAssumeCapacity(key); diff --git a/src/engine/Atom.zig b/src/engine/Atom.zig new file mode 100644 index 0000000..a4f6118 --- /dev/null +++ b/src/engine/Atom.zig @@ -0,0 +1,167 @@ +//! Module for string interning. A string can be converted to a stable integer +//! constant, called an *atom*. The value of an for a given string is guaranteed +//! to be stable throughout a program's runtime, but not across different runs. +//! There can be no more than 2¹⁶ atoms. +//! +//! Use this module for converting string IDs into numbers, so that they can be +//! compared more easily. The users of this module should import it with +//! `@import("Atom.zig").Atom` and use the methods available in the `Atom` type. + +const std = @import("std"); + +pub const Atom = enum(u16) { + // VOLATILE Synchronize explicit values with `init` implementation. + + /// Atom representing an empty string, i.e. `""`. + empty, + _, + + /// Cast an integer into an atom. This can produce an invalid atom. + pub fn fromInt(value: u16) Atom { + return @enumFromInt(value); + } + + /// Cast an index into an atom. This can produce an invalid atom. The caller + /// asserts that the index is not greater than the max atom value. + pub fn fromIndex(index: usize) Atom { + return @enumFromInt(@as(u16, @intCast(index))); + } + + /// Cast an index into an atom. This can produce an invalid atom. Returns an + /// error if the index is greater than the max atom value. + pub fn fromIndexSafe(index: usize) error{Overflow}!Atom { + return @enumFromInt(std.math.cast(u16, index) orelse return error.Overflow); + } + + /// Turn a string into an atom. Returns either an existing atom or makes a + /// new one, if necessary. This will always produce a valid atom. Will not + /// return any error if the atom already exists. + pub fn fromString(string: []const u8) error{ OutOfMemory, OutOfAtoms }!Atom { + mutex.lock(); + defer mutex.unlock(); + + std.debug.assert(initialized); + + const entry = try map.getOrPut(allocator, string); + + if (entry.found_existing) { + return entry.value_ptr.*; + } else { + errdefer _ = map.remove(string); + const atom = Atom.fromIndexSafe(array.items.len) catch |err| switch (err) { + error.Overflow => return error.OutOfAtoms, + }; + + try array.ensureUnusedCapacity(allocator, 1); + const owned_string = try toOwnedString(string); + + entry.key_ptr.* = owned_string; + entry.value_ptr.* = atom; + + array.appendAssumeCapacity(owned_string); + return atom; + } + } + + /// Turn a string into an atom, if the string has been already registered as + /// an atom. Returns `null` otherwise. This will always produce a valid + /// atom. + pub fn fromStringIfExists(string: []const u8) ?Atom { + mutex.lock(); + defer mutex.unlock(); + + std.debug.assert(initialized); + + return map.get(string); + } + + /// Cast an atom into an integer. + pub fn toInt(self: Atom) u32 { + return @intFromEnum(self); + } + + /// Cast an atom into a string. The caller asserts that the atom is valid. + pub fn toString(self: Atom) [:0]const u8 { + try mutex.lock(); + defer mutex.unlock(); + + std.debug.assert(initialized); + + return array.items[self.toInt()]; + } +}; + +/// Flag for debug purposes, to catch misuses of the API. +var initialized: bool = false; + +/// Allocator used for `map` and `array`. Also used as a child allocator for +/// `string_arena`. +var allocator: std.mem.Allocator = undefined; + +/// Allocator for all string values. All values of `map` and keys of `map` are +/// allocated with this arena. The strings are allocated with a null terminator +/// for interoperability with libraries. +var string_arena: std.heap.ArenaAllocator = undefined; + +/// Maps a string value to an atom value. +var map: std.StringHashMapUnmanaged(Atom) = undefined; + +/// Maps an atom value to a string. +var array: std.ArrayList([:0]const u8) = undefined; + +/// Protects all reads and writes to `map` and `array`. +var mutex: std.Thread.Mutex = .{}; + +pub fn init(_allocator: std.mem.Allocator) !void { + mutex.lock(); + defer mutex.unlock(); + + std.debug.assert(!initialized); + + allocator = _allocator; + string_arena = .init(_allocator); + map = .{}; + array = .empty; + initialized = true; + + // VOLATILE Synchronize with explicit values on top of `Atom` type. + try map.put(allocator, "", .empty); + try array.append(allocator, ""); +} + +pub fn deinit() void { + mutex.lock(); + defer mutex.unlock(); + + std.log.scoped(.deinit).debug("Deinitializing atoms", .{}); + std.debug.assert(initialized); + + string_arena.deinit(); + map.deinit(allocator); + array.deinit(allocator); + + allocator = undefined; + string_arena = undefined; + map = undefined; + array = undefined; + initialized = false; +} + +/// Dump all atoms in a readable format. Use for debugging. Does not flush the +/// writer. +pub fn dump(writer: std.Io.Writer) !void { + mutex.lock(); + defer mutex.unlock(); + + std.debug.assert(initialized); + + for (array.items, 0..) |string, i| { + const atom: u32 = @intCast(i); + writer.print("0x{X:0<8} {s}\n", .{ atom, string }); + } +} + +fn toOwnedString(string: []const u8) ![:0]const u8 { + const owned_string = try string_arena.allocator().dupeZ(u8, string); + return owned_string; +} diff --git a/src/engine/Engine.zig b/src/engine/Engine.zig index dc1a959..8e2bd9d 100644 --- a/src/engine/Engine.zig +++ b/src/engine/Engine.zig @@ -398,7 +398,7 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine { } pub fn deinit(self: *Engine) void { - std.log.debug("Deinitializing {*}", .{self}); + std.log.scoped(.deinit).debug("Deinitializing {*}", .{self}); const allocator = self.vk_allocator.allocator; diff --git a/src/engine/GenericBuffer.zig b/src/engine/GenericBuffer.zig index 8b21cdb..d87071f 100644 --- a/src/engine/GenericBuffer.zig +++ b/src/engine/GenericBuffer.zig @@ -89,7 +89,7 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type { } pub fn deinit(self: *Self, engine: *Engine) void { - std.log.debug("Deinitializing {*} with {*}", .{ self, engine }); + std.log.scoped(.deinit).debug("Deinitializing {*} with {*}", .{ self, engine }); engine.freeMemory(self.device_memory); engine.destroyBuffer(self.buffer); diff --git a/src/engine/StagingBuffer.zig b/src/engine/StagingBuffer.zig index 18a3211..9bc6fd9 100644 --- a/src/engine/StagingBuffer.zig +++ b/src/engine/StagingBuffer.zig @@ -51,7 +51,7 @@ pub fn init(engine: *Engine, init_info: InitInfo) !StagingBuffer { } pub fn deinit(self: *StagingBuffer, engine: *Engine) void { - std.log.debug("Deinitializing {*} with {*}", .{ self, engine }); + std.log.scoped(.deinit).debug("Deinitializing {*} with {*}", .{ self, engine }); engine.freeMemory(self.device_memory); engine.destroyBuffer(self.buffer); diff --git a/src/engine/Swapchain.zig b/src/engine/Swapchain.zig index 0e469bc..c9f0eed 100644 --- a/src/engine/Swapchain.zig +++ b/src/engine/Swapchain.zig @@ -116,7 +116,7 @@ pub fn init(engine: *Engine) !Swapchain { } pub fn deinit(self: *Swapchain, engine: *Engine) void { - std.log.debug("Deinitializing {*} with {*}", .{ self, engine }); + std.log.scoped(.deinit).debug("Deinitializing {*} with {*}", .{ self, engine }); const allocator = engine.vk_allocator.allocator; @@ -475,7 +475,7 @@ const SwapchainImage = struct { } fn deinit(self: *SwapchainImage, engine: *Engine) void { - std.log.debug("Deinitializing {*} with {*}", .{ &self, engine }); + std.log.scoped(.deinit).debug("Deinitializing {*} with {*}", .{ self, engine }); engine.waitForFence(self.fence) catch {}; if (self.command_buffer) |*command_buffer| { diff --git a/src/engine/Texture.zig b/src/engine/Texture.zig index 2babd74..bd1f60d 100644 --- a/src/engine/Texture.zig +++ b/src/engine/Texture.zig @@ -157,7 +157,7 @@ pub fn init(engine: *Engine, init_info: InitInfo) !Texture { } pub fn deinit(self: *Texture, engine: *Engine) void { - std.log.debug("Deinitializing {*} with {*}", .{ self, engine }); + std.log.scoped(.deinit).debug("Deinitializing {*} with {*}", .{ self, engine }); engine.destroyImageView(self.image_view); engine.freeMemory(self.device_memory); diff --git a/src/engine/VkAllocator.zig b/src/engine/VkAllocator.zig index 7afd53c..c480ad0 100644 --- a/src/engine/VkAllocator.zig +++ b/src/engine/VkAllocator.zig @@ -35,7 +35,7 @@ pub fn init(allocator: std.mem.Allocator) !*VkAllocator { } pub fn deinit(self: *VkAllocator) void { - std.log.debug("Deinitializing {*}", .{self}); + std.log.scoped(.deinit).debug("Deinitializing {*}", .{self}); if (self.allocated_bytes > 0) { log.warn("{d} byte(s) still allocated while deinitializing", .{self.allocated_bytes}); } diff --git a/src/engine/atoms.zig b/src/engine/atoms.zig deleted file mode 100644 index 0791177..0000000 --- a/src/engine/atoms.zig +++ /dev/null @@ -1,77 +0,0 @@ -pub const Atoms = @This(); -const std = @import("std"); - -var allocator: std.mem.Allocator = undefined; -var string_arena: std.heap.ArenaAllocator = undefined; -var map: Map = undefined; -var array: Array = undefined; -var mutex: std.Thread.Mutex = undefined; - -pub const Atom = enum(u32) { _ }; - -pub const Map = std.StringHashMapUnmanaged(Atom); -pub const Array = std.ArrayList([:0]const u8); - -pub fn init(_allocator: std.mem.Allocator) void { - allocator = _allocator; - string_arena = .init(_allocator); - map = .{}; - array = .empty; - mutex = .{}; -} - -pub fn deinit() void { - std.log.debug("Deinitializing atoms", .{}); - - string_arena.deinit(); - map.deinit(allocator); - array.deinit(allocator); - - allocator = undefined; - string_arena = undefined; - map = undefined; - array = undefined; - mutex = undefined; -} - -pub fn getString(atom: Atom) [:0]const u8 { - try mutex.lock(); - defer mutex.unlock(); - - return array.items[atom.value]; -} - -pub fn getAtom(string: []const u8) ?Atom { - mutex.lock(); - defer mutex.unlock(); - - return map.get(string); -} - -pub fn getOrPutAtom(string: []const u8) !Atom { - mutex.lock(); - defer mutex.unlock(); - - const entry = try map.getOrPut(allocator, string); - - if (entry.found_existing) { - return entry.value_ptr.*; - } else { - errdefer _ = map.remove(string); - try array.ensureUnusedCapacity(allocator, 1); - - const owned_string = try toOwnedString(string); - const atom: Atom = @enumFromInt(array.items.len); - - entry.key_ptr.* = owned_string; - entry.value_ptr.* = atom; - - array.appendAssumeCapacity(owned_string); - return atom; - } -} - -fn toOwnedString(string: []const u8) ![:0]const u8 { - const owned_string = try string_arena.allocator().dupeZ(u8, string); - return owned_string; -} diff --git a/src/main.zig b/src/main.zig index 0a77c28..632e07b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -6,13 +6,23 @@ const vk = @import("vulkan"); const c = @import("const.zig"); -const atoms = @import("engine/atoms.zig"); +const atoms = @import("engine/Atom.zig"); const Engine = @import("engine/Engine.zig"); const Swapchain = @import("engine/Swapchain.zig"); const Game = @import("Game.zig"); pub const std_options: std.Options = .{ - .log_level = .info, + .log_scope_levels = &.{ + .{ + .scope = .vulkan, + .level = .debug, + }, + .{ + .scope = .deinit, + // Change to `.debug` to see a log when calling `deinit`. + .level = .info, + }, + }, }; pub fn main() !void { @@ -21,7 +31,7 @@ pub fn main() !void { const allocator = gpa.allocator(); - atoms.init(allocator); + try atoms.init(allocator); defer atoms.deinit(); stbi.init(allocator); diff --git a/src/math.zig b/src/math.zig index d868b6f..7d55b18 100644 --- a/src/math.zig +++ b/src/math.zig @@ -31,7 +31,7 @@ pub inline fn epu64x2(value: u64) u64x8 { pub inline fn lerp(a: f32, b: f32, t: f32) f32 { const s = 1.0 - t; - return a * t + b * s; + return a * s + b * t; } pub const noise2 = @import("math/noise.zig").noise2;