mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Ensures that all chunks are stored within 5 seconds of an update.
Closes #348
This commit is contained in:
parent
cca1c14242
commit
814bcedcba
@ -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
|
||||
@ -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.
|
||||
@ -348,7 +356,7 @@ pub const Chunk = struct {
|
||||
}
|
||||
}
|
||||
|
||||
self.wasChanged = true;
|
||||
self.setChanged();
|
||||
}
|
||||
|
||||
pub fn save(self: *Chunk, world: *main.server.ServerWorld) void {
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
@ -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();
|
||||
@ -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();
|
||||
@ -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 {
|
||||
@ -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();
|
||||
}
|
||||
};
|
||||
|
@ -37,6 +37,9 @@ pub var guiScale: ?f32 = null;
|
||||
pub var musicVolume: f32 = 1;
|
||||
|
||||
|
||||
pub var storageTime: i64 = 5000;
|
||||
|
||||
|
||||
pub var developerAutoEnterWorld: []const u8 = "";
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user