Settings loading and storing (using fancy comptime reflection).

This commit is contained in:
IntegratedQuantum 2022-11-27 20:19:49 +01:00
parent 0d6303f7de
commit 3bc3fa8620
4 changed files with 122 additions and 6 deletions

View File

@ -19,6 +19,7 @@ const Mat4f = vec.Mat4f;
const graphics = @import("graphics.zig");
const Fog = graphics.Fog;
const renderer = @import("renderer.zig");
const settings = @import("settings.zig");
pub const camera = struct {
pub var rotation: Vec3f = Vec3f{0, 0, 0};
@ -99,7 +100,7 @@ pub const World = struct {
// TODO:
// super.itemEntityManager = new InterpolatedItemEntityManager(this);
// player = new ClientPlayer(this, 0);
try network.Protocols.handShake.clientSide(self.conn, "quanturmdoelvloper"); // TODO: Read name from settings.
try network.Protocols.handShake.clientSide(self.conn, settings.playerName);
}
pub fn deinit(self: *World) void {

View File

@ -146,7 +146,6 @@ pub const JsonElement = union(JsonType) {
},
.Pointer => |ptr| {
if(ptr.child == u8 and ptr.size == .Slice) {
std.log.info("String: {s}", .{value});
return JsonElement{.JsonString=value};
} else {
@compileError("Unknown value type.");
@ -163,6 +162,11 @@ pub const JsonElement = union(JsonType) {
try self.JsonObject.put(try self.JsonObject.allocator.dupe(u8, key), result);
}
pub fn putOwnedString(self: *const JsonElement, key: []const u8, value: []const u8) !void {
const result = JsonElement{.JsonStringOwned = try self.JsonObject.allocator.dupe(u8, value)};
try self.JsonObject.put(try self.JsonObject.allocator.dupe(u8, key), result);
}
pub fn free(self: *const JsonElement, allocator: Allocator) void {
switch(self.*) {
JsonType.JsonInt, JsonType.JsonFloat, JsonType.JsonBool, JsonType.JsonNull, JsonType.JsonString => return,

View File

@ -237,6 +237,9 @@ pub fn main() !void {
threadPool = try utils.ThreadPool.init(poolgpa.allocator(), 1 + ((std.Thread.getCpuCount() catch 4) -| 3));
defer threadPool.deinit();
try settings.init();
defer settings.deinit();
try Window.init();
defer Window.deinit();
@ -272,7 +275,7 @@ pub fn main() !void {
var manager = try network.ConnectionManager.init(12347, true);
defer manager.deinit();
try game.world.?.init("127.0.0.1", manager);
try game.world.?.init(settings.lastUsedIPAddress, manager);
defer game.world.?.deinit();
Window.setMouseGrabbed(true);

View File

@ -1,21 +1,129 @@
const std = @import("std");
const json = @import("json.zig");
const main = @import("main.zig");
pub const defaultPort: u16 = 47649;
pub const connectionTimeout = 60000;
pub const entityLookback: i16 = 100;
pub const version = "0.12.0";
pub const version = "Cubyz α 0.12.0";
pub const highestLOD: u5 = 5;
pub var entityDistance: i32 = 2;
pub var fov: f32 = 45;
pub var fov: f32 = 70;
pub var mouseSensitivity: f32 = 1;
pub var fogCoefficient: f32 = 15;
pub var renderDistance: i32 = 4;
pub var LODFactor: f32 = 2.0;
pub var bloom: bool = true;
pub var bloom: bool = true;
pub var playerName: []const u8 = "quanturmdoelvloper";
pub var lastUsedIPAddress: []const u8 = "localhost";
pub fn init() !void {
const jsonObject = blk: {
var file = std.fs.cwd().openFile("settings.json", .{}) catch break :blk json.JsonElement{.JsonNull={}};
defer file.close();
const fileString = try file.readToEndAlloc(main.threadAllocator, std.math.maxInt(usize));
defer main.threadAllocator.free(fileString);
break :blk json.parseFromString(main.threadAllocator, fileString);
};
defer jsonObject.free(main.threadAllocator);
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.
if(!is_const and decl.is_pub) {
const declType = @TypeOf(@field(@This(), decl.name));
if(@typeInfo(declType) == .Struct) {
@compileError("Not implemented yet.");
}
@field(@This(), decl.name) = jsonObject.get(declType, decl.name, @field(@This(), decl.name));
if(@typeInfo(declType) == .Pointer) {
if(@typeInfo(declType).Pointer.size == .Slice) {
@field(@This(), decl.name) = try main.globalAllocator.dupe(@typeInfo(declType).Pointer.child, @field(@This(), decl.name));
} else {
@compileError("Not implemented yet.");
}
}
}
}
}
pub fn deinit() void {
const jsonObject = json.JsonElement.initObject(main.threadAllocator) catch |err| {
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
return;
};
defer jsonObject.free(main.threadAllocator);
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.
if(!is_const and decl.is_pub) {
const declType = @TypeOf(@field(@This(), decl.name));
if(@typeInfo(declType) == .Struct) {
@compileError("Not implemented yet.");
}
if(declType == []const u8) {
jsonObject.putOwnedString(decl.name, @field(@This(), decl.name)) catch |err| {
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
};
} else {
jsonObject.put(decl.name, @field(@This(), decl.name)) catch |err| {
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
};
}
if(@typeInfo(declType) == .Pointer) {
if(@typeInfo(declType).Pointer.size == .Slice) {
main.globalAllocator.free(@field(@This(), decl.name));
} else {
@compileError("Not implemented yet.");
}
}
}
}
const string = jsonObject.toStringEfficient(main.threadAllocator, "") catch |err| {
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
return;
};
defer main.threadAllocator.free(string);
var file = std.fs.cwd().createFile("settings.json", .{}) catch |err| {
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
return;
};
defer file.close();
file.writeAll(string) catch |err| {
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
return;
};
}
// TODO: Check if/how these are needed:
// static Side currentSide = null;
//
// private static Language currentLanguage = null;
//
// public static int GUI_SCALE = 2;
//
// public static boolean musicOnOff = true; //Turn on or off the music
//
// /**Not actually a setting, but stored here anyways.*/
// public static int EFFECTIVE_RENDER_DISTANCE = calculatedEffectiveRenderDistance();
//
// public static int calculatedEffectiveRenderDistance() {
// return RENDER_DISTANCE + (((int)(RENDER_DISTANCE*LOD_FACTOR) & ~1) << Constants.HIGHEST_LOD);
// }