mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
Refactor how block entity unloading works and unloading things on the client side (#1475)
extracted from #1446
This commit is contained in:
parent
a4809555e9
commit
c852393076
@ -18,9 +18,9 @@ pub const BlockEntityType = struct {
|
|||||||
|
|
||||||
const VTable = struct {
|
const VTable = struct {
|
||||||
onLoadClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
onLoadClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
||||||
onUnloadClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
onUnloadClient: *const fn(dataIndex: BlockEntityIndex) void,
|
||||||
onLoadServer: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
onLoadServer: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
||||||
onUnloadServer: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
onUnloadServer: *const fn(dataIndex: BlockEntityIndex) void,
|
||||||
onPlaceClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
onPlaceClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
||||||
onBreakClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
onBreakClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
||||||
onPlaceServer: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
onPlaceServer: *const fn(pos: Vec3i, chunk: *Chunk) void,
|
||||||
@ -45,14 +45,14 @@ pub const BlockEntityType = struct {
|
|||||||
pub inline fn onLoadClient(self: *BlockEntityType, pos: Vec3i, chunk: *Chunk) void {
|
pub inline fn onLoadClient(self: *BlockEntityType, pos: Vec3i, chunk: *Chunk) void {
|
||||||
return self.vtable.onLoadClient(pos, chunk);
|
return self.vtable.onLoadClient(pos, chunk);
|
||||||
}
|
}
|
||||||
pub inline fn onUnloadClient(self: *BlockEntityType, pos: Vec3i, chunk: *Chunk) void {
|
pub inline fn onUnloadClient(self: *BlockEntityType, dataIndex: BlockEntityIndex) void {
|
||||||
return self.vtable.onUnloadClient(pos, chunk);
|
return self.vtable.onUnloadClient(dataIndex);
|
||||||
}
|
}
|
||||||
pub inline fn onLoadServer(self: *BlockEntityType, pos: Vec3i, chunk: *Chunk) void {
|
pub inline fn onLoadServer(self: *BlockEntityType, pos: Vec3i, chunk: *Chunk) void {
|
||||||
return self.vtable.onLoadServer(pos, chunk);
|
return self.vtable.onLoadServer(pos, chunk);
|
||||||
}
|
}
|
||||||
pub inline fn onUnloadServer(self: *BlockEntityType, pos: Vec3i, chunk: *Chunk) void {
|
pub inline fn onUnloadServer(self: *BlockEntityType, dataIndex: BlockEntityIndex) void {
|
||||||
return self.vtable.onUnloadServer(pos, chunk);
|
return self.vtable.onUnloadServer(dataIndex);
|
||||||
}
|
}
|
||||||
pub inline fn onPlaceClient(self: *BlockEntityType, pos: Vec3i, chunk: *Chunk) void {
|
pub inline fn onPlaceClient(self: *BlockEntityType, pos: Vec3i, chunk: *Chunk) void {
|
||||||
return self.vtable.onPlaceClient(pos, chunk);
|
return self.vtable.onPlaceClient(pos, chunk);
|
||||||
@ -117,6 +117,13 @@ fn BlockEntityDataStorage(T: type) type {
|
|||||||
chunk.blockPosToEntityDataMap.put(main.globalAllocator.allocator, blockIndex, @intCast(dataIndex)) catch unreachable;
|
chunk.blockPosToEntityDataMap.put(main.globalAllocator.allocator, blockIndex, @intCast(dataIndex)) catch unreachable;
|
||||||
chunk.blockPosToEntityDataMapMutex.unlock();
|
chunk.blockPosToEntityDataMapMutex.unlock();
|
||||||
}
|
}
|
||||||
|
pub fn removeAtIndex(dataIndex: BlockEntityIndex) void {
|
||||||
|
main.utils.assertLocked(&mutex);
|
||||||
|
freeIndexList.append(main.globalAllocator, dataIndex);
|
||||||
|
storage.remove(dataIndex) catch |err| {
|
||||||
|
std.log.err("Error while removing block entity: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
}
|
||||||
pub fn remove(pos: Vec3i, chunk: *Chunk) void {
|
pub fn remove(pos: Vec3i, chunk: *Chunk) void {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
defer mutex.unlock();
|
defer mutex.unlock();
|
||||||
@ -133,10 +140,7 @@ fn BlockEntityDataStorage(T: type) type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const dataIndex = entry.value;
|
const dataIndex = entry.value;
|
||||||
freeIndexList.append(main.globalAllocator, dataIndex);
|
removeAtIndex(dataIndex);
|
||||||
storage.remove(dataIndex) catch |err| {
|
|
||||||
std.log.err("Error while remvoing block entity at position {}: {s}", .{pos, @errorName(err)});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
pub fn get(pos: Vec3i, chunk: *Chunk) ?*DataT {
|
pub fn get(pos: Vec3i, chunk: *Chunk) ?*DataT {
|
||||||
main.utils.assertLocked(&mutex);
|
main.utils.assertLocked(&mutex);
|
||||||
@ -175,9 +179,13 @@ pub const BlockEntityTypes = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn onLoadClient(_: Vec3i, _: *Chunk) void {}
|
pub fn onLoadClient(_: Vec3i, _: *Chunk) void {}
|
||||||
pub fn onUnloadClient(_: Vec3i, _: *Chunk) void {}
|
pub fn onUnloadClient(_: BlockEntityIndex) void {}
|
||||||
pub fn onLoadServer(_: Vec3i, _: *Chunk) void {}
|
pub fn onLoadServer(_: Vec3i, _: *Chunk) void {}
|
||||||
pub fn onUnloadServer(_: Vec3i, _: *Chunk) void {}
|
pub fn onUnloadServer(dataIndex: BlockEntityIndex) void {
|
||||||
|
StorageServer.mutex.lock();
|
||||||
|
defer StorageServer.mutex.unlock();
|
||||||
|
StorageServer.removeAtIndex(dataIndex);
|
||||||
|
}
|
||||||
pub fn onPlaceClient(_: Vec3i, _: *Chunk) void {}
|
pub fn onPlaceClient(_: Vec3i, _: *Chunk) void {}
|
||||||
pub fn onBreakClient(_: Vec3i, _: *Chunk) void {}
|
pub fn onBreakClient(_: Vec3i, _: *Chunk) void {}
|
||||||
pub fn onPlaceServer(_: Vec3i, _: *Chunk) void {}
|
pub fn onPlaceServer(_: Vec3i, _: *Chunk) void {}
|
||||||
|
@ -284,6 +284,27 @@ pub const Chunk = struct { // MARK: Chunk
|
|||||||
memoryPool.destroy(@alignCast(self));
|
memoryPool.destroy(@alignCast(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unloadBlockEntities(self: *Chunk, comptime side: main.utils.Side) void {
|
||||||
|
self.blockPosToEntityDataMapMutex.lock();
|
||||||
|
defer self.blockPosToEntityDataMapMutex.unlock();
|
||||||
|
var iterator = self.blockPosToEntityDataMap.iterator();
|
||||||
|
while(iterator.next()) |elem| {
|
||||||
|
const index = elem.key_ptr.*;
|
||||||
|
const entityDataIndex = elem.value_ptr.*;
|
||||||
|
const block = self.data.getValue(index);
|
||||||
|
const blockEntity = block.blockEntity() orelse unreachable;
|
||||||
|
switch(side) {
|
||||||
|
.client => {
|
||||||
|
blockEntity.onUnloadClient(entityDataIndex);
|
||||||
|
},
|
||||||
|
.server => {
|
||||||
|
blockEntity.onUnloadServer(entityDataIndex);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.blockPosToEntityDataMap.clearRetainingCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates a block if it is inside this chunk.
|
/// Updates a block if it is inside this chunk.
|
||||||
/// Does not do any bound checks. They are expected to be done with the `liesInChunk` function.
|
/// Does not do any bound checks. They are expected to be done with the `liesInChunk` function.
|
||||||
pub fn updateBlock(self: *Chunk, _x: i32, _y: i32, _z: i32, newBlock: Block) void {
|
pub fn updateBlock(self: *Chunk, _x: i32, _y: i32, _z: i32, newBlock: Block) void {
|
||||||
|
@ -694,6 +694,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
|
|||||||
chunkBuffer.free(self.chunkAllocation);
|
chunkBuffer.free(self.chunkAllocation);
|
||||||
self.opaqueMesh.deinit();
|
self.opaqueMesh.deinit();
|
||||||
self.transparentMesh.deinit();
|
self.transparentMesh.deinit();
|
||||||
|
self.chunk.unloadBlockEntities(.client);
|
||||||
self.chunk.deinit();
|
self.chunk.deinit();
|
||||||
main.globalAllocator.free(self.currentSorting);
|
main.globalAllocator.free(self.currentSorting);
|
||||||
main.globalAllocator.free(self.sortingOutputBuffer);
|
main.globalAllocator.free(self.sortingOutputBuffer);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user