From 254546c789ebc59a7a262153195bb391c0b76720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wi=C5=9Bniewski?= Date: Sat, 28 Jun 2025 15:45:34 +0200 Subject: [PATCH] Use `enum` instead of `packed struct` for `*Index` objects (#1640) Resolves: #1600 --------- Co-authored-by: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com> --- mods/cubyz/rotation/branch.zig | 4 +-- mods/cubyz/rotation/carpet.zig | 4 +-- mods/cubyz/rotation/direction.zig | 2 +- mods/cubyz/rotation/fence.zig | 2 +- mods/cubyz/rotation/log.zig | 2 +- mods/cubyz/rotation/planar.zig | 2 +- mods/cubyz/rotation/sign.zig | 2 +- mods/cubyz/rotation/stairs.zig | 4 +-- mods/cubyz/rotation/texture_pile.zig | 2 +- mods/cubyz/rotation/torch.zig | 4 +-- src/assets.zig | 4 +-- src/block_entity.zig | 2 +- src/game.zig | 2 +- src/itemdrop.zig | 4 +-- src/items.zig | 50 ++++++++++++++-------------- src/models.zig | 23 +++++++------ 16 files changed, 58 insertions(+), 55 deletions(-) diff --git a/mods/cubyz/rotation/branch.zig b/mods/cubyz/rotation/branch.zig index 653684f9..e570bd5e 100644 --- a/mods/cubyz/rotation/branch.zig +++ b/mods/cubyz/rotation/branch.zig @@ -301,7 +301,7 @@ pub fn createBlockModel(_: Block, modeData: *u16, zon: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + (block.data & 63)}; + return blocks.meshes.modelIndexStart(block).add(block.data & 63); } pub fn rotateZ(data: u16, angle: Degrees) u16 { @@ -396,7 +396,7 @@ fn closestRay(block: Block, relativePlayerPos: Vec3f, playerDir: Vec3f) ?u16 { const directionBitMask = Neighbor.bitMask(direction); if((block.data & directionBitMask) != 0) { - const modelIndex = ModelIndex{.index = blocks.meshes.modelIndexStart(block).index + directionBitMask}; + const modelIndex: ModelIndex = blocks.meshes.modelIndexStart(block).add(directionBitMask); if(RotationMode.DefaultFunctions.rayModelIntersection(modelIndex, relativePlayerPos, playerDir)) |intersection| { if(@abs(closestIntersectionDistance) > @abs(intersection.distance)) { closestIntersectionDistance = intersection.distance; diff --git a/mods/cubyz/rotation/carpet.zig b/mods/cubyz/rotation/carpet.zig index 2c7e2e58..6faa1670 100644 --- a/mods/cubyz/rotation/carpet.zig +++ b/mods/cubyz/rotation/carpet.zig @@ -120,7 +120,7 @@ pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + (@as(u6, @truncate(block.data)) -| 1)}; + return blocks.meshes.modelIndexStart(block).add(@as(u6, @truncate(block.data)) -| 1); } pub fn generateData(_: *main.game.World, _: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, relativeDir: Vec3i, _: ?Neighbor, currentData: *Block, neighbor: Block, _: bool) bool { @@ -154,7 +154,7 @@ fn closestRay(comptime typ: enum {bit, intersection}, block: Block, _: ?main.ite var resultBit: u16 = 0; for([_]u16{1, 2, 4, 8, 16, 32}) |bit| { if(block.data & bit != 0) { - const modelIndex = ModelIndex{.index = blocks.meshes.modelIndexStart(block).index + bit - 1}; + const modelIndex: ModelIndex = blocks.meshes.modelIndexStart(block).add(bit - 1); if(RotationMode.DefaultFunctions.rayModelIntersection(modelIndex, relativePlayerPos, playerDir)) |intersection| { if(result == null or result.?.distance > intersection.distance) { result = intersection; diff --git a/mods/cubyz/rotation/direction.zig b/mods/cubyz/rotation/direction.zig index 5abbc4eb..6192c46e 100644 --- a/mods/cubyz/rotation/direction.zig +++ b/mods/cubyz/rotation/direction.zig @@ -44,7 +44,7 @@ pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + @min(block.data, 5)}; + return blocks.meshes.modelIndexStart(block).add(@min(block.data, 5)); } pub fn rotateZ(data: u16, angle: Degrees) u16 { diff --git a/mods/cubyz/rotation/fence.zig b/mods/cubyz/rotation/fence.zig index f6d33f6f..0e01afa5 100644 --- a/mods/cubyz/rotation/fence.zig +++ b/mods/cubyz/rotation/fence.zig @@ -99,7 +99,7 @@ pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + (block.data & 15)}; + return blocks.meshes.modelIndexStart(block).add(block.data & 15); } pub fn updateData(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool { diff --git a/mods/cubyz/rotation/log.zig b/mods/cubyz/rotation/log.zig index 5e2c7d17..9006e68f 100644 --- a/mods/cubyz/rotation/log.zig +++ b/mods/cubyz/rotation/log.zig @@ -179,7 +179,7 @@ pub fn createBlockModel(_: Block, _: *u16, _: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + (block.data & 63)}; + return blocks.meshes.modelIndexStart(block).add(block.data & 63); } pub const rotateZ = branch.rotateZ; diff --git a/mods/cubyz/rotation/planar.zig b/mods/cubyz/rotation/planar.zig index 981ad567..128c1756 100644 --- a/mods/cubyz/rotation/planar.zig +++ b/mods/cubyz/rotation/planar.zig @@ -42,7 +42,7 @@ pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + @min(block.data, 3)}; + return blocks.meshes.modelIndexStart(block).add(@min(block.data, 3)); } pub fn rotateZ(data: u16, angle: Degrees) u16 { diff --git a/mods/cubyz/rotation/sign.zig b/mods/cubyz/rotation/sign.zig index 65b5d700..cbef4121 100644 --- a/mods/cubyz/rotation/sign.zig +++ b/mods/cubyz/rotation/sign.zig @@ -62,7 +62,7 @@ pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + @min(centerRotations*2 + sideRotations, block.data)}; + return blocks.meshes.modelIndexStart(block).add(@min(centerRotations*2 + sideRotations, block.data)); } pub fn rotateZ(data: u16, angle: Degrees) u16 { diff --git a/mods/cubyz/rotation/stairs.zig b/mods/cubyz/rotation/stairs.zig index ae2d83e1..9cf84737 100644 --- a/mods/cubyz/rotation/stairs.zig +++ b/mods/cubyz/rotation/stairs.zig @@ -243,7 +243,7 @@ pub fn createBlockModel(_: Block, _: *u16, _: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + (block.data & 255)}; + return blocks.meshes.modelIndexStart(block).add(block.data & 255); } pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, _: Vec3i, _: ?Neighbor, currentData: *Block, _: Block, blockPlacing: bool) bool { @@ -259,7 +259,7 @@ fn closestRay(comptime typ: enum {bit, intersection}, block: Block, relativePlay var resultBit: u16 = 0; for([_]u16{1, 2, 4, 8, 16, 32, 64, 128}) |bit| { if(block.data & bit == 0) { - const cornerModelIndex = ModelIndex{.index = blocks.meshes.modelIndexStart(block).index + (255 ^ bit)}; + const cornerModelIndex: ModelIndex = blocks.meshes.modelIndexStart(block).add(255 ^ bit); if(RotationMode.DefaultFunctions.rayModelIntersection(cornerModelIndex, relativePlayerPos, playerDir)) |intersection| { if(result == null or intersection.distance < result.?.distance) { result = intersection; diff --git a/mods/cubyz/rotation/texture_pile.zig b/mods/cubyz/rotation/texture_pile.zig index 2c96cf37..f92e137b 100644 --- a/mods/cubyz/rotation/texture_pile.zig +++ b/mods/cubyz/rotation/texture_pile.zig @@ -54,7 +54,7 @@ pub fn createBlockModel(block: Block, modeData: *u16, zon: ZonElement) ModelInde } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + @min(block.data, block.modeData() - 1)}; + return blocks.meshes.modelIndexStart(block).add(@min(block.data, block.modeData() - 1)); } pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, _: Vec3i, _: ?Neighbor, currentData: *Block, _: Block, blockPlacing: bool) bool { diff --git a/mods/cubyz/rotation/torch.zig b/mods/cubyz/rotation/torch.zig index 38159bdf..1df19bb1 100644 --- a/mods/cubyz/rotation/torch.zig +++ b/mods/cubyz/rotation/torch.zig @@ -94,7 +94,7 @@ pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex { } pub fn model(block: Block) ModelIndex { - return .{.index = blocks.meshes.modelIndexStart(block).index + (@as(u5, @truncate(block.data)) -| 1)}; + return blocks.meshes.modelIndexStart(block).add(@as(u5, @truncate(block.data)) -| 1); } pub fn rotateZ(data: u16, angle: Degrees) u16 { @@ -172,7 +172,7 @@ fn closestRay(comptime typ: enum {bit, intersection}, block: Block, _: ?main.ite var resultBit: u16 = 0; for([_]u16{1, 2, 4, 8, 16}) |bit| { if(block.data & bit != 0) { - const modelIndex = ModelIndex{.index = blocks.meshes.modelIndexStart(block).index + bit - 1}; + const modelIndex: ModelIndex = blocks.meshes.modelIndexStart(block).add(bit - 1); if(RotationMode.DefaultFunctions.rayModelIntersection(modelIndex, relativePlayerPos, playerDir)) |intersection| { if(result == null or intersection.distance < result.?.distance) { result = intersection; diff --git a/src/assets.zig b/src/assets.zig index 7f781fee..45219de3 100644 --- a/src/assets.zig +++ b/src/assets.zig @@ -365,8 +365,8 @@ fn registerBlock(assetFolder: []const u8, id: []const u8, zon: ZonElement) !void fn assignBlockItem(stringId: []const u8) !void { const block = blocks_zig.getTypeById(stringId); // TODO: This must be gone in PixelGuys/Cubyz#1205 - const index = (items_zig.BaseItemIndex.fromId(stringId) orelse unreachable).index; - const item = &items_zig.itemList[index]; + const index = items_zig.BaseItemIndex.fromId(stringId) orelse unreachable; + const item = &items_zig.itemList[@intFromEnum(index)]; item.block = block; } diff --git a/src/block_entity.zig b/src/block_entity.zig index a2f4aa42..c96fbe80 100644 --- a/src/block_entity.zig +++ b/src/block_entity.zig @@ -477,7 +477,7 @@ pub const BlockEntityTypes = struct { signData.renderedTexture.?.bindTo(0); - c.glUniform1i(uniforms.quadIndex, quad.index); + c.glUniform1i(uniforms.quadIndex, @intFromEnum(quad)); const mesh = main.renderer.mesh_storage.getMeshAndIncreaseRefCount(main.chunk.ChunkPosition.initFromWorldPos(signData.blockPos, 1)) orelse continue :outer; defer mesh.decreaseRefCount(); mesh.lightingData[0].lock.lockRead(); diff --git a/src/game.zig b/src/game.zig index 4416635a..bba4c50f 100644 --- a/src/game.zig +++ b/src/game.zig @@ -607,7 +607,7 @@ pub const Player = struct { // MARK: Player const block = main.renderer.mesh_storage.getBlock(selectedPos[0], selectedPos[1], selectedPos[2]) orelse return; const item: items.Item = for(0..items.itemListSize) |idx| { - const baseItem: main.items.BaseItemIndex = .{.index = @intCast(idx)}; + const baseItem: main.items.BaseItemIndex = @enumFromInt(idx); if(baseItem.block() == block.typ) { break .{.baseItem = baseItem}; } diff --git a/src/itemdrop.zig b/src/itemdrop.zig index 8811bf47..a580dbbe 100644 --- a/src/itemdrop.zig +++ b/src/itemdrop.zig @@ -592,13 +592,13 @@ pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer defer data.deinit(); for(model.internalQuads) |quad| { const textureIndex = blocks.meshes.textureIndex(block, quad.quadInfo().textureSlot); - data.append(@as(u32, quad.index) << 16 | textureIndex); // modelAndTexture + data.append(@as(u32, @intFromEnum(quad)) << 16 | textureIndex); // modelAndTexture data.append(0); // offsetByNormal } for(model.neighborFacingQuads) |list| { for(list) |quad| { const textureIndex = blocks.meshes.textureIndex(block, quad.quadInfo().textureSlot); - data.append(@as(u32, quad.index) << 16 | textureIndex); // modelAndTexture + data.append(@as(u32, @intFromEnum(quad)) << 16 | textureIndex); // modelAndTexture data.append(1); // offsetByNormal } } diff --git a/src/items.zig b/src/items.zig index afe27fa7..610d6bae 100644 --- a/src/items.zig +++ b/src/items.zig @@ -157,47 +157,47 @@ const MaterialProperty = enum { } }; -pub const BaseItemIndex = packed struct { - index: u16, +pub const BaseItemIndex = enum(u16) { + _, pub fn fromId(_id: []const u8) ?BaseItemIndex { return reverseIndices.get(_id); } pub fn image(self: BaseItemIndex) graphics.Image { - return itemList[self.index].image; + return itemList[@intFromEnum(self)].image; } pub fn texture(self: BaseItemIndex) ?graphics.Texture { - return itemList[self.index].texture; + return itemList[@intFromEnum(self)].texture; } pub fn id(self: BaseItemIndex) []const u8 { - return itemList[self.index].id; + return itemList[@intFromEnum(self)].id; } pub fn name(self: BaseItemIndex) []const u8 { - return itemList[self.index].name; + return itemList[@intFromEnum(self)].name; } pub fn tags(self: BaseItemIndex) []const Tag { - return itemList[self.index].tags; + return itemList[@intFromEnum(self)].tags; } pub fn stackSize(self: BaseItemIndex) u16 { - return itemList[self.index].stackSize; + return itemList[@intFromEnum(self)].stackSize; } pub fn material(self: BaseItemIndex) ?Material { - return itemList[self.index].material; + return itemList[@intFromEnum(self)].material; } pub fn block(self: BaseItemIndex) ?u16 { - return itemList[self.index].block; + return itemList[@intFromEnum(self)].block; } pub fn hasTag(self: BaseItemIndex, tag: Tag) bool { - return itemList[self.index].hasTag(tag); + return itemList[@intFromEnum(self)].hasTag(tag); } pub fn hashCode(self: BaseItemIndex) u32 { - return itemList[self.index].hashCode(); + return itemList[@intFromEnum(self)].hashCode(); } pub fn getTexture(self: BaseItemIndex) graphics.Texture { - return itemList[self.index].getTexture(); + return itemList[@intFromEnum(self)].getTexture(); } pub fn getTooltip(self: BaseItemIndex) []const u8 { - return itemList[self.index].getTooltip(); + return itemList[@intFromEnum(self)].getTooltip(); } }; @@ -505,8 +505,8 @@ const PropertyMatrix = struct { // MARK: PropertyMatrix }; }; -pub const ToolTypeIndex = packed struct { - index: u16, +pub const ToolTypeIndex = enum(u16) { + _, const ToolTypeIterator = struct { i: u16 = 0, @@ -514,7 +514,7 @@ pub const ToolTypeIndex = packed struct { pub fn next(self: *ToolTypeIterator) ?ToolTypeIndex { if(self.i >= toolTypeList.items.len) return null; defer self.i += 1; - return ToolTypeIndex{.index = self.i}; + return @enumFromInt(self.i); } }; @@ -525,22 +525,22 @@ pub const ToolTypeIndex = packed struct { return toolTypeIdToIndex.get(_id); } pub fn id(self: ToolTypeIndex) []const u8 { - return toolTypeList.items[self.index].id; + return toolTypeList.items[@intFromEnum(self)].id; } pub fn blockTags(self: ToolTypeIndex) []const Tag { - return toolTypeList.items[self.index].blockTags; + return toolTypeList.items[@intFromEnum(self)].blockTags; } pub fn properties(self: ToolTypeIndex) []const PropertyMatrix { - return toolTypeList.items[self.index].properties; + return toolTypeList.items[@intFromEnum(self)].properties; } pub fn slotInfos(self: ToolTypeIndex) *const [25]SlotInfo { - return &toolTypeList.items[self.index].slotInfos; + return &toolTypeList.items[@intFromEnum(self)].slotInfos; } pub fn pixelSources(self: ToolTypeIndex) *const [16][16]u8 { - return &toolTypeList.items[self.index].pixelSources; + return &toolTypeList.items[@intFromEnum(self)].pixelSources; } pub fn pixelSourcesOverlay(self: ToolTypeIndex) *const [16][16]u8 { - return &toolTypeList.items[self.index].pixelSourcesOverlay; + return &toolTypeList.items[@intFromEnum(self)].pixelSourcesOverlay; } }; @@ -982,7 +982,7 @@ pub fn register(_: []const u8, texturePath: []const u8, replacementTexturePath: defer itemListSize += 1; newItem.init(arena.allocator(), texturePath, replacementTexturePath, id, zon); - reverseIndices.put(newItem.id, .{.index = itemListSize}) catch unreachable; + reverseIndices.put(newItem.id, @enumFromInt(itemListSize)) catch unreachable; std.log.debug("Registered item: {d: >5} '{s}'", .{itemListSize, id}); return newItem; @@ -1068,7 +1068,7 @@ pub fn registerTool(assetFolder: []const u8, id: []const u8, zon: ZonElement) vo .pixelSources = pixelSources, .pixelSourcesOverlay = pixelSourcesOverlay, }); - toolTypeIdToIndex.put(arena.allocator().allocator, idDupe, .{.index = @intCast(toolTypeList.items.len - 1)}) catch unreachable; + toolTypeIdToIndex.put(arena.allocator().allocator, idDupe, @enumFromInt(toolTypeList.items.len - 1)) catch unreachable; std.log.debug("Registered tool: '{s}'", .{id}); } diff --git a/src/models.zig b/src/models.zig index 16168597..f62ee49d 100644 --- a/src/models.zig +++ b/src/models.zig @@ -60,23 +60,26 @@ const Quad = struct { uvs: [4]usize, }; -pub const ModelIndex = packed struct { - index: u32, +pub const ModelIndex = enum(u32) { + _, pub fn model(self: ModelIndex) *const Model { - return &models.items()[self.index]; + return &models.items()[@intFromEnum(self)]; + } + pub fn add(self: ModelIndex, offset: u32) ModelIndex { + return @enumFromInt(@intFromEnum(self) + offset); } }; -pub const QuadIndex = packed struct { - index: u16, +pub const QuadIndex = enum(u16) { + _, pub fn quadInfo(self: QuadIndex) *const QuadInfo { - return &quads.items[self.index]; + return &quads.items[@intFromEnum(self)]; } pub fn extraQuadInfo(self: QuadIndex) *const ExtraQuadInfo { - return &extraQuadInfos.items[self.index]; + return &extraQuadInfos.items[@intFromEnum(self)]; } }; @@ -134,7 +137,7 @@ pub const Model = struct { // Snap the normals as well: dest.normal = snapToGrid(dest.normal); } - const modelIndex: ModelIndex = .{.index = models.len}; + const modelIndex: ModelIndex = @enumFromInt(models.len); const self = models.addOne(); var amounts: [6]usize = .{0, 0, 0, 0, 0, 0}; var internalAmount: usize = 0; @@ -440,7 +443,7 @@ var nameToIndex: std.StringHashMap(ModelIndex) = undefined; pub fn getModelIndex(string: []const u8) ModelIndex { return nameToIndex.get(string) orelse { std.log.err("Couldn't find voxelModel with name: {s}.", .{string}); - return .{.index = 0}; + return @enumFromInt(0); }; } @@ -463,7 +466,7 @@ fn addQuad(info_: QuadInfo) error{Degenerate}!QuadIndex { } } if(cornerEqualities >= 2) return error.Degenerate; // One corner equality is fine, since then the quad degenerates to a triangle, which has a non-zero area. - const index: QuadIndex = .{.index = @intCast(quads.items.len)}; + const index: QuadIndex = @enumFromInt(quads.items.len); if(info.opaqueInLod == 2) { info.opaqueInLod = 0; } else {