Skip to content

Commit 830b597

Browse files
Add logic for unloading block entities
1 parent 224f8c8 commit 830b597

File tree

3 files changed

+60
-24
lines changed

3 files changed

+60
-24
lines changed

src/chunk.zig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,27 @@ pub const Chunk = struct { // MARK: Chunk
284284
memoryPool.destroy(@alignCast(self));
285285
}
286286

287+
pub fn unloadBlockEntities(self: *Chunk, comptime side: main.utils.Side) void {
288+
self.blockPosToEntityDataMapMutex.lock();
289+
defer self.blockPosToEntityDataMapMutex.unlock();
290+
var iterator = self.blockPosToEntityDataMap.iterator();
291+
while(iterator.next()) |elem| {
292+
const index = elem.key_ptr.*;
293+
const entityDataIndex = elem.value_ptr.*;
294+
const block = self.data.getValue(index);
295+
const blockEntity = block.entityDataClass() orelse unreachable;
296+
switch (side) {
297+
.client => {
298+
blockEntity.onUnloadClient(entityDataIndex);
299+
},
300+
.server => {
301+
blockEntity.onUnloadServer(entityDataIndex);
302+
}
303+
}
304+
}
305+
self.blockPosToEntityDataMap.clearRetainingCapacity();
306+
}
307+
287308
/// Updates a block if it is inside this chunk.
288309
/// Does not do any bound checks. They are expected to be done with the `liesInChunk` function.
289310
pub fn updateBlock(self: *Chunk, _x: i32, _y: i32, _z: i32, newBlock: Block) void {

src/entity_data.zig

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ pub const EntityDataClass = struct {
1717

1818
const VTable = struct {
1919
onLoadClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
20-
onUnloadClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
20+
onUnloadClient: *const fn(dataIndex: u32) void,
2121
onLoadServer: *const fn(pos: Vec3i, chunk: *Chunk) void,
22-
onUnloadServer: *const fn(pos: Vec3i, chunk: *Chunk) void,
22+
onUnloadServer: *const fn(dataIndex: u32) void,
2323
onPlaceClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
2424
onBreakClient: *const fn(pos: Vec3i, chunk: *Chunk) void,
2525
onPlaceServer: *const fn(pos: Vec3i, chunk: *Chunk) void,
@@ -44,14 +44,14 @@ pub const EntityDataClass = struct {
4444
pub inline fn onLoadClient(self: *EntityDataClass, pos: Vec3i, chunk: *Chunk) void {
4545
return self.vtable.onLoadClient(pos, chunk);
4646
}
47-
pub inline fn onUnloadClient(self: *EntityDataClass, pos: Vec3i, chunk: *Chunk) void {
48-
return self.vtable.onUnloadClient(pos, chunk);
47+
pub inline fn onUnloadClient(self: *EntityDataClass, dataIndex: u32) void {
48+
return self.vtable.onUnloadClient(dataIndex);
4949
}
5050
pub inline fn onLoadServer(self: *EntityDataClass, pos: Vec3i, chunk: *Chunk) void {
5151
return self.vtable.onLoadServer(pos, chunk);
5252
}
53-
pub inline fn onUnloadServer(self: *EntityDataClass, pos: Vec3i, chunk: *Chunk) void {
54-
return self.vtable.onUnloadServer(pos, chunk);
53+
pub inline fn onUnloadServer(self: *EntityDataClass, dataIndex: u32) void {
54+
return self.vtable.onUnloadServer(dataIndex);
5555
}
5656
pub inline fn onPlaceClient(self: *EntityDataClass, pos: Vec3i, chunk: *Chunk) void {
5757
return self.vtable.onPlaceClient(pos, chunk);
@@ -107,6 +107,20 @@ fn BlockEntityDataStorage(comptime side: enum {client, server}, T: type) type {
107107
chunk.blockPosToEntityDataMap.put(main.globalAllocator.allocator, blockIndex, @intCast(dataIndex)) catch unreachable;
108108
chunk.blockPosToEntityDataMapMutex.unlock();
109109
}
110+
pub fn removeByIndex(dataIndex: u32) void {
111+
main.utils.assertLocked(&mutex);
112+
113+
_ = storage.swapRemove(dataIndex);
114+
if(dataIndex == storage.items.len) {
115+
return;
116+
}
117+
118+
const movedEntry = storage.items[dataIndex];
119+
switch(side) {
120+
.server => propagateRemoveServer(movedEntry.absoluteBlockPosition, dataIndex),
121+
.client => propagateRemoveClient(movedEntry.absoluteBlockPosition, dataIndex),
122+
}
123+
}
110124
pub fn remove(pos: Vec3i, chunk: *Chunk) void {
111125
mutex.lock();
112126
defer mutex.unlock();
@@ -122,17 +136,7 @@ fn BlockEntityDataStorage(comptime side: enum {client, server}, T: type) type {
122136
return;
123137
};
124138

125-
const dataIndex = entry.value;
126-
_ = storage.swapRemove(dataIndex);
127-
if(dataIndex == storage.items.len) {
128-
return;
129-
}
130-
131-
const movedEntry = storage.items[dataIndex];
132-
switch(side) {
133-
.server => propagateRemoveServer(movedEntry.absoluteBlockPosition, dataIndex),
134-
.client => propagateRemoveClient(movedEntry.absoluteBlockPosition, dataIndex),
135-
}
139+
removeByIndex(entry.value);
136140
}
137141
fn propagateRemoveServer(pos: Vec3i, index: u32) void {
138142
const severChunk = server.world.?.getChunkFromCacheAndIncreaseRefCount(ChunkPosition.initFromWorldPos(pos, 1)).?;
@@ -192,9 +196,9 @@ pub const EntityDataClasses = struct {
192196
}
193197

194198
pub fn onLoadClient(_: Vec3i, _: *Chunk) void {}
195-
pub fn onUnloadClient(_: Vec3i, _: *Chunk) void {}
199+
pub fn onUnloadClient(_: u32) void {}
196200
pub fn onLoadServer(_: Vec3i, _: *Chunk) void {}
197-
pub fn onUnloadServer(_: Vec3i, _: *Chunk) void {}
201+
pub fn onUnloadServer(_: u32) void {}
198202
pub fn onPlaceClient(_: Vec3i, _: *Chunk) void {}
199203
pub fn onBreakClient(_: Vec3i, _: *Chunk) void {}
200204
pub fn onPlaceServer(_: Vec3i, _: *Chunk) void {}
@@ -238,12 +242,22 @@ pub const EntityDataClasses = struct {
238242
}
239243

240244
pub fn onLoadClient(_: Vec3i, _: *Chunk) void {}
241-
pub fn onUnloadClient(_: Vec3i, _: *Chunk) void {}
245+
pub fn onUnloadClient(dataIndex: u32) void {
246+
StorageClient.mutex.lock();
247+
defer StorageClient.mutex.unlock();
248+
StorageClient.removeByIndex(dataIndex);
249+
}
242250
pub fn onLoadServer(_: Vec3i, _: *Chunk) void {}
243-
pub fn onUnloadServer(_: Vec3i, _: *Chunk) void {}
244-
pub fn onPlaceClient(_: Vec3i, _: *Chunk) void {}
245-
pub fn onBreakClient(_: Vec3i, _: *Chunk) void {}
246-
pub fn onPlaceServer(_: Vec3i, _: *Chunk) void {}
251+
pub fn onUnloadServer(_: u32) void {}
252+
pub fn onPlaceClient(pos: Vec3i, chunk: *Chunk) void {
253+
StorageClient.add(pos, .{.text = "test"}, chunk);
254+
}
255+
pub fn onBreakClient(pos: Vec3i, chunk: *Chunk) void {
256+
StorageClient.remove(pos, chunk);
257+
}
258+
pub fn onPlaceServer(pos: Vec3i, chunk: *Chunk) void {
259+
StorageServer.add(pos, .{.text = "test"}, chunk);
260+
}
247261
pub fn onBreakServer(pos: Vec3i, chunk: *Chunk) void {
248262
StorageServer.remove(pos, chunk);
249263
}

src/renderer/chunk_meshing.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
694694
chunkBuffer.free(self.chunkAllocation);
695695
self.opaqueMesh.deinit();
696696
self.transparentMesh.deinit();
697+
self.chunk.unloadBlockEntities(.client);
697698
self.chunk.deinit();
698699
main.globalAllocator.free(self.currentSorting);
699700
main.globalAllocator.free(self.sortingOutputBuffer);

0 commit comments

Comments
 (0)