mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Improve the StackAllocator so it allows all kinds of allocation patterns.
This allows using the StackAllocator for more data structures and library functions. Fixes #268 Fixes #95 (at least to the point where I can't do anything about it)
This commit is contained in:
parent
0177099f6b
commit
d08096057f
@ -25,7 +25,7 @@ pub fn readAllJsonFilesInAddons(externalAllocator: NeverFailingAllocator, addons
|
|||||||
};
|
};
|
||||||
defer dir.close();
|
defer dir.close();
|
||||||
|
|
||||||
var walker = dir.walk(main.globalAllocator.allocator) catch unreachable;
|
var walker = dir.walk(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer walker.deinit();
|
defer walker.deinit();
|
||||||
|
|
||||||
while(walker.next() catch |err| blk: {
|
while(walker.next() catch |err| blk: {
|
||||||
@ -69,7 +69,7 @@ pub fn readAllFilesInAddons(externalAllocator: NeverFailingAllocator, addons: ma
|
|||||||
};
|
};
|
||||||
defer dir.close();
|
defer dir.close();
|
||||||
|
|
||||||
var walker = dir.walk(main.globalAllocator.allocator) catch unreachable;
|
var walker = dir.walk(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer walker.deinit();
|
defer walker.deinit();
|
||||||
|
|
||||||
while(walker.next() catch |err| blk: {
|
while(walker.next() catch |err| blk: {
|
||||||
@ -90,9 +90,9 @@ pub fn readAllFilesInAddons(externalAllocator: NeverFailingAllocator, addons: ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u8, blocks: *std.StringHashMap(JsonElement), items: *std.StringHashMap(JsonElement), biomes: *std.StringHashMap(JsonElement), recipes: *main.List([]const u8)) void {
|
pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u8, blocks: *std.StringHashMap(JsonElement), items: *std.StringHashMap(JsonElement), biomes: *std.StringHashMap(JsonElement), recipes: *main.List([]const u8)) void {
|
||||||
var addons = main.List(std.fs.Dir).init(main.globalAllocator);
|
var addons = main.List(std.fs.Dir).init(main.stackAllocator);
|
||||||
defer addons.deinit();
|
defer addons.deinit();
|
||||||
var addonNames = main.List([]const u8).init(main.globalAllocator);
|
var addonNames = main.List([]const u8).init(main.stackAllocator);
|
||||||
defer addonNames.deinit();
|
defer addonNames.deinit();
|
||||||
|
|
||||||
{ // Find all the sub-directories to the assets folder.
|
{ // Find all the sub-directories to the assets folder.
|
||||||
@ -111,13 +111,13 @@ pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u
|
|||||||
std.log.err("Got error while reading addon {s} from {s}: {s}", .{addon.name, assetPath, @errorName(err)});
|
std.log.err("Got error while reading addon {s} from {s}: {s}", .{addon.name, assetPath, @errorName(err)});
|
||||||
continue;
|
continue;
|
||||||
});
|
});
|
||||||
addonNames.append(main.globalAllocator.dupe(u8, addon.name));
|
addonNames.append(main.stackAllocator.dupe(u8, addon.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer for(addons.items, addonNames.items) |*dir, addonName| {
|
defer for(addons.items, addonNames.items) |*dir, addonName| {
|
||||||
dir.close();
|
dir.close();
|
||||||
main.globalAllocator.free(addonName);
|
main.stackAllocator.free(addonName);
|
||||||
};
|
};
|
||||||
|
|
||||||
readAllJsonFilesInAddons(externalAllocator, addons, addonNames, "blocks", blocks);
|
readAllJsonFilesInAddons(externalAllocator, addons, addonNames, "blocks", blocks);
|
||||||
@ -224,13 +224,13 @@ var loadedAssets: bool = false;
|
|||||||
pub fn loadWorldAssets(assetFolder: []const u8, palette: *BlockPalette) !void {
|
pub fn loadWorldAssets(assetFolder: []const u8, palette: *BlockPalette) !void {
|
||||||
if(loadedAssets) return; // The assets already got loaded by the server.
|
if(loadedAssets) return; // The assets already got loaded by the server.
|
||||||
loadedAssets = true;
|
loadedAssets = true;
|
||||||
var blocks = commonBlocks.cloneWithAllocator(main.globalAllocator.allocator) catch unreachable;
|
var blocks = commonBlocks.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer blocks.clearAndFree();
|
defer blocks.clearAndFree();
|
||||||
var items = commonItems.cloneWithAllocator(main.globalAllocator.allocator) catch unreachable;
|
var items = commonItems.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer items.clearAndFree();
|
defer items.clearAndFree();
|
||||||
var biomes = commonBiomes.cloneWithAllocator(main.globalAllocator.allocator) catch unreachable;
|
var biomes = commonBiomes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer biomes.clearAndFree();
|
defer biomes.clearAndFree();
|
||||||
var recipes = main.List([]const u8).init(main.globalAllocator);
|
var recipes = main.List([]const u8).init(main.stackAllocator);
|
||||||
recipes.appendSlice(commonRecipes.items);
|
recipes.appendSlice(commonRecipes.items);
|
||||||
defer recipes.clearAndFree();
|
defer recipes.clearAndFree();
|
||||||
|
|
||||||
|
@ -391,10 +391,8 @@ pub const draw = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn print(comptime format: []const u8, args: anytype, x: f32, y: f32, fontSize: f32, alignment: TextBuffer.Alignment) void {
|
pub inline fn print(comptime format: []const u8, args: anytype, x: f32, y: f32, fontSize: f32, alignment: TextBuffer.Alignment) void {
|
||||||
var stackFallback = std.heap.stackFallback(4096, main.globalAllocator.allocator);
|
const string = std.fmt.allocPrint(main.stackAllocator.allocator, format, args) catch unreachable;
|
||||||
const allocator = stackFallback.get();
|
defer main.stackAllocator.free(string);
|
||||||
const string = std.fmt.allocPrint(allocator, format, args) catch unreachable;
|
|
||||||
defer allocator.free(string);
|
|
||||||
text(string, x, y ,fontSize, alignment);
|
text(string, x, y ,fontSize, alignment);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -560,13 +558,11 @@ pub const TextBuffer = struct {
|
|||||||
pub fn init(allocator: NeverFailingAllocator, text: []const u8, initialFontEffect: FontEffect, showControlCharacters: bool, alignment: Alignment) TextBuffer {
|
pub fn init(allocator: NeverFailingAllocator, text: []const u8, initialFontEffect: FontEffect, showControlCharacters: bool, alignment: Alignment) TextBuffer {
|
||||||
var self: TextBuffer = undefined;
|
var self: TextBuffer = undefined;
|
||||||
self.alignment = alignment;
|
self.alignment = alignment;
|
||||||
var stackFallback = std.heap.stackFallback(4096, main.globalAllocator.allocator);
|
|
||||||
const stackFallbackAllocator = stackFallback.get();
|
|
||||||
// Parse the input text:
|
// Parse the input text:
|
||||||
var parser = Parser {
|
var parser = Parser {
|
||||||
.unicodeIterator = std.unicode.Utf8Iterator{.bytes = text, .i = 0},
|
.unicodeIterator = std.unicode.Utf8Iterator{.bytes = text, .i = 0},
|
||||||
.currentFontEffect = initialFontEffect,
|
.currentFontEffect = initialFontEffect,
|
||||||
.parsedText = main.List(u32).init(.{.allocator = stackFallbackAllocator, .IAssertThatTheProvidedAllocatorCantFail = {}}),
|
.parsedText = main.List(u32).init(main.stackAllocator),
|
||||||
.fontEffects = main.List(FontEffect).init(allocator),
|
.fontEffects = main.List(FontEffect).init(allocator),
|
||||||
.characterIndex = main.List(u32).init(allocator),
|
.characterIndex = main.List(u32).init(allocator),
|
||||||
.showControlCharacters = showControlCharacters
|
.showControlCharacters = showControlCharacters
|
||||||
@ -1040,9 +1036,7 @@ const TextRendering = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn renderText(text: []const u8, x: f32, y: f32, fontSize: f32, initialFontEffect: TextBuffer.FontEffect, alignment: TextBuffer.Alignment) void {
|
fn renderText(text: []const u8, x: f32, y: f32, fontSize: f32, initialFontEffect: TextBuffer.FontEffect, alignment: TextBuffer.Alignment) void {
|
||||||
var stackFallback = std.heap.stackFallback(4096, main.globalAllocator.allocator);
|
const buf = TextBuffer.init(main.stackAllocator, text, initialFontEffect, false, alignment);
|
||||||
const allocator = stackFallback.get();
|
|
||||||
const buf = TextBuffer.init(.{.allocator = allocator, .IAssertThatTheProvidedAllocatorCantFail = {}}, text, initialFontEffect, false, alignment);
|
|
||||||
defer buf.deinit();
|
defer buf.deinit();
|
||||||
|
|
||||||
buf.render(x, y, fontSize);
|
buf.render(x, y, fontSize);
|
||||||
@ -1530,7 +1524,7 @@ pub const TextureArray = struct {
|
|||||||
|
|
||||||
const maxLOD = if(mipmapping) 1 + std.math.log2_int(u31, @min(maxWidth, maxHeight)) else 1;
|
const maxLOD = if(mipmapping) 1 + std.math.log2_int(u31, @min(maxWidth, maxHeight)) else 1;
|
||||||
c.glTexStorage3D(c.GL_TEXTURE_2D_ARRAY, maxLOD, c.GL_RGBA8, maxWidth, maxHeight, @intCast(images.len));
|
c.glTexStorage3D(c.GL_TEXTURE_2D_ARRAY, maxLOD, c.GL_RGBA8, maxWidth, maxHeight, @intCast(images.len));
|
||||||
var arena = main.utils.NeverFailingArenaAllocator.init(main.globalAllocator);
|
var arena = main.utils.NeverFailingArenaAllocator.init(main.stackAllocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const lodBuffer: [][]Color = arena.allocator().alloc([]Color, maxLOD);
|
const lodBuffer: [][]Color = arena.allocator().alloc([]Color, maxLOD);
|
||||||
for(lodBuffer, 0..) |*buffer, i| {
|
for(lodBuffer, 0..) |*buffer, i| {
|
||||||
|
@ -182,12 +182,12 @@ pub fn deinit() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn save() void {
|
fn save() void {
|
||||||
const guiJson = JsonElement.initObject(main.globalAllocator);
|
const guiJson = JsonElement.initObject(main.stackAllocator);
|
||||||
defer guiJson.free(main.globalAllocator);
|
defer guiJson.free(main.stackAllocator);
|
||||||
for(windowList.items) |window| {
|
for(windowList.items) |window| {
|
||||||
const windowJson = JsonElement.initObject(main.globalAllocator);
|
const windowJson = JsonElement.initObject(main.stackAllocator);
|
||||||
for(window.relativePosition, 0..) |relPos, i| {
|
for(window.relativePosition, 0..) |relPos, i| {
|
||||||
const relPosJson = JsonElement.initObject(main.globalAllocator);
|
const relPosJson = JsonElement.initObject(main.stackAllocator);
|
||||||
switch(relPos) {
|
switch(relPos) {
|
||||||
.ratio => |ratio| {
|
.ratio => |ratio| {
|
||||||
relPosJson.put("type", "ratio");
|
relPosJson.put("type", "ratio");
|
||||||
@ -222,13 +222,13 @@ fn save() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load() void {
|
fn load() void {
|
||||||
const json: JsonElement = main.files.readToJson(main.globalAllocator, "gui_layout.json") catch |err| blk: {
|
const json: JsonElement = main.files.readToJson(main.stackAllocator, "gui_layout.json") catch |err| blk: {
|
||||||
if(err != error.FileNotFound) {
|
if(err != error.FileNotFound) {
|
||||||
std.log.err("Could not read gui_layout.json: {s}", .{@errorName(err)});
|
std.log.err("Could not read gui_layout.json: {s}", .{@errorName(err)});
|
||||||
}
|
}
|
||||||
break :blk JsonElement{.JsonNull={}};
|
break :blk JsonElement{.JsonNull={}};
|
||||||
};
|
};
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
|
|
||||||
for(windowList.items) |window| {
|
for(windowList.items) |window| {
|
||||||
const windowJson = json.getChild(window.id);
|
const windowJson = json.getChild(window.id);
|
||||||
@ -649,7 +649,7 @@ pub const inventory = struct {
|
|||||||
if(carriedItemStack.amount == 0) if(hoveredItemSlot) |hovered| {
|
if(carriedItemStack.amount == 0) if(hoveredItemSlot) |hovered| {
|
||||||
if(hovered.itemStack.item) |item| {
|
if(hovered.itemStack.item) |item| {
|
||||||
const tooltip = item.getTooltip();
|
const tooltip = item.getTooltip();
|
||||||
var textBuffer: graphics.TextBuffer = graphics.TextBuffer.init(main.globalAllocator, tooltip, .{}, false, .left);
|
var textBuffer: graphics.TextBuffer = graphics.TextBuffer.init(main.stackAllocator, tooltip, .{}, false, .left);
|
||||||
defer textBuffer.deinit();
|
defer textBuffer.deinit();
|
||||||
var size = textBuffer.calculateLineBreaks(16, 256);
|
var size = textBuffer.calculateLineBreaks(16, 256);
|
||||||
size[0] = 0;
|
size[0] = 0;
|
||||||
|
@ -275,10 +275,10 @@ pub const ItemDropManager = struct {
|
|||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
if(self.size == maxCapacity) {
|
if(self.size == maxCapacity) {
|
||||||
const json = itemStack.store(main.globalAllocator);
|
const json = itemStack.store(main.stackAllocator);
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
const string = json.toString(main.stackAllocator);
|
const string = json.toString(main.stackAllocator);
|
||||||
defer main.globalAllocator.free(string);
|
defer main.stackAllocator.free(string);
|
||||||
std.log.err("Item drop capacitiy limit reached. Failed to add itemStack: {s}", .{string});
|
std.log.err("Item drop capacitiy limit reached. Failed to add itemStack: {s}", .{string});
|
||||||
if(itemStack.item) |item| {
|
if(itemStack.item) |item| {
|
||||||
item.deinit();
|
item.deinit();
|
||||||
|
@ -441,7 +441,7 @@ const TextureGenerator = struct {
|
|||||||
var pixelMaterials: [16][16]PixelData = undefined;
|
var pixelMaterials: [16][16]PixelData = undefined;
|
||||||
for(0..16) |x| {
|
for(0..16) |x| {
|
||||||
for(0..16) |y| {
|
for(0..16) |y| {
|
||||||
pixelMaterials[x][y] = PixelData.init(main.globalAllocator);
|
pixelMaterials[x][y] = PixelData.init(main.stackAllocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1331,19 +1331,19 @@ pub fn register(_: []const u8, texturePath: []const u8, replacementTexturePath:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn registerRecipes(file: []const u8) void {
|
pub fn registerRecipes(file: []const u8) void {
|
||||||
var shortcuts = std.StringHashMap(*BaseItem).init(main.globalAllocator.allocator);
|
var shortcuts = std.StringHashMap(*BaseItem).init(main.stackAllocator.allocator);
|
||||||
defer shortcuts.deinit();
|
defer shortcuts.deinit();
|
||||||
defer {
|
defer {
|
||||||
var keyIterator = shortcuts.keyIterator();
|
var keyIterator = shortcuts.keyIterator();
|
||||||
while(keyIterator.next()) |key| {
|
while(keyIterator.next()) |key| {
|
||||||
main.globalAllocator.free(key.*);
|
main.stackAllocator.free(key.*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var items = main.List(*BaseItem).init(main.globalAllocator);
|
var items = main.List(*BaseItem).init(main.stackAllocator);
|
||||||
defer items.deinit();
|
defer items.deinit();
|
||||||
var itemAmounts = main.List(u16).init(main.globalAllocator);
|
var itemAmounts = main.List(u16).init(main.stackAllocator);
|
||||||
defer itemAmounts.deinit();
|
defer itemAmounts.deinit();
|
||||||
var string = main.List(u8).init(main.globalAllocator);
|
var string = main.List(u8).init(main.stackAllocator);
|
||||||
defer string.deinit();
|
defer string.deinit();
|
||||||
var lines = std.mem.split(u8, file, "\n");
|
var lines = std.mem.split(u8, file, "\n");
|
||||||
while(lines.next()) |line| {
|
while(lines.next()) |line| {
|
||||||
|
@ -97,7 +97,7 @@ const Socket = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn resolveIP(addr: []const u8) !u32 {
|
fn resolveIP(addr: []const u8) !u32 {
|
||||||
const list = try std.net.getAddressList(main.globalAllocator.allocator, addr, settings.defaultPort);
|
const list = try std.net.getAddressList(main.stackAllocator.allocator, addr, settings.defaultPort);
|
||||||
defer list.deinit();
|
defer list.deinit();
|
||||||
return list.addrs[0].in.sa.addr;
|
return list.addrs[0].in.sa.addr;
|
||||||
}
|
}
|
||||||
@ -605,8 +605,8 @@ pub const Protocols = struct {
|
|||||||
conn.handShakeState.store(data[0], .Monotonic);
|
conn.handShakeState.store(data[0], .Monotonic);
|
||||||
switch(data[0]) {
|
switch(data[0]) {
|
||||||
stepUserData => {
|
stepUserData => {
|
||||||
const json = JsonElement.parseFromString(main.globalAllocator, data[1..]);
|
const json = JsonElement.parseFromString(main.stackAllocator, data[1..]);
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
const name = json.get([]const u8, "name", "unnamed");
|
const name = json.get([]const u8, "name", "unnamed");
|
||||||
const version = json.get([]const u8, "version", "unknown");
|
const version = json.get([]const u8, "version", "unknown");
|
||||||
std.log.info("User {s} joined using version {s}.", .{name, version});
|
std.log.info("User {s} joined using version {s}.", .{name, version});
|
||||||
@ -617,7 +617,7 @@ pub const Protocols = struct {
|
|||||||
defer main.stackAllocator.free(path);
|
defer main.stackAllocator.free(path);
|
||||||
var dir = try std.fs.cwd().openDir(path, .{.iterate = true});
|
var dir = try std.fs.cwd().openDir(path, .{.iterate = true});
|
||||||
defer dir.close();
|
defer dir.close();
|
||||||
var arrayList = main.List(u8).init(main.globalAllocator);
|
var arrayList = main.List(u8).init(main.stackAllocator);
|
||||||
defer arrayList.deinit();
|
defer arrayList.deinit();
|
||||||
arrayList.append(stepAssets);
|
arrayList.append(stepAssets);
|
||||||
try utils.Compression.pack(dir, arrayList.writer());
|
try utils.Compression.pack(dir, arrayList.writer());
|
||||||
@ -627,13 +627,13 @@ pub const Protocols = struct {
|
|||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
conn.user.?.initPlayer(name);
|
conn.user.?.initPlayer(name);
|
||||||
const jsonObject = JsonElement.initObject(main.globalAllocator);
|
const jsonObject = JsonElement.initObject(main.stackAllocator);
|
||||||
defer jsonObject.free(main.globalAllocator);
|
defer jsonObject.free(main.stackAllocator);
|
||||||
jsonObject.put("player", conn.user.?.player.save(main.globalAllocator));
|
jsonObject.put("player", conn.user.?.player.save(main.stackAllocator));
|
||||||
// TODO:
|
// TODO:
|
||||||
// jsonObject.put("player_id", ((User)conn).player.id);
|
// jsonObject.put("player_id", ((User)conn).player.id);
|
||||||
// jsonObject.put("blockPalette", Server.world.blockPalette.save());
|
// jsonObject.put("blockPalette", Server.world.blockPalette.save());
|
||||||
const spawn = JsonElement.initObject(main.globalAllocator);
|
const spawn = JsonElement.initObject(main.stackAllocator);
|
||||||
spawn.put("x", main.server.world.?.spawn[0]);
|
spawn.put("x", main.server.world.?.spawn[0]);
|
||||||
spawn.put("y", main.server.world.?.spawn[1]);
|
spawn.put("y", main.server.world.?.spawn[1]);
|
||||||
spawn.put("z", main.server.world.?.spawn[2]);
|
spawn.put("z", main.server.world.?.spawn[2]);
|
||||||
@ -657,8 +657,8 @@ pub const Protocols = struct {
|
|||||||
try utils.Compression.unpack(dir, data[1..]);
|
try utils.Compression.unpack(dir, data[1..]);
|
||||||
},
|
},
|
||||||
stepServerData => {
|
stepServerData => {
|
||||||
const json = JsonElement.parseFromString(main.globalAllocator, data[1..]);
|
const json = JsonElement.parseFromString(main.stackAllocator, data[1..]);
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
try conn.manager.world.?.finishHandshake(json);
|
try conn.manager.world.?.finishHandshake(json);
|
||||||
conn.handShakeState.store(stepComplete, .Monotonic);
|
conn.handShakeState.store(stepComplete, .Monotonic);
|
||||||
conn.handShakeWaiting.broadcast(); // Notify the waiting client thread.
|
conn.handShakeWaiting.broadcast(); // Notify the waiting client thread.
|
||||||
@ -680,8 +680,8 @@ pub const Protocols = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn clientSide(conn: *Connection, name: []const u8) void {
|
pub fn clientSide(conn: *Connection, name: []const u8) void {
|
||||||
const jsonObject = JsonElement.initObject(main.globalAllocator);
|
const jsonObject = JsonElement.initObject(main.stackAllocator);
|
||||||
defer jsonObject.free(main.globalAllocator);
|
defer jsonObject.free(main.stackAllocator);
|
||||||
jsonObject.putOwnedString("version", settings.version);
|
jsonObject.putOwnedString("version", settings.version);
|
||||||
jsonObject.putOwnedString("name", name);
|
jsonObject.putOwnedString("name", name);
|
||||||
const prefix = [1]u8 {stepUserData};
|
const prefix = [1]u8 {stepUserData};
|
||||||
@ -869,8 +869,8 @@ pub const Protocols = struct {
|
|||||||
pub const entity = struct {
|
pub const entity = struct {
|
||||||
pub const id: u8 = 8;
|
pub const id: u8 = 8;
|
||||||
fn receive(conn: *Connection, data: []const u8) !void {
|
fn receive(conn: *Connection, data: []const u8) !void {
|
||||||
const jsonArray = JsonElement.parseFromString(main.globalAllocator, data);
|
const jsonArray = JsonElement.parseFromString(main.stackAllocator, data);
|
||||||
defer jsonArray.free(main.globalAllocator);
|
defer jsonArray.free(main.stackAllocator);
|
||||||
var i: u32 = 0;
|
var i: u32 = 0;
|
||||||
while(i < jsonArray.JsonArray.items.len) : (i += 1) {
|
while(i < jsonArray.JsonArray.items.len) : (i += 1) {
|
||||||
const elem = jsonArray.JsonArray.items[i];
|
const elem = jsonArray.JsonArray.items[i];
|
||||||
@ -1065,8 +1065,8 @@ pub const Protocols = struct {
|
|||||||
// );
|
// );
|
||||||
},
|
},
|
||||||
type_itemStackCollect => {
|
type_itemStackCollect => {
|
||||||
const json = JsonElement.parseFromString(main.globalAllocator, data[1..]);
|
const json = JsonElement.parseFromString(main.stackAllocator, data[1..]);
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
const item = items.Item.init(json) catch |err| {
|
const item = items.Item.init(json) catch |err| {
|
||||||
std.log.err("Error {s} while collecting item {s}. Ignoring it.", .{@errorName(err), data[1..]});
|
std.log.err("Error {s} while collecting item {s}. Ignoring it.", .{@errorName(err), data[1..]});
|
||||||
return;
|
return;
|
||||||
@ -1083,8 +1083,8 @@ pub const Protocols = struct {
|
|||||||
},
|
},
|
||||||
type_timeAndBiome => {
|
type_timeAndBiome => {
|
||||||
if(conn.manager.world) |world| {
|
if(conn.manager.world) |world| {
|
||||||
const json = JsonElement.parseFromString(main.globalAllocator, data[1..]);
|
const json = JsonElement.parseFromString(main.stackAllocator, data[1..]);
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
const expectedTime = json.get(i64, "time", 0);
|
const expectedTime = json.get(i64, "time", 0);
|
||||||
var curTime = world.gameTime.load(.Monotonic);
|
var curTime = world.gameTime.load(.Monotonic);
|
||||||
if(@abs(curTime -% expectedTime) >= 1000) {
|
if(@abs(curTime -% expectedTime) >= 1000) {
|
||||||
@ -1155,8 +1155,8 @@ pub const Protocols = struct {
|
|||||||
|
|
||||||
|
|
||||||
pub fn sendInventory_full(conn: *Connection, inv: Inventory) void {
|
pub fn sendInventory_full(conn: *Connection, inv: Inventory) void {
|
||||||
const json = inv.save(main.globalAllocator);
|
const json = inv.save(main.stackAllocator);
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
const string = json.toString(main.stackAllocator);
|
const string = json.toString(main.stackAllocator);
|
||||||
defer main.stackAllocator.free(string);
|
defer main.stackAllocator.free(string);
|
||||||
addHeaderAndSendImportant(conn, type_inventoryFull, string);
|
addHeaderAndSendImportant(conn, type_inventoryFull, string);
|
||||||
@ -1169,8 +1169,8 @@ pub const Protocols = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn itemStackDrop(conn: *Connection, stack: ItemStack, pos: Vec3d, dir: Vec3f, vel: f32) void {
|
pub fn itemStackDrop(conn: *Connection, stack: ItemStack, pos: Vec3d, dir: Vec3f, vel: f32) void {
|
||||||
const jsonObject = stack.store(main.globalAllocator);
|
const jsonObject = stack.store(main.stackAllocator);
|
||||||
defer jsonObject.free(main.globalAllocator);
|
defer jsonObject.free(main.stackAllocator);
|
||||||
jsonObject.put("x", pos[0]);
|
jsonObject.put("x", pos[0]);
|
||||||
jsonObject.put("y", pos[1]);
|
jsonObject.put("y", pos[1]);
|
||||||
jsonObject.put("z", pos[2]);
|
jsonObject.put("z", pos[2]);
|
||||||
@ -1184,16 +1184,16 @@ pub const Protocols = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn itemStackCollect(conn: *Connection, stack: ItemStack) void {
|
pub fn itemStackCollect(conn: *Connection, stack: ItemStack) void {
|
||||||
const json = stack.store(main.globalAllocator);
|
const json = stack.store(main.stackAllocator);
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
const string = json.toString(main.stackAllocator);
|
const string = json.toString(main.stackAllocator);
|
||||||
defer main.stackAllocator.free(string);
|
defer main.stackAllocator.free(string);
|
||||||
addHeaderAndSendImportant(conn, type_itemStackCollect, string);
|
addHeaderAndSendImportant(conn, type_itemStackCollect, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sendTimeAndBiome(conn: *Connection, world: *const main.server.ServerWorld) void {
|
pub fn sendTimeAndBiome(conn: *Connection, world: *const main.server.ServerWorld) void {
|
||||||
const json = JsonElement.initObject(main.globalAllocator);
|
const json = JsonElement.initObject(main.stackAllocator);
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
json.put("time", world.gameTime);
|
json.put("time", world.gameTime);
|
||||||
const pos = conn.user.?.player.pos;
|
const pos = conn.user.?.player.pos;
|
||||||
json.put("biome", (world.getBiome(@intFromFloat(pos[0]), @intFromFloat(pos[1]), @intFromFloat(pos[2]))).id);
|
json.put("biome", (world.getBiome(@intFromFloat(pos[0]), @intFromFloat(pos[1]), @intFromFloat(pos[2]))).id);
|
||||||
@ -1483,9 +1483,9 @@ pub const Connection = struct {
|
|||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
|
|
||||||
var runLengthEncodingStarts: main.List(u32) = main.List(u32).init(main.globalAllocator);
|
var runLengthEncodingStarts: main.List(u32) = main.List(u32).init(main.stackAllocator);
|
||||||
defer runLengthEncodingStarts.deinit();
|
defer runLengthEncodingStarts.deinit();
|
||||||
var runLengthEncodingLengths: main.List(u32) = main.List(u32).init(main.globalAllocator);
|
var runLengthEncodingLengths: main.List(u32) = main.List(u32).init(main.stackAllocator);
|
||||||
defer runLengthEncodingLengths.deinit();
|
defer runLengthEncodingLengths.deinit();
|
||||||
|
|
||||||
for(self.receivedPackets) |list| {
|
for(self.receivedPackets) |list| {
|
||||||
|
@ -486,19 +486,19 @@ pub const MenuBackGround = struct {
|
|||||||
var dir = try std.fs.cwd().makeOpenPath("assets/backgrounds", .{.iterate = true});
|
var dir = try std.fs.cwd().makeOpenPath("assets/backgrounds", .{.iterate = true});
|
||||||
defer dir.close();
|
defer dir.close();
|
||||||
|
|
||||||
var walker = try dir.walk(main.globalAllocator.allocator);
|
var walker = try dir.walk(main.stackAllocator.allocator);
|
||||||
defer walker.deinit();
|
defer walker.deinit();
|
||||||
var fileList = main.List([]const u8).init(main.globalAllocator);
|
var fileList = main.List([]const u8).init(main.stackAllocator);
|
||||||
defer {
|
defer {
|
||||||
for(fileList.items) |fileName| {
|
for(fileList.items) |fileName| {
|
||||||
main.globalAllocator.free(fileName);
|
main.stackAllocator.free(fileName);
|
||||||
}
|
}
|
||||||
fileList.deinit();
|
fileList.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
while(try walker.next()) |entry| {
|
while(try walker.next()) |entry| {
|
||||||
if(entry.kind == .file and std.ascii.endsWithIgnoreCase(entry.basename, ".png")) {
|
if(entry.kind == .file and std.ascii.endsWithIgnoreCase(entry.basename, ".png")) {
|
||||||
fileList.append(main.globalAllocator.dupe(u8, entry.path));
|
fileList.append(main.stackAllocator.dupe(u8, entry.path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(fileList.items.len == 0) {
|
if(fileList.items.len == 0) {
|
||||||
|
@ -574,7 +574,7 @@ pub const ChunkMesh = struct {
|
|||||||
|
|
||||||
fn initLight(self: *ChunkMesh) void {
|
fn initLight(self: *ChunkMesh) void {
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
var lightEmittingBlocks = main.List([3]u8).init(main.globalAllocator);
|
var lightEmittingBlocks = main.List([3]u8).init(main.stackAllocator);
|
||||||
defer lightEmittingBlocks.deinit();
|
defer lightEmittingBlocks.deinit();
|
||||||
var x: u8 = 0;
|
var x: u8 = 0;
|
||||||
while(x < chunk.chunkSize): (x += 1) {
|
while(x < chunk.chunkSize): (x += 1) {
|
||||||
|
@ -88,7 +88,7 @@ pub const ChannelChunk = struct {
|
|||||||
var neighborLists: [6]main.ListUnmanaged(Entry) = .{.{}} ** 6;
|
var neighborLists: [6]main.ListUnmanaged(Entry) = .{.{}} ** 6;
|
||||||
defer {
|
defer {
|
||||||
for(&neighborLists) |*list| {
|
for(&neighborLists) |*list| {
|
||||||
list.deinit(lightQueue.allocator);
|
list.deinit(main.stackAllocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ pub const ChannelChunk = struct {
|
|||||||
}
|
}
|
||||||
if(result.value == 0) continue;
|
if(result.value == 0) continue;
|
||||||
if(nx < 0 or nx >= chunk.chunkSize or ny < 0 or ny >= chunk.chunkSize or nz < 0 or nz >= chunk.chunkSize) {
|
if(nx < 0 or nx >= chunk.chunkSize or ny < 0 or ny >= chunk.chunkSize or nz < 0 or nz >= chunk.chunkSize) {
|
||||||
neighborLists[neighbor].append(lightQueue.allocator, result);
|
neighborLists[neighbor].append(main.stackAllocator, result);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const neighborIndex = chunk.getIndex(nx, ny, nz);
|
const neighborIndex = chunk.getIndex(nx, ny, nz);
|
||||||
@ -136,7 +136,7 @@ pub const ChannelChunk = struct {
|
|||||||
var constructiveList: main.ListUnmanaged(PositionEntry) = .{};
|
var constructiveList: main.ListUnmanaged(PositionEntry) = .{};
|
||||||
defer {
|
defer {
|
||||||
for(&neighborLists) |*list| {
|
for(&neighborLists) |*list| {
|
||||||
list.deinit(lightQueue.allocator);
|
list.deinit(main.stackAllocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var isFirstIteration: bool = isFirstBlock;
|
var isFirstIteration: bool = isFirstBlock;
|
||||||
@ -146,7 +146,7 @@ pub const ChannelChunk = struct {
|
|||||||
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
||||||
if(entry.value != self.data[index].load(.Unordered)) {
|
if(entry.value != self.data[index].load(.Unordered)) {
|
||||||
if(self.data[index].load(.Unordered) != 0) {
|
if(self.data[index].load(.Unordered) != 0) {
|
||||||
constructiveList.append(lightQueue.allocator, .{.x = entry.x, .y = entry.y, .z = entry.z});
|
constructiveList.append(main.stackAllocator, .{.x = entry.x, .y = entry.y, .z = entry.z});
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -163,7 +163,7 @@ pub const ChannelChunk = struct {
|
|||||||
result.value -|= 8*|@as(u8, @intCast(self.ch.pos.voxelSize));
|
result.value -|= 8*|@as(u8, @intCast(self.ch.pos.voxelSize));
|
||||||
}
|
}
|
||||||
if(nx < 0 or nx >= chunk.chunkSize or ny < 0 or ny >= chunk.chunkSize or nz < 0 or nz >= chunk.chunkSize) {
|
if(nx < 0 or nx >= chunk.chunkSize or ny < 0 or ny >= chunk.chunkSize or nz < 0 or nz >= chunk.chunkSize) {
|
||||||
neighborLists[neighbor].append(lightQueue.allocator, result);
|
neighborLists[neighbor].append(main.stackAllocator, result);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const neighborIndex = chunk.getIndex(nx, ny, nz);
|
const neighborIndex = chunk.getIndex(nx, ny, nz);
|
||||||
@ -181,7 +181,7 @@ pub const ChannelChunk = struct {
|
|||||||
for(0..6) |neighbor| {
|
for(0..6) |neighbor| {
|
||||||
if(neighborLists[neighbor].items.len == 0) continue;
|
if(neighborLists[neighbor].items.len == 0) continue;
|
||||||
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
||||||
constructiveEntries.append(lightQueue.allocator, .{
|
constructiveEntries.append(main.stackAllocator, .{
|
||||||
.mesh = neighborMesh,
|
.mesh = neighborMesh,
|
||||||
.entries = neighborMesh.lightingData[@intFromEnum(self.channel)].propagateDestructiveFromNeighbor(lightQueue, neighborLists[neighbor].items, constructiveEntries),
|
.entries = neighborMesh.lightingData[@intFromEnum(self.channel)].propagateDestructiveFromNeighbor(lightQueue, neighborLists[neighbor].items, constructiveEntries),
|
||||||
});
|
});
|
||||||
@ -217,12 +217,7 @@ pub const ChannelChunk = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn propagateLights(self: *ChannelChunk, lights: []const [3]u8, comptime checkNeighbors: bool) void {
|
pub fn propagateLights(self: *ChannelChunk, lights: []const [3]u8, comptime checkNeighbors: bool) void {
|
||||||
const buf = main.stackAllocator.alloc(u8, 1 << 16);
|
var lightQueue = main.utils.CircularBufferQueue(Entry).init(main.stackAllocator, 1 << 12);
|
||||||
defer main.stackAllocator.free(buf);
|
|
||||||
var bufferFallback = main.utils.BufferFallbackAllocator.init(buf, main.globalAllocator);
|
|
||||||
var arena = main.utils.NeverFailingArenaAllocator.init(bufferFallback.allocator());
|
|
||||||
defer arena.deinit();
|
|
||||||
var lightQueue = main.utils.CircularBufferQueue(Entry).init(arena.allocator(), 1 << 10);
|
|
||||||
defer lightQueue.deinit();
|
defer lightQueue.deinit();
|
||||||
for(lights) |pos| {
|
for(lights) |pos| {
|
||||||
const index = chunk.getIndex(pos[0], pos[1], pos[2]);
|
const index = chunk.getIndex(pos[0], pos[1], pos[2]);
|
||||||
@ -280,20 +275,15 @@ pub const ChannelChunk = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn propagateLightsDestructive(self: *ChannelChunk, lights: []const [3]u8) void {
|
pub fn propagateLightsDestructive(self: *ChannelChunk, lights: []const [3]u8) void {
|
||||||
const buf = main.stackAllocator.alloc(u8, 1 << 16);
|
var lightQueue = main.utils.CircularBufferQueue(Entry).init(main.stackAllocator, 1 << 12);
|
||||||
defer main.stackAllocator.free(buf);
|
|
||||||
var bufferFallback = main.utils.BufferFallbackAllocator.init(buf, main.globalAllocator);
|
|
||||||
var arena = main.utils.NeverFailingArenaAllocator.init(bufferFallback.allocator());
|
|
||||||
defer arena.deinit();
|
|
||||||
var lightQueue = main.utils.CircularBufferQueue(Entry).init(arena.allocator(), 1 << 10);
|
|
||||||
defer lightQueue.deinit();
|
defer lightQueue.deinit();
|
||||||
for(lights) |pos| {
|
for(lights) |pos| {
|
||||||
const index = chunk.getIndex(pos[0], pos[1], pos[2]);
|
const index = chunk.getIndex(pos[0], pos[1], pos[2]);
|
||||||
lightQueue.enqueue(.{.x = @intCast(pos[0]), .y = @intCast(pos[1]), .z = @intCast(pos[2]), .value = self.data[index].load(.Unordered), .sourceDir = 6});
|
lightQueue.enqueue(.{.x = @intCast(pos[0]), .y = @intCast(pos[1]), .z = @intCast(pos[2]), .value = self.data[index].load(.Unordered), .sourceDir = 6});
|
||||||
}
|
}
|
||||||
var constructiveEntries: main.ListUnmanaged(ChunkEntries) = .{};
|
var constructiveEntries: main.ListUnmanaged(ChunkEntries) = .{};
|
||||||
defer constructiveEntries.deinit(arena.allocator());
|
defer constructiveEntries.deinit(main.stackAllocator);
|
||||||
constructiveEntries.append(arena.allocator(), .{
|
constructiveEntries.append(main.stackAllocator, .{
|
||||||
.mesh = null,
|
.mesh = null,
|
||||||
.entries = self.propagateDestructive(&lightQueue, &constructiveEntries, true),
|
.entries = self.propagateDestructive(&lightQueue, &constructiveEntries, true),
|
||||||
});
|
});
|
||||||
@ -301,7 +291,7 @@ pub const ChannelChunk = struct {
|
|||||||
const mesh = entries.mesh;
|
const mesh = entries.mesh;
|
||||||
defer if(mesh) |_mesh| _mesh.decreaseRefCount();
|
defer if(mesh) |_mesh| _mesh.decreaseRefCount();
|
||||||
var entryList = entries.entries;
|
var entryList = entries.entries;
|
||||||
defer entryList.deinit(arena.allocator());
|
defer entryList.deinit(main.stackAllocator);
|
||||||
const channelChunk = if(mesh) |_mesh| _mesh.lightingData[@intFromEnum(self.channel)] else self;
|
const channelChunk = if(mesh) |_mesh| _mesh.lightingData[@intFromEnum(self.channel)] else self;
|
||||||
for(entryList.items) |entry| {
|
for(entryList.items) |entry| {
|
||||||
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
||||||
|
@ -531,9 +531,9 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V
|
|||||||
network.Protocols.genericUpdate.sendRenderDistance(conn, renderDistance);
|
network.Protocols.genericUpdate.sendRenderDistance(conn, renderDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
var meshRequests = main.List(chunk.ChunkPosition).init(main.globalAllocator);
|
var meshRequests = main.List(chunk.ChunkPosition).init(main.stackAllocator);
|
||||||
defer meshRequests.deinit();
|
defer meshRequests.deinit();
|
||||||
var mapRequests = main.List(LightMap.MapFragmentPosition).init(main.globalAllocator);
|
var mapRequests = main.List(LightMap.MapFragmentPosition).init(main.stackAllocator);
|
||||||
defer mapRequests.deinit();
|
defer mapRequests.deinit();
|
||||||
|
|
||||||
const olderPx = lastPx;
|
const olderPx = lastPx;
|
||||||
@ -568,7 +568,7 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Is there a way to combine this with minecraft's approach?
|
// TODO: Is there a way to combine this with minecraft's approach?
|
||||||
var searchList = std.PriorityQueue(OcclusionData, void, OcclusionData.compare).init(main.globalAllocator.allocator, {});
|
var searchList = std.PriorityQueue(OcclusionData, void, OcclusionData.compare).init(main.stackAllocator.allocator, {});
|
||||||
defer searchList.deinit();
|
defer searchList.deinit();
|
||||||
{
|
{
|
||||||
var firstPos = chunk.ChunkPosition{
|
var firstPos = chunk.ChunkPosition{
|
||||||
@ -601,7 +601,7 @@ pub noinline fn updateAndGetRenderChunks(conn: *network.Connection, playerPos: V
|
|||||||
firstPos.voxelSize *= 2;
|
firstPos.voxelSize *= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var nodeList = main.List(*ChunkMeshNode).init(main.globalAllocator);
|
var nodeList = main.List(*ChunkMeshNode).init(main.stackAllocator);
|
||||||
defer nodeList.deinit();
|
defer nodeList.deinit();
|
||||||
const projRotMat = game.projectionMatrix.mul(game.camera.viewMatrix);
|
const projRotMat = game.projectionMatrix.mul(game.camera.viewMatrix);
|
||||||
while(searchList.removeOrNull()) |data| {
|
while(searchList.removeOrNull()) |data| {
|
||||||
|
@ -146,10 +146,10 @@ pub const Biome = struct {
|
|||||||
|
|
||||||
const structures = json.getChild("structures");
|
const structures = json.getChild("structures");
|
||||||
var vegetation = main.ListUnmanaged(StructureModel){};
|
var vegetation = main.ListUnmanaged(StructureModel){};
|
||||||
defer vegetation.deinit(main.globalAllocator);
|
defer vegetation.deinit(main.stackAllocator);
|
||||||
for(structures.toSlice()) |elem| {
|
for(structures.toSlice()) |elem| {
|
||||||
if(StructureModel.initModel(elem)) |model| {
|
if(StructureModel.initModel(elem)) |model| {
|
||||||
vegetation.append(main.globalAllocator, model);
|
vegetation.append(main.stackAllocator, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.vegetationModels = main.globalAllocator.dupe(StructureModel, vegetation.items);
|
self.vegetationModels = main.globalAllocator.dupe(StructureModel, vegetation.items);
|
||||||
|
@ -30,7 +30,7 @@ pub fn deinit() void {
|
|||||||
pub fn generateMapFragment(map: *ClimateMapFragment, worldSeed: u64) void {
|
pub fn generateMapFragment(map: *ClimateMapFragment, worldSeed: u64) void {
|
||||||
var seed: u64 = worldSeed;
|
var seed: u64 = worldSeed;
|
||||||
|
|
||||||
const generator = GenerationStructure.init(main.globalAllocator, map.pos.wx, map.pos.wz, ClimateMapFragment.mapSize, ClimateMapFragment.mapSize, terrain.biomes.byTypeBiomes, seed);
|
const generator = GenerationStructure.init(main.stackAllocator, map.pos.wx, map.pos.wz, ClimateMapFragment.mapSize, ClimateMapFragment.mapSize, terrain.biomes.byTypeBiomes, seed);
|
||||||
defer generator.deinit(main.stackAllocator);
|
defer generator.deinit(main.stackAllocator);
|
||||||
|
|
||||||
generator.toMap(map, ClimateMapFragment.mapSize, ClimateMapFragment.mapSize, worldSeed);
|
generator.toMap(map, ClimateMapFragment.mapSize, ClimateMapFragment.mapSize, worldSeed);
|
||||||
@ -327,7 +327,7 @@ const GenerationStructure = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add some sub-biomes:
|
// Add some sub-biomes:
|
||||||
var extraBiomes = main.List(BiomePoint).init(main.globalAllocator);
|
var extraBiomes = main.List(BiomePoint).init(main.stackAllocator);
|
||||||
defer extraBiomes.deinit();
|
defer extraBiomes.deinit();
|
||||||
for(self.chunks.mem) |chunk| {
|
for(self.chunks.mem) |chunk| {
|
||||||
for(chunk.biomesSortedByX) |biome| {
|
for(chunk.biomesSortedByX) |biome| {
|
||||||
|
@ -269,8 +269,8 @@ const WorldIO = struct {
|
|||||||
|
|
||||||
/// Load the seed, which is needed before custom item and ore generation.
|
/// Load the seed, which is needed before custom item and ore generation.
|
||||||
pub fn loadWorldSeed(self: WorldIO) !u64 {
|
pub fn loadWorldSeed(self: WorldIO) !u64 {
|
||||||
const worldData: JsonElement = try self.dir.readToJson(main.globalAllocator, "world.dat");
|
const worldData: JsonElement = try self.dir.readToJson(main.stackAllocator, "world.dat");
|
||||||
defer worldData.free(main.globalAllocator);
|
defer worldData.free(main.stackAllocator);
|
||||||
if(worldData.get(u32, "version", 0) != worldDataVersion) {
|
if(worldData.get(u32, "version", 0) != worldDataVersion) {
|
||||||
std.log.err("Cannot read world file version {}. Expected version {}.", .{worldData.get(u32, "version", 0), worldDataVersion});
|
std.log.err("Cannot read world file version {}. Expected version {}.", .{worldData.get(u32, "version", 0), worldDataVersion});
|
||||||
return error.OldWorld;
|
return error.OldWorld;
|
||||||
@ -279,8 +279,8 @@ const WorldIO = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn loadWorldData(self: WorldIO) !void {
|
pub fn loadWorldData(self: WorldIO) !void {
|
||||||
const worldData: JsonElement = try self.dir.readToJson(main.globalAllocator, "world.dat");
|
const worldData: JsonElement = try self.dir.readToJson(main.stackAllocator, "world.dat");
|
||||||
defer worldData.free(main.globalAllocator);
|
defer worldData.free(main.stackAllocator);
|
||||||
|
|
||||||
const entityJson = worldData.getChild("entities");
|
const entityJson = worldData.getChild("entities");
|
||||||
_ = entityJson;
|
_ = entityJson;
|
||||||
@ -300,15 +300,15 @@ const WorldIO = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn saveWorldData(self: WorldIO) !void {
|
pub fn saveWorldData(self: WorldIO) !void {
|
||||||
const worldData: JsonElement = JsonElement.initObject(main.globalAllocator);
|
const worldData: JsonElement = JsonElement.initObject(main.stackAllocator);
|
||||||
defer worldData.free(main.globalAllocator);
|
defer worldData.free(main.stackAllocator);
|
||||||
worldData.put("version", worldDataVersion);
|
worldData.put("version", worldDataVersion);
|
||||||
worldData.put("seed", self.world.seed);
|
worldData.put("seed", self.world.seed);
|
||||||
worldData.put("doGameTimeCycle", self.world.doGameTimeCycle);
|
worldData.put("doGameTimeCycle", self.world.doGameTimeCycle);
|
||||||
worldData.put("gameTime", self.world.gameTime);
|
worldData.put("gameTime", self.world.gameTime);
|
||||||
// TODO:
|
// TODO:
|
||||||
// worldData.put("entityCount", world.getEntities().length);
|
// worldData.put("entityCount", world.getEntities().length);
|
||||||
const spawnData = JsonElement.initObject(main.globalAllocator);
|
const spawnData = JsonElement.initObject(main.stackAllocator);
|
||||||
spawnData.put("x", self.world.spawn[0]);
|
spawnData.put("x", self.world.spawn[0]);
|
||||||
spawnData.put("y", self.world.spawn[1]);
|
spawnData.put("y", self.world.spawn[1]);
|
||||||
spawnData.put("z", self.world.spawn[2]);
|
spawnData.put("z", self.world.spawn[2]);
|
||||||
@ -366,7 +366,7 @@ pub const ServerWorld = struct {
|
|||||||
self.itemDropManager.init(main.globalAllocator, self, self.gravity);
|
self.itemDropManager.init(main.globalAllocator, self, self.gravity);
|
||||||
errdefer self.itemDropManager.deinit();
|
errdefer self.itemDropManager.deinit();
|
||||||
|
|
||||||
var loadArena = main.utils.NeverFailingArenaAllocator.init(main.globalAllocator);
|
var loadArena = main.utils.NeverFailingArenaAllocator.init(main.stackAllocator);
|
||||||
defer loadArena.deinit();
|
defer loadArena.deinit();
|
||||||
const arenaAllocator = loadArena.allocator();
|
const arenaAllocator = loadArena.allocator();
|
||||||
var buf: [32768]u8 = undefined;
|
var buf: [32768]u8 = undefined;
|
||||||
@ -438,8 +438,8 @@ pub const ServerWorld = struct {
|
|||||||
|
|
||||||
pub fn findPlayer(self: *ServerWorld, user: *User) void {
|
pub fn findPlayer(self: *ServerWorld, user: *User) void {
|
||||||
var buf: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
const playerData = files.readToJson(main.globalAllocator, std.fmt.bufPrint(&buf, "saves/{s}/player/{s}.json", .{self.name, user.name}) catch "") catch .JsonNull; // TODO: Utils.escapeFolderName(user.name)
|
const playerData = files.readToJson(main.stackAllocator, std.fmt.bufPrint(&buf, "saves/{s}/player/{s}.json", .{self.name, user.name}) catch "") catch .JsonNull; // TODO: Utils.escapeFolderName(user.name)
|
||||||
defer playerData.free(main.globalAllocator);
|
defer playerData.free(main.stackAllocator);
|
||||||
const player = &user.player;
|
const player = &user.player;
|
||||||
if(playerData == .JsonNull) {
|
if(playerData == .JsonNull) {
|
||||||
// Generate a new player:
|
// Generate a new player:
|
||||||
@ -473,8 +473,8 @@ pub const ServerWorld = struct {
|
|||||||
// savePlayers();
|
// savePlayers();
|
||||||
// chunkManager.forceSave();
|
// chunkManager.forceSave();
|
||||||
// ChunkIO.save();
|
// ChunkIO.save();
|
||||||
const itemDropJson = self.itemDropManager.store(main.globalAllocator);
|
const itemDropJson = self.itemDropManager.store(main.stackAllocator);
|
||||||
defer itemDropJson.free(main.globalAllocator);
|
defer itemDropJson.free(main.stackAllocator);
|
||||||
var buf: [32768]u8 = undefined;
|
var buf: [32768]u8 = undefined;
|
||||||
try files.writeJson(try std.fmt.bufPrint(&buf, "saves/{s}/items.json", .{self.name}), itemDropJson);
|
try files.writeJson(try std.fmt.bufPrint(&buf, "saves/{s}/items.json", .{self.name}), itemDropJson);
|
||||||
}
|
}
|
||||||
|
@ -41,13 +41,13 @@ pub var developerAutoEnterWorld: []const u8 = "";
|
|||||||
|
|
||||||
|
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
const json: JsonElement = main.files.readToJson(main.globalAllocator, "settings.json") catch |err| {
|
const json: JsonElement = main.files.readToJson(main.stackAllocator, "settings.json") catch |err| {
|
||||||
if(err != error.FileNotFound) {
|
if(err != error.FileNotFound) {
|
||||||
std.log.err("Could not read settings file: {s}", .{@errorName(err)});
|
std.log.err("Could not read settings file: {s}", .{@errorName(err)});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
defer json.free(main.globalAllocator);
|
defer json.free(main.stackAllocator);
|
||||||
|
|
||||||
inline for(@typeInfo(@This()).Struct.decls) |decl| {
|
inline for(@typeInfo(@This()).Struct.decls) |decl| {
|
||||||
const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).Pointer.is_const; // Sadly there is no direct way to check if a declaration is const.
|
const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).Pointer.is_const; // Sadly there is no direct way to check if a declaration is const.
|
||||||
@ -78,8 +78,8 @@ pub fn init() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
const jsonObject = JsonElement.initObject(main.globalAllocator);
|
const jsonObject = JsonElement.initObject(main.stackAllocator);
|
||||||
defer jsonObject.free(main.globalAllocator);
|
defer jsonObject.free(main.stackAllocator);
|
||||||
|
|
||||||
inline for(@typeInfo(@This()).Struct.decls) |decl| {
|
inline for(@typeInfo(@This()).Struct.decls) |decl| {
|
||||||
const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).Pointer.is_const; // Sadly there is no direct way to check if a declaration is const.
|
const is_const = @typeInfo(@TypeOf(&@field(@This(), decl.name))).Pointer.is_const; // Sadly there is no direct way to check if a declaration is const.
|
||||||
@ -104,9 +104,9 @@ pub fn deinit() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// keyboard settings:
|
// keyboard settings:
|
||||||
const keyboard = JsonElement.initObject(main.globalAllocator);
|
const keyboard = JsonElement.initObject(main.stackAllocator);
|
||||||
for(&main.KeyBoard.keys) |key| {
|
for(&main.KeyBoard.keys) |key| {
|
||||||
const keyJson = JsonElement.initObject(main.globalAllocator);
|
const keyJson = JsonElement.initObject(main.stackAllocator);
|
||||||
keyJson.put("key", key.key);
|
keyJson.put("key", key.key);
|
||||||
keyJson.put("mouseButton", key.mouseButton);
|
keyJson.put("mouseButton", key.mouseButton);
|
||||||
keyJson.put("scancode", key.scancode);
|
keyJson.put("scancode", key.scancode);
|
||||||
|
@ -8,7 +8,7 @@ const main = @import("main.zig");
|
|||||||
pub const Compression = struct {
|
pub const Compression = struct {
|
||||||
pub fn deflate(allocator: NeverFailingAllocator, data: []const u8) []u8 {
|
pub fn deflate(allocator: NeverFailingAllocator, data: []const u8) []u8 {
|
||||||
var result = main.List(u8).init(allocator);
|
var result = main.List(u8).init(allocator);
|
||||||
var comp = std.compress.deflate.compressor(main.globalAllocator.allocator, result.writer(), .{.level = .default_compression}) catch unreachable;
|
var comp = std.compress.deflate.compressor(main.stackAllocator.allocator, result.writer(), .{.level = .default_compression}) catch unreachable;
|
||||||
_ = comp.write(data) catch unreachable;
|
_ = comp.write(data) catch unreachable;
|
||||||
comp.close() catch unreachable;
|
comp.close() catch unreachable;
|
||||||
comp.deinit();
|
comp.deinit();
|
||||||
@ -25,9 +25,9 @@ pub const Compression = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn pack(sourceDir: std.fs.Dir, writer: anytype) !void {
|
pub fn pack(sourceDir: std.fs.Dir, writer: anytype) !void {
|
||||||
var comp = try std.compress.deflate.compressor(main.globalAllocator.allocator, writer, .{.level = .default_compression});
|
var comp = try std.compress.deflate.compressor(main.stackAllocator.allocator, writer, .{.level = .default_compression});
|
||||||
defer comp.deinit();
|
defer comp.deinit();
|
||||||
var walker = try sourceDir.walk(main.globalAllocator.allocator);
|
var walker = try sourceDir.walk(main.stackAllocator.allocator);
|
||||||
defer walker.deinit();
|
defer walker.deinit();
|
||||||
|
|
||||||
while(try walker.next()) |entry| {
|
while(try walker.next()) |entry| {
|
||||||
@ -61,7 +61,7 @@ pub const Compression = struct {
|
|||||||
|
|
||||||
pub fn unpack(outDir: std.fs.Dir, input: []const u8) !void {
|
pub fn unpack(outDir: std.fs.Dir, input: []const u8) !void {
|
||||||
var stream = std.io.fixedBufferStream(input);
|
var stream = std.io.fixedBufferStream(input);
|
||||||
var decomp = try std.compress.deflate.decompressor(main.globalAllocator.allocator, stream.reader(), null);
|
var decomp = try std.compress.deflate.decompressor(main.stackAllocator.allocator, stream.reader(), null);
|
||||||
defer decomp.deinit();
|
defer decomp.deinit();
|
||||||
const reader = decomp.reader();
|
const reader = decomp.reader();
|
||||||
const _data = try reader.readAllAlloc(main.stackAllocator.allocator, std.math.maxInt(usize));
|
const _data = try reader.readAllAlloc(main.stackAllocator.allocator, std.math.maxInt(usize));
|
||||||
@ -373,26 +373,23 @@ pub fn CircularBufferQueue(comptime T: type) type {
|
|||||||
/// Allows for stack-like allocations in a fast and safe way.
|
/// Allows for stack-like allocations in a fast and safe way.
|
||||||
/// It is safe in the sense that a regular allocator will be used when the buffer is full.
|
/// It is safe in the sense that a regular allocator will be used when the buffer is full.
|
||||||
pub const StackAllocator = struct {
|
pub const StackAllocator = struct {
|
||||||
const Allocation = struct{start: u32, len: u32};
|
const AllocationTrailer = packed struct{wasFreed: bool, previousAllocationTrailer: u31};
|
||||||
backingAllocator: NeverFailingAllocator,
|
backingAllocator: NeverFailingAllocator,
|
||||||
buffer: []align(4096) u8,
|
buffer: []align(4096) u8,
|
||||||
allocationList: main.List(Allocation),
|
|
||||||
index: usize,
|
index: usize,
|
||||||
|
|
||||||
pub fn init(backingAllocator: NeverFailingAllocator, size: u32) StackAllocator {
|
pub fn init(backingAllocator: NeverFailingAllocator, size: u31) StackAllocator {
|
||||||
return .{
|
return .{
|
||||||
.backingAllocator = backingAllocator,
|
.backingAllocator = backingAllocator,
|
||||||
.buffer = backingAllocator.alignedAlloc(u8, 4096, size),
|
.buffer = backingAllocator.alignedAlloc(u8, 4096, size),
|
||||||
.allocationList = main.List(Allocation).init(backingAllocator),
|
|
||||||
.index = 0,
|
.index = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: StackAllocator) void {
|
pub fn deinit(self: StackAllocator) void {
|
||||||
if(self.allocationList.items.len != 0) {
|
if(self.index != 0) {
|
||||||
std.log.err("Memory leak in Stack Allocator", .{});
|
std.log.err("Memory leak in Stack Allocator", .{});
|
||||||
}
|
}
|
||||||
self.allocationList.deinit();
|
|
||||||
self.backingAllocator.free(self.buffer);
|
self.backingAllocator.free(self.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,6 +420,16 @@ pub const StackAllocator = struct {
|
|||||||
return compare - bufferStart;
|
return compare - bufferStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getTrueAllocationEnd(start: usize, len: usize) usize {
|
||||||
|
const trailerStart = std.mem.alignForward(usize, start + len, @alignOf(AllocationTrailer));
|
||||||
|
return trailerStart + @sizeOf(AllocationTrailer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getTrailerBefore(self: *StackAllocator, end: usize) *AllocationTrailer {
|
||||||
|
const trailerStart = end - @sizeOf(AllocationTrailer);
|
||||||
|
return @ptrCast(@alignCast(self.buffer[trailerStart..].ptr));
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempt to allocate exactly `len` bytes aligned to `1 << ptr_align`.
|
/// Attempt to allocate exactly `len` bytes aligned to `1 << ptr_align`.
|
||||||
///
|
///
|
||||||
/// `ret_addr` is optionally provided as the first return address of the
|
/// `ret_addr` is optionally provided as the first return address of the
|
||||||
@ -430,11 +437,12 @@ pub const StackAllocator = struct {
|
|||||||
/// has been provided.
|
/// has been provided.
|
||||||
fn alloc(ctx: *anyopaque, len: usize, ptr_align: u8, ret_addr: usize) ?[*]u8 {
|
fn alloc(ctx: *anyopaque, len: usize, ptr_align: u8, ret_addr: usize) ?[*]u8 {
|
||||||
const self: *StackAllocator = @ptrCast(@alignCast(ctx));
|
const self: *StackAllocator = @ptrCast(@alignCast(ctx));
|
||||||
if(len >= self.buffer.len) return self.backingAllocator.rawAlloc(len, ptr_align, ret_addr);
|
|
||||||
const start = std.mem.alignForward(usize, self.index, @as(usize, 1) << @intCast(ptr_align));
|
const start = std.mem.alignForward(usize, self.index, @as(usize, 1) << @intCast(ptr_align));
|
||||||
if(start + len >= self.buffer.len) return self.backingAllocator.rawAlloc(len, ptr_align, ret_addr);
|
const end = getTrueAllocationEnd(start, len);
|
||||||
self.allocationList.append(.{.start = @intCast(start), .len = @intCast(len)});
|
if(end >= self.buffer.len) return self.backingAllocator.rawAlloc(len, ptr_align, ret_addr);
|
||||||
self.index = start + len;
|
const trailer = self.getTrailerBefore(end);
|
||||||
|
trailer.* = .{.wasFreed = false, .previousAllocationTrailer = @intCast(self.index)};
|
||||||
|
self.index = end;
|
||||||
return self.buffer.ptr + start;
|
return self.buffer.ptr + start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,16 +464,18 @@ pub const StackAllocator = struct {
|
|||||||
fn resize(ctx: *anyopaque, buf: []u8, buf_align: u8, new_len: usize, ret_addr: usize) bool {
|
fn resize(ctx: *anyopaque, buf: []u8, buf_align: u8, new_len: usize, ret_addr: usize) bool {
|
||||||
const self: *StackAllocator = @ptrCast(@alignCast(ctx));
|
const self: *StackAllocator = @ptrCast(@alignCast(ctx));
|
||||||
if(self.isInsideBuffer(buf)) {
|
if(self.isInsideBuffer(buf)) {
|
||||||
const top = &self.allocationList.items[self.allocationList.items.len - 1];
|
const start = self.indexInBuffer(buf);
|
||||||
std.debug.assert(top.start == self.indexInBuffer(buf)); // Can only resize the top element.
|
const end = getTrueAllocationEnd(start, buf.len);
|
||||||
std.debug.assert(top.len == buf.len);
|
if(end != self.index) return false;
|
||||||
std.debug.assert(self.index >= top.start + top.len);
|
const newEnd = getTrueAllocationEnd(start, new_len);
|
||||||
if(top.start + new_len >= self.buffer.len) {
|
if(newEnd >= self.buffer.len) return false;
|
||||||
return false;
|
|
||||||
}
|
const trailer = self.getTrailerBefore(end);
|
||||||
self.index -= top.len;
|
std.debug.assert(!trailer.wasFreed);
|
||||||
self.index += new_len;
|
const newTrailer = self.getTrailerBefore(newEnd);
|
||||||
top.len = @intCast(new_len);
|
|
||||||
|
newTrailer.* = .{.wasFreed = false, .previousAllocationTrailer = trailer.previousAllocationTrailer};
|
||||||
|
self.index = newEnd;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return self.backingAllocator.rawResize(buf, buf_align, new_len, ret_addr);
|
return self.backingAllocator.rawResize(buf, buf_align, new_len, ret_addr);
|
||||||
@ -486,11 +496,24 @@ pub const StackAllocator = struct {
|
|||||||
fn free(ctx: *anyopaque, buf: []u8, buf_align: u8, ret_addr: usize) void {
|
fn free(ctx: *anyopaque, buf: []u8, buf_align: u8, ret_addr: usize) void {
|
||||||
const self: *StackAllocator = @ptrCast(@alignCast(ctx));
|
const self: *StackAllocator = @ptrCast(@alignCast(ctx));
|
||||||
if(self.isInsideBuffer(buf)) {
|
if(self.isInsideBuffer(buf)) {
|
||||||
const top = self.allocationList.pop();
|
const start = self.indexInBuffer(buf);
|
||||||
std.debug.assert(top.start == self.indexInBuffer(buf)); // Can only free the top element.
|
const end = getTrueAllocationEnd(start, buf.len);
|
||||||
std.debug.assert(top.len == buf.len);
|
const trailer = self.getTrailerBefore(end);
|
||||||
std.debug.assert(self.index >= top.start + top.len);
|
std.debug.assert(!trailer.wasFreed); // Double Free
|
||||||
self.index = top.start;
|
|
||||||
|
if(end == self.index) {
|
||||||
|
self.index = trailer.previousAllocationTrailer;
|
||||||
|
if(self.index != 0) {
|
||||||
|
var previousTrailer = self.getTrailerBefore(trailer.previousAllocationTrailer);
|
||||||
|
while(previousTrailer.wasFreed) {
|
||||||
|
self.index = previousTrailer.previousAllocationTrailer;
|
||||||
|
if(self.index == 0) break;
|
||||||
|
previousTrailer = self.getTrailerBefore(previousTrailer.previousAllocationTrailer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
trailer.wasFreed = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.backingAllocator.rawFree(buf, buf_align, ret_addr);
|
self.backingAllocator.rawFree(buf, buf_align, ret_addr);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user