Skip to content

Commit

Permalink
Ensures that all chunks are stored within 5 seconds of an update.
Browse files Browse the repository at this point in the history
Closes #348
  • Loading branch information
IntegratedQuantum committed May 14, 2024
1 parent cca1c14 commit 814bced
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 3 deletions.
12 changes: 10 additions & 2 deletions src/chunk.zig
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ pub const Chunk = struct {
memoryPoolMutex.unlock();
}

fn setChanged(self: *Chunk) void {
main.utils.assertLocked(&self.mutex);
if(!self.wasChanged) {
self.wasChanged = true;
main.server.world.?.queueChunkUpdate(self);
}
}

/// Checks if the given relative coordinates lie within the bounds of this chunk.
pub fn liesInChunk(self: *const Chunk, x: i32, y: i32, z: i32) bool {
return x >= 0 and x < self.width
Expand Down Expand Up @@ -258,7 +266,7 @@ pub const Chunk = struct {
const z = _z >> self.voxelSizeShift;
const index = getIndex(x, y, z);
self.data.setValue(index, newBlock);
self.wasChanged = true;
self.setChanged();
}

/// Updates a block if it is inside this chunk. Should be used in generation to prevent accidently storing these as changes.
Expand Down Expand Up @@ -348,7 +356,7 @@ pub const Chunk = struct {
}
}

self.wasChanged = true;
self.setChanged();
}

pub fn save(self: *Chunk, world: *main.server.ServerWorld) void {
Expand Down
2 changes: 2 additions & 0 deletions src/network.zig
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,8 @@ pub const Protocols = struct {
if(conn.user != null) { // TODO: Send update event to other players.
const mask = ~@as(i32, chunk.chunkMask);
const ch = main.server.world.?.getOrGenerateChunk(.{.wx = x & mask, .wy = y & mask, .wz = z & mask, .voxelSize = 1});
ch.mutex.lock();
defer ch.mutex.unlock();
ch.updateBlockAndSetChanged(x & chunk.chunkMask, y & chunk.chunkMask, z & chunk.chunkMask, newBlock);
} else {
renderer.mesh_storage.updateBlock(x, y, z, newBlock);
Expand Down
5 changes: 4 additions & 1 deletion src/server/storage.zig
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,13 @@ pub const RegionFile = struct {
pub fn storeChunk(self: *RegionFile, ch: []const u8, relX: usize, relY: usize, relZ: usize) void {
self.mutex.lock();
defer self.mutex.unlock();
self.modified = true;
const index = getIndex(relX, relY, relZ);
self.chunks[index] = main.globalAllocator.realloc(self.chunks[index], ch.len);
@memcpy(self.chunks[index], ch);
if(!self.modified) {
self.modified = true;
main.server.world.?.queueRegionFileUpdate(self);
}
}

pub fn getChunk(self: *RegionFile, allocator: main.utils.NeverFailingAllocator, relX: usize, relY: usize, relZ: usize) ?[]const u8 {
Expand Down
49 changes: 49 additions & 0 deletions src/server/world.zig
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,21 @@ pub const ServerWorld = struct {

wio: WorldIO = undefined,

mutex: std.Thread.Mutex = .{},

chunkUpdateQueue: main.utils.CircularBufferQueue(ChunkUpdateRequest),
regionUpdateQueue: main.utils.CircularBufferQueue(RegionUpdateRequest),

const ChunkUpdateRequest = struct {
ch: *Chunk,
milliTimeStamp: i64,
};

const RegionUpdateRequest = struct {
region: *storage.RegionFile,
milliTimeStamp: i64,
};

pub fn init(name: []const u8, nullGeneratorSettings: ?JsonElement) !*ServerWorld {
const self = main.globalAllocator.create(ServerWorld);
errdefer main.globalAllocator.destroy(self);
Expand All @@ -329,6 +344,8 @@ pub const ServerWorld = struct {
.lastUnimportantDataSent = std.time.milliTimestamp(),
.seed = @bitCast(@as(i64, @truncate(std.time.nanoTimestamp()))),
.name = main.globalAllocator.dupe(u8, name),
.chunkUpdateQueue = main.utils.CircularBufferQueue(ChunkUpdateRequest).init(main.globalAllocator, 256),
.regionUpdateQueue = main.utils.CircularBufferQueue(RegionUpdateRequest).init(main.globalAllocator, 256),
};
self.itemDropManager.init(main.globalAllocator, self, self.gravity);
errdefer self.itemDropManager.deinit();
Expand Down Expand Up @@ -372,6 +389,14 @@ pub const ServerWorld = struct {
}

pub fn deinit(self: *ServerWorld) void {
while(self.chunkUpdateQueue.dequeue()) |updateRequest| {
updateRequest.ch.save(self);
}
self.chunkUpdateQueue.deinit();
while(self.regionUpdateQueue.dequeue()) |updateRequest| {
updateRequest.region.store();
}
self.regionUpdateQueue.deinit();
self.chunkManager.deinit();
self.itemDropManager.deinit();
self.blockPalette.deinit();
Expand Down Expand Up @@ -462,6 +487,19 @@ pub const ServerWorld = struct {

// Item Entities
self.itemDropManager.update(deltaTime);

// Store chunks and regions.
// Stores at least one chunk and one region per iteration.
// All chunks and regions will be stored within the storage time.
const insertionTime = newTime -% main.settings.storageTime;
while(self.chunkUpdateQueue.dequeue()) |updateRequest| {
updateRequest.ch.save(self);
if(updateRequest.milliTimeStamp -% insertionTime <= 0) break;
}
while(self.regionUpdateQueue.dequeue()) |updateRequest| {
updateRequest.region.store();
if(updateRequest.milliTimeStamp -% insertionTime <= 0) break;
}
}

pub fn queueChunks(self: *ServerWorld, positions: []ChunkPosition, source: ?*User) void {
Expand Down Expand Up @@ -504,4 +542,15 @@ pub const ServerWorld = struct {
return Block {.typ = 0, .data = 0};
}

pub fn queueChunkUpdate(self: *ServerWorld, ch: *Chunk) void {
self.mutex.lock();
self.chunkUpdateQueue.enqueue(.{.ch = ch, .milliTimeStamp = std.time.milliTimestamp()});
self.mutex.unlock();
}

pub fn queueRegionFileUpdate(self: *ServerWorld, region: *storage.RegionFile) void {
self.mutex.lock();
self.regionUpdateQueue.enqueue(.{.region = region, .milliTimeStamp = std.time.milliTimestamp()});
self.mutex.unlock();
}
};
3 changes: 3 additions & 0 deletions src/settings.zig
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ pub var guiScale: ?f32 = null;
pub var musicVolume: f32 = 1;


pub var storageTime: i64 = 5000;


pub var developerAutoEnterWorld: []const u8 = "";


Expand Down

0 comments on commit 814bced

Please sign in to comment.