Use enum instead of packed struct for *Index objects (#1640)

Resolves: #1600

---------

Co-authored-by: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com>
This commit is contained in:
Krzysztof Wiśniewski 2025-06-28 15:45:34 +02:00 committed by GitHub
parent 24a1fcdc69
commit 254546c789
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 58 additions and 55 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}

View File

@ -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();

View File

@ -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};
}

View File

@ -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
}
}

View File

@ -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});
}

View File

@ -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 {