Some improvements to error handling

This commit is contained in:
IntegratedQuantum 2024-01-31 15:35:15 +01:00
parent 2c33f3779d
commit 05769cc765
15 changed files with 60 additions and 71 deletions

View File

@ -30,6 +30,7 @@ pub fn readAllJsonFilesInAddons(externalAllocator: NeverFailingAllocator, addons
if(entry.kind == .file and std.ascii.endsWithIgnoreCase(entry.basename, ".json")) {
const folderName = addonName;
const id: []u8 = externalAllocator.alloc(u8, folderName.len + 1 + entry.path.len - 5);
errdefer externalAllocator.free(id);
@memcpy(id[0..folderName.len], folderName);
id[folderName.len] = ':';
for(0..entry.path.len-5) |i| {
@ -219,9 +220,8 @@ pub fn loadWorldAssets(assetFolder: []const u8, palette: *BlockPalette) !void {
json = value;
} else {
std.log.err("Missing block: {s}. Replacing it with default block.", .{id});
json = JsonElement.initObject(main.globalAllocator);
json = .{.JsonNull={}};
}
defer if(nullValue == null) json.free(main.globalAllocator);
try registerBlock(assetFolder, id, json);
block += 1;
}

View File

@ -206,7 +206,7 @@ fn moveCursorRight(self: *TextInput, mods: main.Key.Modifiers) void {
if(self.cursor.? >= self.currentString.items.len) return;
}
} else {
self.cursor.? += std.unicode.utf8ByteSequenceLength(self.currentString.items[self.cursor.?]) catch unreachable;
self.cursor.? += std.unicode.utf8ByteSequenceLength(self.currentString.items[self.cursor.?]) catch 0;
}
}
}

View File

@ -28,18 +28,16 @@ var gotIpAddress: std.atomic.Value(bool) = std.atomic.Value(bool).init(false);
var thread: ?std.Thread = null;
const width: f32 = 420;
fn flawedDiscoverIpAddress() !void {
connection = try ConnectionManager.init(12347, true); // TODO: default port
fn discoverIpAddress() void {
connection = ConnectionManager.init(12347, true) catch |err| {
std.log.err("Could not open Connection: {s}", .{@errorName(err)});
ipAddress = main.globalAllocator.dupe(u8, @errorName(err));
return;
}; // TODO: default port
ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{}", .{connection.?.externalAddress}) catch unreachable;
gotIpAddress.store(true, .Release);
}
fn discoverIpAddress() void {
flawedDiscoverIpAddress() catch |err| {
std.log.err("Encountered error {s} while discovering the ip address for multiplayer.", .{@errorName(err)});
};
}
fn discoverIpAddressFromNewThread() void {
var sta = main.utils.StackAllocator.init(main.globalAllocator, 1 << 23);
defer sta.deinit();

View File

@ -25,7 +25,7 @@ const width: f32 = 128;
var buttonNameArena: main.utils.NeverFailingArenaAllocator = undefined;
pub fn openWorld(name: []const u8) void {
std.log.info("TODO: Open world {s}", .{name});
std.log.info("Opening world {s}", .{name});
main.server.thread = std.Thread.spawn(.{}, main.server.start, .{name}) catch |err| {
std.log.err("Encountered error while starting server thread: {s}", .{@errorName(err)});
return;
@ -44,14 +44,6 @@ pub fn openWorld(name: []const u8) void {
gui.closeWindow(openWindow);
}
gui.openHud();
// while(Server.world == null) {
// try {
// Thread.sleep(10);
// } catch(InterruptedException e) {}
// }
// try {
// GameLauncher.logic.loadWorld(new ClientWorld("127.0.0.1", new UDPConnectionManager(Constants.DEFAULT_PORT+1, false))); // TODO: Don't go over the local network in singleplayer.
// } catch(InterruptedException e) {}
}
fn openWorldWrap(namePtr: usize) void { // TODO: Improve this situation. Maybe it makes sense to always use 2 arguments in the Callback.
@ -109,29 +101,33 @@ pub fn onOpen() void {
const list = VerticalList.init(.{padding, 16 + padding}, 300, 8);
// TODO: list.add(Button.initText(.{0, 0}, 128, "Create World", gui.openWindowCallback("save_creation")));
var dir = std.fs.cwd().makeOpenPath("saves", .{.iterate = true}) catch |err| {
std.log.err("Encountered error while trying to open folder \"saves\": {s}", .{@errorName(err)});
return;
};
defer dir.close();
readingSaves: {
var dir = std.fs.cwd().makeOpenPath("saves", .{.iterate = true}) catch |err| {
list.add(Label.init(.{0, 0}, 128, "Encountered error while trying to open saves folder:", .center));
list.add(Label.init(.{0, 0}, 128, @errorName(err), .center));
break :readingSaves;
};
defer dir.close();
var iterator = dir.iterate();
while(iterator.next() catch |err| {
std.log.err("Encountered error while iterating over folder \"saves\": {s}", .{@errorName(err)});
return;
}) |entry| {
if(entry.kind == .directory) {
const row = HorizontalList.init();
var iterator = dir.iterate();
while(iterator.next() catch |err| {
list.add(Label.init(.{0, 0}, 128, "Encountered error while iterating over saves folder:", .center));
list.add(Label.init(.{0, 0}, 128, @errorName(err), .center));
break :readingSaves;
}) |entry| {
if(entry.kind == .directory) {
const row = HorizontalList.init();
const decodedName = parseEscapedFolderName(main.stackAllocator, entry.name);
defer main.stackAllocator.free(decodedName);
const name = buttonNameArena.allocator().dupeZ(u8, entry.name); // Null terminate, so we can later recover the string from just the pointer.
const buttonName = std.fmt.allocPrint(buttonNameArena.allocator().allocator, "Play {s}", .{decodedName}) catch unreachable;
row.add(Button.initText(.{0, 0}, 128, buttonName, .{.callback = &openWorldWrap, .arg = @intFromPtr(name.ptr)}));
row.add(Button.initText(.{8, 0}, 64, "delete", .{.callback = &deleteWorld, .arg = @intFromPtr(name.ptr)}));
row.finish(.{0, 0}, .center);
list.add(row);
const decodedName = parseEscapedFolderName(main.stackAllocator, entry.name);
defer main.stackAllocator.free(decodedName);
const name = buttonNameArena.allocator().dupeZ(u8, entry.name); // Null terminate, so we can later recover the string from just the pointer.
const buttonName = std.fmt.allocPrint(buttonNameArena.allocator().allocator, "Play {s}", .{decodedName}) catch unreachable;
row.add(Button.initText(.{0, 0}, 128, buttonName, .{.callback = &openWorldWrap, .arg = @intFromPtr(name.ptr)}));
row.add(Button.initText(.{8, 0}, 64, "delete", .{.callback = &deleteWorld, .arg = @intFromPtr(name.ptr)}));
row.finish(.{0, 0}, .center);
list.add(row);
}
}
}

View File

@ -237,13 +237,13 @@ pub const JsonElement = union(JsonType) {
list.append('\t');
}
}
fn recurseToString(json: JsonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) !void {
fn recurseToString(json: JsonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) void {
switch(json) {
.JsonInt => |value| {
try std.fmt.formatInt(value, 10, .lower, .{}, list.writer());
std.fmt.formatInt(value, 10, .lower, .{}, list.writer()) catch unreachable;
},
.JsonFloat => |value| {
try std.fmt.formatFloatScientific(value, .{}, list.writer());
std.fmt.formatFloatScientific(value, .{}, list.writer()) catch unreachable;
},
.JsonBool => |value| {
if(value) {
@ -268,7 +268,7 @@ pub const JsonElement = union(JsonType) {
}
if(visualCharacters) list.append('\n');
if(visualCharacters) writeTabs(list, tabs + 1);
try recurseToString(elem, list, tabs + 1, visualCharacters);
recurseToString(elem, list, tabs + 1, visualCharacters);
}
if(visualCharacters) list.append('\n');
if(visualCharacters) writeTabs(list, tabs);
@ -292,7 +292,7 @@ pub const JsonElement = union(JsonType) {
list.append(':');
if(visualCharacters) list.append(' ');
try recurseToString(elem.value_ptr.*, list, tabs + 1, visualCharacters);
recurseToString(elem.value_ptr.*, list, tabs + 1, visualCharacters);
first = false;
}
if(visualCharacters) list.append('\n');
@ -303,7 +303,7 @@ pub const JsonElement = union(JsonType) {
}
pub fn toString(json: JsonElement, allocator: NeverFailingAllocator) []const u8 {
var string = List(u8).init(allocator);
recurseToString(json, &string, 0, true) catch unreachable;
recurseToString(json, &string, 0, true);
return string.toOwnedSlice();
}
@ -311,7 +311,7 @@ pub const JsonElement = union(JsonType) {
pub fn toStringEfficient(json: JsonElement, allocator: NeverFailingAllocator, prefix: []const u8) []const u8 {
var string = List(u8).init(allocator);
string.appendSlice(prefix);
recurseToString(json, &string, 0, false) catch unreachable;
recurseToString(json, &string, 0, false);
return string.toOwnedSlice();
}
@ -505,10 +505,11 @@ const Parser = struct {
index.* += 1;
skipWhitespaces(chars, index);
const value: JsonElement = parseElement(allocator, chars, index);
map.putNoClobber(key, value) catch {
if(map.fetchPut(key, value) catch unreachable) |old| {
printError(chars, index.*, "Duplicate key.");
allocator.free(key);
};
allocator.free(old.key);
old.value.free(allocator);
}
skipWhitespaces(chars, index);
if(index.* < chars.len and chars[index.*] == ',') {
index.* += 1;

View File

@ -668,7 +668,7 @@ pub fn main() !void {
// init logging.
try std.fs.cwd().makePath("logs");
logFile = std.fs.cwd().createFile("logs/latest.log", .{}) catch unreachable;
logFile = try std.fs.cwd().createFile("logs/latest.log", .{});
defer logFile.close();
supportsANSIColors = std.io.getStdOut().supportsAnsiEscapeCodes();

View File

@ -288,7 +288,7 @@ const STUN = struct {
std.log.err("Cannot resolve stun server address: {s}, error: {s}", .{ip, @errorName(err)});
continue;
},
.port=std.fmt.parseUnsigned(u16, splitter.rest(), 10) catch 3478
.port=std.fmt.parseUnsigned(u16, splitter.rest(), 10) catch 3478,
};
if(connection.sendRequest(main.globalAllocator, &data, serverAddress, 500*1000000)) |answer| {
defer main.globalAllocator.free(answer);

View File

@ -482,6 +482,7 @@ pub const MenuBackGround = struct {
c.glBufferData(c.GL_ELEMENT_ARRAY_BUFFER, @intCast(indices.len*@sizeOf(c_int)), &indices, c.GL_STATIC_DRAW);
// Load a random texture from the backgrounds folder. The player may make their own pictures which can be chosen as well.
texture = .{.textureID = 0};
var dir = try std.fs.cwd().makeOpenPath("assets/backgrounds", .{.iterate = true});
defer dir.close();
@ -502,7 +503,6 @@ pub const MenuBackGround = struct {
}
if(fileList.items.len == 0) {
std.log.warn("Couldn't find any background scene images in \"assets/backgrounds\".", .{});
texture = .{.textureID = 0};
return;
}
const theChosenOne = main.random.nextIntBounded(u32, &main.seed, @as(u32, @intCast(fileList.items.len)));

View File

@ -610,7 +610,7 @@ pub const ChunkMesh = struct {
}
}
pub fn generateLightingData(self: *ChunkMesh) !void {
pub fn generateLightingData(self: *ChunkMesh) error{AlreadyStored}!void {
self.mutex.lock();
self.opaqueMesh.reset();
self.transparentMesh.reset();

View File

@ -963,7 +963,7 @@ pub fn addToUpdateListAndDecreaseRefCount(mesh: *chunk_meshing.ChunkMesh) void {
}
}
pub fn addMeshToStorage(mesh: *chunk_meshing.ChunkMesh) !void {
pub fn addMeshToStorage(mesh: *chunk_meshing.ChunkMesh) error{AlreadyStored}!void {
mutex.lock();
defer mutex.unlock();
if(isInRenderDistance(mesh.pos)) {
@ -1018,13 +1018,7 @@ pub const MeshGenerationTask = struct {
const mesh = main.globalAllocator.create(chunk_meshing.ChunkMesh);
mesh.init(pos, self.mesh);
defer mesh.decreaseRefCount();
mesh.generateLightingData() catch |err| {
switch(err) {
error.AlreadyStored => {
return;
},
}
};
mesh.generateLightingData() catch return;
}
pub fn clean(self: *MeshGenerationTask) void {

View File

@ -117,7 +117,7 @@ fn init(name: []const u8) void {
users = main.List(*User).init(main.globalAllocator);
lastTime = std.time.nanoTimestamp();
connectionManager = ConnectionManager.init(main.settings.defaultPort, false) catch |err| {
std.log.err("Couldn't create connection from port: {s}", .{@errorName(err)});
std.log.err("Couldn't create socket: {s}", .{@errorName(err)});
@panic("Could not open Server.");
}; // TODO Configure the second argument in the server settings.
// TODO: Load the assets.
@ -128,7 +128,7 @@ fn init(name: []const u8) void {
};
if(true) blk: { // singleplayer // TODO: Configure this in the server settings.
const user = User.init(connectionManager, "127.0.0.1:47650") catch |err| {
std.log.err("Cannot create user {s}", .{@errorName(err)});
std.log.err("Cannot create singleplayer user {s}", .{@errorName(err)});
break :blk;
};
user.isLocal = true;

View File

@ -204,7 +204,7 @@ pub const BlockStructure = struct {
};
for(blockStackDescriptions, self.structure) |jsonString, *blockStack| {
blockStack.init(jsonString.as([]const u8, "That's not a json string.")) catch |err| {
std.log.warn("Couldn't parse blockStack '{s}': {s} Removing it.", .{jsonString.as([]const u8, "That's not a json string."), @errorName(err)});
std.log.warn("Couldn't parse blockStack '{s}': {s} Removing it.", .{jsonString.as([]const u8, "(not a json string)"), @errorName(err)});
blockStack.* = .{};
};
}

View File

@ -42,7 +42,7 @@ pub fn generate(map: *CaveMapFragment, worldSeed: u64) void {
const outerSize = @max(map.pos.voxelSize, interpolatedPart);
const outerSizeShift = std.math.log2_int(u31, outerSize);
const outerSizeFloat: f32 = @floatFromInt(outerSize);
const noise = FractalNoise3D.generateAligned(main.stackAllocator, map.pos.wx, map.pos.wy, map.pos.wz, outerSize, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, CaveMapFragment.height*map.pos.voxelSize/outerSize + 1, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, worldSeed, scale);//try Cached3DFractalNoise.init(map.pos.wx, map.pos.wy & ~@as(i32, CaveMapFragment.width*map.pos.voxelSize - 1), map.pos.wz, outerSize, map.pos.voxelSize*CaveMapFragment.width, worldSeed, scale);
const noise = FractalNoise3D.generateAligned(main.stackAllocator, map.pos.wx, map.pos.wy, map.pos.wz, outerSize, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, CaveMapFragment.height*map.pos.voxelSize/outerSize + 1, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, worldSeed, scale);
defer noise.deinit(main.stackAllocator);
biomeMap.bulkInterpolateValue("caves", map.pos.wx, map.pos.wy, map.pos.wz, outerSize, noise, .addToMap, scale);
var x: u31 = 0;

View File

@ -39,7 +39,7 @@ pub fn samplePoint2D(x: f32, _y: f32, worldSeed: u64) f32 {
const percentileTable = [_]f32 {0.0e+00, 9.20569300e-02, 1.18748918e-01, 1.38117700e-01, 1.53936773e-01, 1.67584523e-01, 1.79740771e-01, 1.90797567e-01, 2.01004371e-01, 2.10530936e-01, 2.19498828e-01, 2.27998286e-01, 2.36098647e-01, 2.43854254e-01, 2.51308768e-01, 2.58497864e-01, 2.65450924e-01, 2.72192806e-01, 2.78744399e-01, 2.85123795e-01, 2.91346460e-01, 2.97426044e-01, 3.03374379e-01, 3.09202045e-01, 3.14918369e-01, 3.20531696e-01, 3.26049506e-01, 3.31478625e-01, 3.36825191e-01, 3.42094779e-01, 3.47292482e-01, 3.52423042e-01, 3.57490718e-01, 3.62499535e-01, 3.67453157e-01, 3.72355014e-01, 3.77208292e-01, 3.82015973e-01, 3.86780887e-01, 3.91505628e-01, 3.96192669e-01, 4.00844365e-01, 4.05462920e-01, 4.10050421e-01, 4.14608865e-01, 4.19140160e-01, 4.23646122e-01, 4.28128510e-01, 4.32588934e-01, 4.37029063e-01, 4.41450417e-01, 4.45854485e-01, 4.50242727e-01, 4.54616576e-01, 4.58977371e-01, 4.63326483e-01, 4.67665165e-01, 4.71994757e-01, 4.76316481e-01, 4.80631619e-01, 4.84941333e-01, 4.89246904e-01, 4.93549466e-01, 4.97850269e-01, 5.02150475e-01, 5.06451249e-01, 5.10753810e-01, 5.15059411e-01, 5.19369125e-01, 5.23684263e-01, 5.28005957e-01, 5.32335579e-01, 5.36674261e-01, 5.41023373e-01, 5.45384168e-01, 5.49758017e-01, 5.54146230e-01, 5.58550298e-01, 5.62971651e-01, 5.67411780e-01, 5.71872234e-01, 5.76354622e-01, 5.80860555e-01, 5.85391879e-01, 5.89950323e-01, 5.94537794e-01, 5.99156379e-01, 6.03808045e-01, 6.08495116e-01, 6.13219857e-01, 6.17984771e-01, 6.22792422e-01, 6.27645730e-01, 6.32547557e-01, 6.37501180e-01, 6.42509996e-01, 6.47577702e-01, 6.52708232e-01, 6.57905936e-01, 6.63175523e-01, 6.68522059e-01, 6.73951208e-01, 6.79469048e-01, 6.85082376e-01, 6.90798640e-01, 6.96626305e-01, 7.02574670e-01, 7.08654224e-01, 7.14876949e-01, 7.21256315e-01, 7.27807879e-01, 7.34549760e-01, 7.41502821e-01, 7.48691916e-01, 7.56146430e-01, 7.63902068e-01, 7.72002398e-01, 7.80501842e-01, 7.89469778e-01, 7.98996329e-01, 8.09203147e-01, 8.20259928e-01, 8.32416176e-01, 8.46063911e-01, 8.61882984e-01, 8.81251752e-01, 9.07943725e-01, 1.0e+00};
fn preGeneratePercentileTable() !void {
fn preGeneratePercentileTable() void {
const randomNumbers = 4096;
const positions = 4096;
const totalValues = randomNumbers*positions;
@ -66,7 +66,7 @@ fn preGeneratePercentileTable() !void {
}
var samples: u128 = 0;
for(&amount2D) |val| {
samples = try std.math.add(u128, samples, val);
samples = std.math.add(u128, samples, val) catch @panic("Number too big");
}
std.log.info("{}", .{samples});

View File

@ -463,7 +463,7 @@ pub const ServerWorld = struct {
// for(MetaChunk chunk : metaChunks.values().toArray(new MetaChunk[0])) {
// if (chunk != null) chunk.save();
// }
self.wio.saveWorldData();
try self.wio.saveWorldData();
// TODO:
// savePlayers();
// chunkManager.forceSave();
@ -471,7 +471,7 @@ pub const ServerWorld = struct {
const itemDropJson = self.itemDropManager.store(main.globalAllocator);
defer itemDropJson.free(main.globalAllocator);
var buf: [32768]u8 = undefined;
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);
}
// TODO:
// public void addEntity(Entity ent) {