mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-02 18:57:10 -04:00
Update Zig to use the new Writergate version (#1664)
For reference: https://github.com/ziglang/zig/pull/24329 some commits have been extracted from #1583, but the x86_64 backend has been disabled due to its horrible performance. Remaining work: - [x] Wait for official builds on ziglang.org and upload them to our repository - [x] Add workaround for https://github.com/ziglang/zig/pull/24466 - [x] Fix TODO comment about ANSI support in stdout - [x] Check for compile-time performance changes → it went from 13.1 to 11.9 seconds 🎉
This commit is contained in:
parent
6811f21682
commit
aae66ea77f
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@ -14,11 +14,12 @@ jobs:
|
|||||||
name: Compilation Check
|
name: Compilation Check
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: mlugg/setup-zig@v1
|
- uses: mlugg/setup-zig@v2
|
||||||
with:
|
with:
|
||||||
version: 0.14.0
|
version: 0.15.0-dev.1034+bd97b6618
|
||||||
- run: sudo apt install libgl-dev libasound2-dev libx11-dev glslang-tools
|
- run: sudo apt install libgl-dev libasound2-dev libx11-dev glslang-tools
|
||||||
- run: wget -O /opt/hostedtoolcache/zig/0.14.0/x64/lib/std/zig/render.zig https://github.com/PixelGuys/Cubyz-std-lib/releases/download/0.14.0/render.zig
|
- run: echo "zigPath=$(command -v zig | sed 's/.\{3\}$//')" >> $GITHUB_ENV
|
||||||
|
- run: wget -O $zigPath/lib/std/zig/render.zig https://github.com/PixelGuys/Cubyz-std-lib/releases/download/0.15.0-dev.1034+bd97b6618/render.zig
|
||||||
- run: zig build
|
- run: zig build
|
||||||
- run: zig build -Dtarget=x86_64-windows-gnu
|
- run: zig build -Dtarget=x86_64-windows-gnu
|
||||||
- run: zig build test
|
- run: zig build test
|
||||||
|
@ -1 +1 @@
|
|||||||
0.14.0
|
0.15.0-dev.1034+bd97b6618
|
49
build.zig
49
build.zig
@ -52,6 +52,7 @@ fn linkLibraries(b: *std.Build, exe: *std.Build.Step.Compile, useLocalDeps: bool
|
|||||||
exe.addObjectFile(subPath.path(b, libName(b, "SPIRV-Tools-opt", t)));
|
exe.addObjectFile(subPath.path(b, libName(b, "SPIRV-Tools-opt", t)));
|
||||||
|
|
||||||
if(t.os.tag == .windows) {
|
if(t.os.tag == .windows) {
|
||||||
|
exe.linkSystemLibrary("crypt32");
|
||||||
exe.linkSystemLibrary("gdi32");
|
exe.linkSystemLibrary("gdi32");
|
||||||
exe.linkSystemLibrary("opengl32");
|
exe.linkSystemLibrary("opengl32");
|
||||||
exe.linkSystemLibrary("ws2_32");
|
exe.linkSystemLibrary("ws2_32");
|
||||||
@ -168,15 +169,19 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.install_dir = .{.custom = ".."},
|
.install_dir = .{.custom = ".."},
|
||||||
});
|
});
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
const mainModule = b.addModule("main", .{
|
||||||
.name = "Cubyzig",
|
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
//.sanitize_thread = true,
|
|
||||||
//.use_llvm = false,
|
|
||||||
});
|
});
|
||||||
exe.root_module.addImport("main", exe.root_module);
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "Cubyzig",
|
||||||
|
.root_module = mainModule,
|
||||||
|
//.sanitize_thread = true,
|
||||||
|
.use_llvm = true,
|
||||||
|
});
|
||||||
|
exe.root_module.addImport("main", mainModule);
|
||||||
try addModFeatures(b, exe);
|
try addModFeatures(b, exe);
|
||||||
|
|
||||||
linkLibraries(b, exe, useLocalDeps);
|
linkLibraries(b, exe, useLocalDeps);
|
||||||
@ -193,13 +198,11 @@ pub fn build(b: *std.Build) !void {
|
|||||||
run_step.dependOn(&run_cmd.step);
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
|
||||||
const exe_tests = b.addTest(.{
|
const exe_tests = b.addTest(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_module = mainModule,
|
||||||
.test_runner = .{.path = b.path("test/runner.zig"), .mode = .simple},
|
.test_runner = .{.path = b.path("test/runner.zig"), .mode = .simple},
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
});
|
||||||
linkLibraries(b, exe_tests, useLocalDeps);
|
linkLibraries(b, exe_tests, useLocalDeps);
|
||||||
exe_tests.root_module.addImport("main", exe_tests.root_module);
|
exe_tests.root_module.addImport("main", mainModule);
|
||||||
try addModFeatures(b, exe_tests);
|
try addModFeatures(b, exe_tests);
|
||||||
const run_exe_tests = b.addRunArtifact(exe_tests);
|
const run_exe_tests = b.addRunArtifact(exe_tests);
|
||||||
|
|
||||||
@ -210,16 +213,14 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
const formatter = b.addExecutable(.{
|
const formatter = b.addExecutable(.{
|
||||||
.name = "CubyzigFormatter",
|
.name = "CubyzigFormatter",
|
||||||
.root_source_file = b.path("src/formatter/format.zig"),
|
.root_module = b.addModule("format", .{
|
||||||
.target = target,
|
.root_source_file = b.path("src/formatter/format.zig"),
|
||||||
.optimize = optimize,
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
// ZLS is stupid and cannot detect which executable is the main one, so we add the import everywhere...
|
// ZLS is stupid and cannot detect which executable is the main one, so we add the import everywhere...
|
||||||
formatter.root_module.addAnonymousImport("main", .{
|
formatter.root_module.addImport("main", mainModule);
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.root_source_file = b.path("src/main.zig"),
|
|
||||||
});
|
|
||||||
|
|
||||||
const formatter_install = b.addInstallArtifact(formatter, .{});
|
const formatter_install = b.addInstallArtifact(formatter, .{});
|
||||||
|
|
||||||
@ -234,16 +235,14 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
const zig_fmt = b.addExecutable(.{
|
const zig_fmt = b.addExecutable(.{
|
||||||
.name = "zig_fmt",
|
.name = "zig_fmt",
|
||||||
.root_source_file = b.path("src/formatter/fmt.zig"),
|
.root_module = b.addModule("fmt", .{
|
||||||
.target = target,
|
.root_source_file = b.path("src/formatter/fmt.zig"),
|
||||||
.optimize = optimize,
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
// ZLS is stupid and cannot detect which executable is the main one, so we add the import everywhere...
|
// ZLS is stupid and cannot detect which executable is the main one, so we add the import everywhere...
|
||||||
zig_fmt.root_module.addAnonymousImport("main", .{
|
zig_fmt.root_module.addImport("main", mainModule);
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.root_source_file = b.path("src/main.zig"),
|
|
||||||
});
|
|
||||||
|
|
||||||
const zig_fmt_install = b.addInstallArtifact(zig_fmt, .{});
|
const zig_fmt_install = b.addInstallArtifact(zig_fmt, .{});
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ then
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
VERSION=zig-$OS-$ARCH-$BASE_VERSION
|
VERSION=zig-$ARCH-$OS-$BASE_VERSION
|
||||||
|
|
||||||
mkdir -p compiler/zig
|
mkdir -p compiler/zig
|
||||||
touch compiler/version.txt
|
touch compiler/version.txt
|
||||||
|
@ -14,7 +14,7 @@ IF "%arch%"=="" (
|
|||||||
set arch=x86_64
|
set arch=x86_64
|
||||||
)
|
)
|
||||||
|
|
||||||
set version=zig-windows-%arch%-%baseVersion%
|
set version=zig-%arch%-windows-%baseVersion%
|
||||||
|
|
||||||
if not exist compiler mkdir compiler
|
if not exist compiler mkdir compiler
|
||||||
if not exist compiler\version.txt copy NUL compiler\version.txt >NUL
|
if not exist compiler\version.txt copy NUL compiler\version.txt >NUL
|
||||||
|
@ -309,7 +309,7 @@ pub const Sync = struct { // MARK: Sync
|
|||||||
const typ = try reader.readEnum(Command.PayloadType);
|
const typ = try reader.readEnum(Command.PayloadType);
|
||||||
@setEvalBranchQuota(100000);
|
@setEvalBranchQuota(100000);
|
||||||
const payload: Command.Payload = switch(typ) {
|
const payload: Command.Payload = switch(typ) {
|
||||||
inline else => |_typ| @unionInit(Command.Payload, @tagName(_typ), try std.meta.FieldType(Command.Payload, _typ).deserialize(reader, .server, source)),
|
inline else => |_typ| @unionInit(Command.Payload, @tagName(_typ), try @FieldType(Command.Payload, @tagName(_typ)).deserialize(reader, .server, source)),
|
||||||
};
|
};
|
||||||
executeCommand(payload, source);
|
executeCommand(payload, source);
|
||||||
}
|
}
|
||||||
@ -2001,7 +2001,7 @@ pub fn save(self: Inventory, allocator: NeverFailingAllocator) ZonElement {
|
|||||||
for(self._items, 0..) |stack, i| {
|
for(self._items, 0..) |stack, i| {
|
||||||
if(!stack.empty()) {
|
if(!stack.empty()) {
|
||||||
var buf: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
zonObject.put(buf[0..std.fmt.formatIntBuf(&buf, i, 10, .lower, .{})], stack.store(allocator));
|
zonObject.put(buf[0..std.fmt.printInt(&buf, i, 10, .lower, .{})], stack.store(allocator));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return zonObject;
|
return zonObject;
|
||||||
@ -2011,7 +2011,7 @@ pub fn loadFromZon(self: Inventory, zon: ZonElement) void {
|
|||||||
for(self._items, 0..) |*stack, i| {
|
for(self._items, 0..) |*stack, i| {
|
||||||
stack.clear();
|
stack.clear();
|
||||||
var buf: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
const stackZon = zon.getChild(buf[0..std.fmt.formatIntBuf(&buf, i, 10, .lower, .{})]);
|
const stackZon = zon.getChild(buf[0..std.fmt.printInt(&buf, i, 10, .lower, .{})]);
|
||||||
if(stackZon == .object) {
|
if(stackZon == .object) {
|
||||||
stack.item = Item.init(stackZon) catch |err| {
|
stack.item = Item.init(stackZon) catch |err| {
|
||||||
const msg = stackZon.toStringEfficient(main.stackAllocator, "");
|
const msg = stackZon.toStringEfficient(main.stackAllocator, "");
|
||||||
|
@ -644,7 +644,7 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
break :blk null;
|
break :blk null;
|
||||||
}) |addon| {
|
}) |addon| {
|
||||||
if(addon.kind == .directory) {
|
if(addon.kind == .directory) {
|
||||||
const path = std.fmt.allocPrintZ(main.stackAllocator.allocator, "assets/{s}/blocks/textures", .{addon.name}) catch unreachable;
|
const path = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "assets/{s}/blocks/textures", .{addon.name}, 0) catch unreachable;
|
||||||
defer main.stackAllocator.free(path);
|
defer main.stackAllocator.free(path);
|
||||||
std.fs.cwd().access(path, .{}) catch continue;
|
std.fs.cwd().access(path, .{}) catch continue;
|
||||||
main.utils.file_monitor.listenToPath(path, main.blocks.meshes.reloadTextures, 0);
|
main.utils.file_monitor.listenToPath(path, main.blocks.meshes.reloadTextures, 0);
|
||||||
@ -680,7 +680,7 @@ pub fn unloadAssets() void { // MARK: unloadAssets()
|
|||||||
break :blk null;
|
break :blk null;
|
||||||
}) |addon| {
|
}) |addon| {
|
||||||
if(addon.kind == .directory) {
|
if(addon.kind == .directory) {
|
||||||
const path = std.fmt.allocPrintZ(main.stackAllocator.allocator, "assets/{s}/blocks/textures", .{addon.name}) catch unreachable;
|
const path = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "assets/{s}/blocks/textures", .{addon.name}, 0) catch unreachable;
|
||||||
defer main.stackAllocator.free(path);
|
defer main.stackAllocator.free(path);
|
||||||
std.fs.cwd().access(path, .{}) catch continue;
|
std.fs.cwd().access(path, .{}) catch continue;
|
||||||
main.utils.file_monitor.removePath(path);
|
main.utils.file_monitor.removePath(path);
|
||||||
|
@ -27,11 +27,11 @@ const AudioData = struct {
|
|||||||
};
|
};
|
||||||
const addon = id[0..colonIndex];
|
const addon = id[0..colonIndex];
|
||||||
const fileName = id[colonIndex + 1 ..];
|
const fileName = id[colonIndex + 1 ..];
|
||||||
const path1 = std.fmt.allocPrintZ(main.stackAllocator.allocator, "assets/{s}/music/{s}.ogg", .{addon, fileName}) catch unreachable;
|
const path1 = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "assets/{s}/music/{s}.ogg", .{addon, fileName}, 0) catch unreachable;
|
||||||
defer main.stackAllocator.free(path1);
|
defer main.stackAllocator.free(path1);
|
||||||
var err: c_int = 0;
|
var err: c_int = 0;
|
||||||
if(c.stb_vorbis_open_filename(path1.ptr, &err, null)) |ogg_stream| return ogg_stream;
|
if(c.stb_vorbis_open_filename(path1.ptr, &err, null)) |ogg_stream| return ogg_stream;
|
||||||
const path2 = std.fmt.allocPrintZ(main.stackAllocator.allocator, "serverAssets/{s}/music/{s}.ogg", .{addon, fileName}) catch unreachable;
|
const path2 = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "serverAssets/{s}/music/{s}.ogg", .{addon, fileName}, 0) catch unreachable;
|
||||||
defer main.stackAllocator.free(path2);
|
defer main.stackAllocator.free(path2);
|
||||||
if(c.stb_vorbis_open_filename(path2.ptr, &err, null)) |ogg_stream| return ogg_stream;
|
if(c.stb_vorbis_open_filename(path2.ptr, &err, null)) |ogg_stream| return ogg_stream;
|
||||||
std.log.err("Couldn't find music with id \"{s}\". Searched path \"{s}\" and \"{s}\"", .{id, path1, path2});
|
std.log.err("Couldn't find music with id \"{s}\". Searched path \"{s}\" and \"{s}\"", .{id, path1, path2});
|
||||||
@ -309,7 +309,7 @@ fn miniaudioCallback(
|
|||||||
output: ?*anyopaque,
|
output: ?*anyopaque,
|
||||||
input: ?*const anyopaque,
|
input: ?*const anyopaque,
|
||||||
frameCount: u32,
|
frameCount: u32,
|
||||||
) callconv(.C) void {
|
) callconv(.c) void {
|
||||||
_ = input;
|
_ = input;
|
||||||
_ = maDevice;
|
_ = maDevice;
|
||||||
const valuesPerBuffer = 2*frameCount; // Stereo
|
const valuesPerBuffer = 2*frameCount; // Stereo
|
||||||
|
@ -7,7 +7,15 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// zig fmt: off
|
// zig fmt: off
|
||||||
/// Everything below is a direct copy of fmt.zig from the zig compiler
|
/// Everything below is a direct copy of src/fmt.zig from the zig compiler
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const mem = std.mem;
|
||||||
|
const fs = std.fs;
|
||||||
|
const process = std.process;
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
const Color = std.zig.Color;
|
||||||
|
const fatal = std.process.fatal;
|
||||||
|
|
||||||
const usage_fmt =
|
const usage_fmt =
|
||||||
\\Usage: zig fmt [file]...
|
\\Usage: zig fmt [file]...
|
||||||
@ -63,7 +71,7 @@ pub fn run(
|
|||||||
const arg = args[i];
|
const arg = args[i];
|
||||||
if (mem.startsWith(u8, arg, "-")) {
|
if (mem.startsWith(u8, arg, "-")) {
|
||||||
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
|
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.fs.File.stdout().deprecatedWriter();
|
||||||
try stdout.writeAll(usage_fmt);
|
try stdout.writeAll(usage_fmt);
|
||||||
return process.cleanExit();
|
return process.cleanExit();
|
||||||
} else if (mem.eql(u8, arg, "--color")) {
|
} else if (mem.eql(u8, arg, "--color")) {
|
||||||
@ -104,7 +112,7 @@ pub fn run(
|
|||||||
fatal("cannot use --stdin with positional arguments", .{});
|
fatal("cannot use --stdin with positional arguments", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
const stdin = std.io.getStdIn();
|
const stdin: fs.File = .stdin();
|
||||||
const source_code = std.zig.readSourceFileToEndAlloc(gpa, stdin, null) catch |err| {
|
const source_code = std.zig.readSourceFileToEndAlloc(gpa, stdin, null) catch |err| {
|
||||||
fatal("unable to read stdin: {}", .{err});
|
fatal("unable to read stdin: {}", .{err});
|
||||||
};
|
};
|
||||||
@ -157,7 +165,7 @@ pub fn run(
|
|||||||
process.exit(code);
|
process.exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std.io.getStdOut().writeAll(formatted);
|
return std.fs.File.stdout().writeAll(formatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_files.items.len == 0) {
|
if (input_files.items.len == 0) {
|
||||||
@ -213,6 +221,7 @@ const FmtError = error{
|
|||||||
DestinationAddressRequired,
|
DestinationAddressRequired,
|
||||||
DiskQuota,
|
DiskQuota,
|
||||||
FileTooBig,
|
FileTooBig,
|
||||||
|
MessageTooBig,
|
||||||
InputOutput,
|
InputOutput,
|
||||||
NoSpaceLeft,
|
NoSpaceLeft,
|
||||||
AccessDenied,
|
AccessDenied,
|
||||||
@ -373,7 +382,7 @@ fn fmtPathFile(
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (check_mode) {
|
if (check_mode) {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.fs.File.stdout().deprecatedWriter();
|
||||||
try stdout.print("{s}\n", .{file_path});
|
try stdout.print("{s}\n", .{file_path});
|
||||||
fmt.any_error = true;
|
fmt.any_error = true;
|
||||||
} else {
|
} else {
|
||||||
@ -382,15 +391,7 @@ fn fmtPathFile(
|
|||||||
|
|
||||||
try af.file.writeAll(fmt.out_buffer.items);
|
try af.file.writeAll(fmt.out_buffer.items);
|
||||||
try af.finish();
|
try af.finish();
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.fs.File.stdout().deprecatedWriter();
|
||||||
try stdout.print("{s}\n", .{file_path});
|
try stdout.print("{s}\n", .{file_path});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const mem = std.mem;
|
|
||||||
const fs = std.fs;
|
|
||||||
const process = std.process;
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
const Color = std.zig.Color;
|
|
||||||
const fatal = std.process.fatal;
|
|
||||||
|
@ -1900,6 +1900,7 @@ pub fn LargeBuffer(comptime Entry: type) type { // MARK: LargerBuffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(self: *Self, allocator: NeverFailingAllocator, size: u31, binding: c_uint) void {
|
pub fn init(self: *Self, allocator: NeverFailingAllocator, size: u31, binding: c_uint) void {
|
||||||
|
self.used = 0;
|
||||||
self.binding = binding;
|
self.binding = binding;
|
||||||
self.createBuffer(size);
|
self.createBuffer(size);
|
||||||
self.activeFence = 0;
|
self.activeFence = 0;
|
||||||
@ -2512,7 +2513,7 @@ pub const Image = struct { // MARK: Image
|
|||||||
pub fn readFromFile(allocator: NeverFailingAllocator, path: []const u8) !Image {
|
pub fn readFromFile(allocator: NeverFailingAllocator, path: []const u8) !Image {
|
||||||
var result: Image = undefined;
|
var result: Image = undefined;
|
||||||
var channel: c_int = undefined;
|
var channel: c_int = undefined;
|
||||||
const nullTerminatedPath = std.fmt.allocPrintZ(main.stackAllocator.allocator, "{s}", .{path}) catch unreachable; // TODO: Find a more zig-friendly image loading library.
|
const nullTerminatedPath = main.stackAllocator.dupeZ(u8, path); // TODO: Find a more zig-friendly image loading library.
|
||||||
errdefer main.stackAllocator.free(nullTerminatedPath);
|
errdefer main.stackAllocator.free(nullTerminatedPath);
|
||||||
stb_image.stbi_set_flip_vertically_on_load(1);
|
stb_image.stbi_set_flip_vertically_on_load(1);
|
||||||
const data = stb_image.stbi_load(nullTerminatedPath.ptr, @ptrCast(&result.width), @ptrCast(&result.height), &channel, 4) orelse {
|
const data = stb_image.stbi_load(nullTerminatedPath.ptr, @ptrCast(&result.width), @ptrCast(&result.height), &channel, 4) orelse {
|
||||||
@ -2526,7 +2527,7 @@ pub const Image = struct { // MARK: Image
|
|||||||
pub fn readUnflippedFromFile(allocator: NeverFailingAllocator, path: []const u8) !Image {
|
pub fn readUnflippedFromFile(allocator: NeverFailingAllocator, path: []const u8) !Image {
|
||||||
var result: Image = undefined;
|
var result: Image = undefined;
|
||||||
var channel: c_int = undefined;
|
var channel: c_int = undefined;
|
||||||
const nullTerminatedPath = std.fmt.allocPrintZ(main.stackAllocator.allocator, "{s}", .{path}) catch unreachable; // TODO: Find a more zig-friendly image loading library.
|
const nullTerminatedPath = main.stackAllocator.dupeZ(u8, path); // TODO: Find a more zig-friendly image loading library.
|
||||||
errdefer main.stackAllocator.free(nullTerminatedPath);
|
errdefer main.stackAllocator.free(nullTerminatedPath);
|
||||||
const data = stb_image.stbi_load(nullTerminatedPath.ptr, @ptrCast(&result.width), @ptrCast(&result.height), &channel, 4) orelse {
|
const data = stb_image.stbi_load(nullTerminatedPath.ptr, @ptrCast(&result.width), @ptrCast(&result.height), &channel, 4) orelse {
|
||||||
return error.FileNotFound;
|
return error.FileNotFound;
|
||||||
|
@ -434,10 +434,10 @@ pub const Key = struct { // MARK: Key
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
|
pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
|
||||||
fn errorCallback(errorCode: c_int, description: [*c]const u8) callconv(.C) void {
|
fn errorCallback(errorCode: c_int, description: [*c]const u8) callconv(.c) void {
|
||||||
std.log.err("GLFW Error({}): {s}", .{errorCode, description});
|
std.log.err("GLFW Error({}): {s}", .{errorCode, description});
|
||||||
}
|
}
|
||||||
fn keyCallback(_: ?*c.GLFWwindow, glfw_key: c_int, scancode: c_int, action: c_int, _mods: c_int) callconv(.C) void {
|
fn keyCallback(_: ?*c.GLFWwindow, glfw_key: c_int, scancode: c_int, action: c_int, _mods: c_int) callconv(.c) void {
|
||||||
const mods: Key.Modifiers = @bitCast(@as(u6, @intCast(_mods)));
|
const mods: Key.Modifiers = @bitCast(@as(u6, @intCast(_mods)));
|
||||||
if(!mods.control and main.gui.selectedTextInput != null and c.glfwGetKeyName(glfw_key, scancode) != null) return; // Don't send events for keys that are used in writing letters.
|
if(!mods.control and main.gui.selectedTextInput != null and c.glfwGetKeyName(glfw_key, scancode) != null) return; // Don't send events for keys that are used in writing letters.
|
||||||
const isGrabbed = grabbed;
|
const isGrabbed = grabbed;
|
||||||
@ -465,13 +465,13 @@ pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn charCallback(_: ?*c.GLFWwindow, codepoint: c_uint) callconv(.C) void {
|
fn charCallback(_: ?*c.GLFWwindow, codepoint: c_uint) callconv(.c) void {
|
||||||
if(!grabbed) {
|
if(!grabbed) {
|
||||||
main.gui.textCallbacks.char(@intCast(codepoint));
|
main.gui.textCallbacks.char(@intCast(codepoint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn framebufferSize(_: ?*c.GLFWwindow, newWidth: c_int, newHeight: c_int) callconv(.C) void {
|
pub fn framebufferSize(_: ?*c.GLFWwindow, newWidth: c_int, newHeight: c_int) callconv(.c) void {
|
||||||
std.log.info("Framebuffer: {}, {}", .{newWidth, newHeight});
|
std.log.info("Framebuffer: {}, {}", .{newWidth, newHeight});
|
||||||
width = @intCast(newWidth);
|
width = @intCast(newWidth);
|
||||||
height = @intCast(newHeight);
|
height = @intCast(newHeight);
|
||||||
@ -485,7 +485,7 @@ pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
|
|||||||
var deltaBufferPosition: u2 = 0;
|
var deltaBufferPosition: u2 = 0;
|
||||||
var currentPos: Vec2f = Vec2f{0, 0};
|
var currentPos: Vec2f = Vec2f{0, 0};
|
||||||
var ignoreDataAfterRecentGrab: bool = true;
|
var ignoreDataAfterRecentGrab: bool = true;
|
||||||
fn cursorPosition(_: ?*c.GLFWwindow, x: f64, y: f64) callconv(.C) void {
|
fn cursorPosition(_: ?*c.GLFWwindow, x: f64, y: f64) callconv(.c) void {
|
||||||
const newPos = Vec2f{
|
const newPos = Vec2f{
|
||||||
@floatCast(x),
|
@floatCast(x),
|
||||||
@floatCast(y),
|
@floatCast(y),
|
||||||
@ -509,7 +509,7 @@ pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
|
|||||||
currentPos = newPos;
|
currentPos = newPos;
|
||||||
lastUsedMouse = true;
|
lastUsedMouse = true;
|
||||||
}
|
}
|
||||||
fn mouseButton(_: ?*c.GLFWwindow, button: c_int, action: c_int, _mods: c_int) callconv(.C) void {
|
fn mouseButton(_: ?*c.GLFWwindow, button: c_int, action: c_int, _mods: c_int) callconv(.c) void {
|
||||||
const mods: Key.Modifiers = @bitCast(@as(u6, @intCast(_mods)));
|
const mods: Key.Modifiers = @bitCast(@as(u6, @intCast(_mods)));
|
||||||
const isGrabbed = grabbed;
|
const isGrabbed = grabbed;
|
||||||
if(action == c.GLFW_PRESS or action == c.GLFW_RELEASE) {
|
if(action == c.GLFW_PRESS or action == c.GLFW_RELEASE) {
|
||||||
@ -526,11 +526,11 @@ pub const GLFWCallbacks = struct { // MARK: GLFWCallbacks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn scroll(_: ?*c.GLFWwindow, xOffset: f64, yOffset: f64) callconv(.C) void {
|
fn scroll(_: ?*c.GLFWwindow, xOffset: f64, yOffset: f64) callconv(.c) void {
|
||||||
_ = xOffset;
|
_ = xOffset;
|
||||||
scrollOffset += @floatCast(yOffset);
|
scrollOffset += @floatCast(yOffset);
|
||||||
}
|
}
|
||||||
fn glDebugOutput(source: c_uint, typ: c_uint, _: c_uint, severity: c_uint, length: c_int, message: [*c]const u8, _: ?*const anyopaque) callconv(.C) void {
|
fn glDebugOutput(source: c_uint, typ: c_uint, _: c_uint, severity: c_uint, length: c_int, message: [*c]const u8, _: ?*const anyopaque) callconv(.c) void {
|
||||||
const sourceString: []const u8 = switch(source) {
|
const sourceString: []const u8 = switch(source) {
|
||||||
c.GL_DEBUG_SOURCE_API => "API",
|
c.GL_DEBUG_SOURCE_API => "API",
|
||||||
c.GL_DEBUG_SOURCE_APPLICATION => "Application",
|
c.GL_DEBUG_SOURCE_APPLICATION => "Application",
|
||||||
|
@ -168,12 +168,12 @@ fn moveCursorLeft(self: *TextInput, mods: main.Window.Key.Modifiers) void {
|
|||||||
if(self.cursor.? == 0) return;
|
if(self.cursor.? == 0) return;
|
||||||
self.cursor.? -= 1;
|
self.cursor.? -= 1;
|
||||||
// Find end of previous "word":
|
// Find end of previous "word":
|
||||||
while(!std.ascii.isAlphabetic(text[self.cursor.?]) and std.ascii.isASCII(text[self.cursor.?])) {
|
while(!std.ascii.isAlphabetic(text[self.cursor.?]) and std.ascii.isAscii(text[self.cursor.?])) {
|
||||||
if(self.cursor.? == 0) return;
|
if(self.cursor.? == 0) return;
|
||||||
self.cursor.? -= 1;
|
self.cursor.? -= 1;
|
||||||
}
|
}
|
||||||
// Find the start of the previous "word":
|
// Find the start of the previous "word":
|
||||||
while(std.ascii.isAlphabetic(text[self.cursor.?]) or !std.ascii.isASCII(text[self.cursor.?])) {
|
while(std.ascii.isAlphabetic(text[self.cursor.?]) or !std.ascii.isAscii(text[self.cursor.?])) {
|
||||||
if(self.cursor.? == 0) return;
|
if(self.cursor.? == 0) return;
|
||||||
self.cursor.? -= 1;
|
self.cursor.? -= 1;
|
||||||
}
|
}
|
||||||
@ -213,12 +213,12 @@ fn moveCursorRight(self: *TextInput, mods: main.Window.Key.Modifiers) void {
|
|||||||
if(mods.control) {
|
if(mods.control) {
|
||||||
const text = self.currentString.items;
|
const text = self.currentString.items;
|
||||||
// Find start of next "word":
|
// Find start of next "word":
|
||||||
while(!std.ascii.isAlphabetic(text[self.cursor.?]) and std.ascii.isASCII(text[self.cursor.?])) {
|
while(!std.ascii.isAlphabetic(text[self.cursor.?]) and std.ascii.isAscii(text[self.cursor.?])) {
|
||||||
self.cursor.? += 1;
|
self.cursor.? += 1;
|
||||||
if(self.cursor.? >= self.currentString.items.len) return;
|
if(self.cursor.? >= self.currentString.items.len) return;
|
||||||
}
|
}
|
||||||
// Find the end of the next "word":
|
// Find the end of the next "word":
|
||||||
while(std.ascii.isAlphabetic(text[self.cursor.?]) or !std.ascii.isASCII(text[self.cursor.?])) {
|
while(std.ascii.isAlphabetic(text[self.cursor.?]) or !std.ascii.isAscii(text[self.cursor.?])) {
|
||||||
self.cursor.? += 1;
|
self.cursor.? += 1;
|
||||||
if(self.cursor.? >= self.currentString.items.len) return;
|
if(self.cursor.? >= self.currentString.items.len) return;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ const width: f32 = 420;
|
|||||||
|
|
||||||
fn discoverIpAddress() void {
|
fn discoverIpAddress() void {
|
||||||
main.server.connectionManager.makeOnline();
|
main.server.connectionManager.makeOnline();
|
||||||
ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{}", .{main.server.connectionManager.externalAddress}) catch unreachable;
|
ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{f}", .{main.server.connectionManager.externalAddress}) catch unreachable;
|
||||||
gotIpAddress.store(true, .release);
|
gotIpAddress.store(true, .release);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ pub fn onOpen() void {
|
|||||||
row.add(Label.init(.{0, 0}, 200, connection.user.?.name, .left));
|
row.add(Label.init(.{0, 0}, 200, connection.user.?.name, .left));
|
||||||
row.add(Button.initText(.{0, 0}, 100, "Kick", .{.callback = @ptrCast(&kick), .arg = @intFromPtr(connection)}));
|
row.add(Button.initText(.{0, 0}, 100, "Kick", .{.callback = @ptrCast(&kick), .arg = @intFromPtr(connection)}));
|
||||||
} else {
|
} else {
|
||||||
const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{}", .{connection.remoteAddress}) catch unreachable;
|
const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{f}", .{connection.remoteAddress}) catch unreachable;
|
||||||
defer main.stackAllocator.free(ip);
|
defer main.stackAllocator.free(ip);
|
||||||
row.add(Label.init(.{0, 0}, 200, ip, .left));
|
row.add(Label.init(.{0, 0}, 200, ip, .left));
|
||||||
row.add(Button.initText(.{0, 0}, 100, "Cancel", .{.callback = @ptrCast(&kick), .arg = @intFromPtr(connection)}));
|
row.add(Button.initText(.{0, 0}, 100, "Cancel", .{.callback = @ptrCast(&kick), .arg = @intFromPtr(connection)}));
|
||||||
|
@ -34,7 +34,7 @@ fn discoverIpAddress() void {
|
|||||||
ipAddress = main.globalAllocator.dupe(u8, @errorName(err));
|
ipAddress = main.globalAllocator.dupe(u8, @errorName(err));
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{}", .{connection.?.externalAddress}) catch unreachable;
|
ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{f}", .{connection.?.externalAddress}) catch unreachable;
|
||||||
gotIpAddress.store(true, .release);
|
gotIpAddress.store(true, .release);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ pub fn openWorld(name: []const u8) void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
while(!main.server.running.load(.acquire)) {
|
while(!main.server.running.load(.acquire)) {
|
||||||
std.time.sleep(1_000_000);
|
std.Thread.sleep(1_000_000);
|
||||||
}
|
}
|
||||||
clientConnection.world = &main.game.testWorld;
|
clientConnection.world = &main.game.testWorld;
|
||||||
const ipPort = std.fmt.allocPrint(main.stackAllocator.allocator, "127.0.0.1:{}", .{main.server.connectionManager.localPort}) catch unreachable;
|
const ipPort = std.fmt.allocPrint(main.stackAllocator.allocator, "127.0.0.1:{}", .{main.server.connectionManager.localPort}) catch unreachable;
|
||||||
|
@ -265,11 +265,10 @@ pub const JsonElement = union(JsonType) { // MARK: JsonElement
|
|||||||
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) {
|
switch(json) {
|
||||||
.JsonInt => |value| {
|
.JsonInt => |value| {
|
||||||
std.fmt.formatInt(value, 10, .lower, .{}, list.writer()) catch unreachable;
|
list.writer().print("{d}", .{value}) catch unreachable;
|
||||||
},
|
},
|
||||||
.JsonFloat => |value| {
|
.JsonFloat => |value| {
|
||||||
var buf: [std.fmt.format_float.bufferSize(.scientific, @TypeOf(value))]u8 = undefined;
|
list.writer().print("{e}", .{value}) catch unreachable;
|
||||||
list.appendSlice(std.fmt.format_float.formatFloat(&buf, value, .{.mode = .scientific}) catch unreachable);
|
|
||||||
},
|
},
|
||||||
.JsonBool => |value| {
|
.JsonBool => |value| {
|
||||||
if(value) {
|
if(value) {
|
||||||
|
10
src/main.zig
10
src/main.zig
@ -231,7 +231,7 @@ fn initLogging() void {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
supportsANSIColors = std.io.getStdOut().supportsAnsiEscapeCodes();
|
supportsANSIColors = std.fs.File.stdout().supportsAnsiEscapeCodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinitLogging() void {
|
fn deinitLogging() void {
|
||||||
@ -264,7 +264,9 @@ fn logToStdErr(comptime format: []const u8, args: anytype) void {
|
|||||||
|
|
||||||
const string = std.fmt.allocPrint(allocator, format, args) catch format;
|
const string = std.fmt.allocPrint(allocator, format, args) catch format;
|
||||||
defer allocator.free(string);
|
defer allocator.free(string);
|
||||||
nosuspend std.io.getStdErr().writeAll(string) catch {};
|
const writer = std.debug.lockStderrWriter(&.{});
|
||||||
|
defer std.debug.unlockStderrWriter();
|
||||||
|
nosuspend writer.writeAll(string) catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Callbacks
|
// MARK: Callbacks
|
||||||
@ -682,7 +684,7 @@ pub fn main() void { // MARK: main()
|
|||||||
c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT);
|
c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT);
|
||||||
gui.windowlist.gpu_performance_measuring.stopQuery();
|
gui.windowlist.gpu_performance_measuring.stopQuery();
|
||||||
} else {
|
} else {
|
||||||
std.time.sleep(16_000_000);
|
std.Thread.sleep(16_000_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
const endRendering = std.time.nanoTimestamp();
|
const endRendering = std.time.nanoTimestamp();
|
||||||
@ -696,7 +698,7 @@ pub fn main() void { // MARK: main()
|
|||||||
if(settings.fpsCap) |fpsCap| {
|
if(settings.fpsCap) |fpsCap| {
|
||||||
const minFrameTime = @divFloor(1000*1000*1000, fpsCap);
|
const minFrameTime = @divFloor(1000*1000*1000, fpsCap);
|
||||||
const sleep = @min(minFrameTime, @max(0, minFrameTime - (endRendering -% lastBeginRendering)));
|
const sleep = @min(minFrameTime, @max(0, minFrameTime - (endRendering -% lastBeginRendering)));
|
||||||
std.time.sleep(sleep);
|
std.Thread.sleep(sleep);
|
||||||
}
|
}
|
||||||
const begin = std.time.nanoTimestamp();
|
const begin = std.time.nanoTimestamp();
|
||||||
const deltaTime = @as(f64, @floatFromInt(begin -% lastBeginRendering))/1e9;
|
const deltaTime = @as(f64, @floatFromInt(begin -% lastBeginRendering))/1e9;
|
||||||
|
@ -64,10 +64,19 @@ const Socket = struct {
|
|||||||
.port = @byteSwap(destination.port),
|
.port = @byteSwap(destination.port),
|
||||||
.addr = destination.ip,
|
.addr = destination.ip,
|
||||||
};
|
};
|
||||||
std.debug.assert(data.len == posix.sendto(self.socketID, data, 0, @ptrCast(&addr), @sizeOf(posix.sockaddr.in)) catch |err| {
|
if(builtin.os.tag == .windows) { // TODO: Upstream error, fix after next Zig update after #24466 is merged
|
||||||
std.log.info("Got error while sending to {}: {s}", .{destination, @errorName(err)});
|
const result = posix.system.sendto(self.socketID, data.ptr, data.len, 0, @ptrCast(&addr), @sizeOf(posix.sockaddr.in));
|
||||||
return;
|
if(result < 0) {
|
||||||
});
|
std.log.info("Got error while sending to {f}: {s}", .{destination, @tagName(std.os.windows.ws2_32.WSAGetLastError())});
|
||||||
|
} else {
|
||||||
|
std.debug.assert(@as(usize, @intCast(result)) == data.len);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std.debug.assert(data.len == posix.sendto(self.socketID, data, 0, @ptrCast(&addr), @sizeOf(posix.sockaddr.in)) catch |err| {
|
||||||
|
std.log.info("Got error while sending to {f}: {s}", .{destination, @errorName(err)});
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive(self: Socket, buffer: []u8, timeout: i32, resultAddress: *Address) ![]u8 {
|
fn receive(self: Socket, buffer: []u8, timeout: i32, resultAddress: *Address) ![]u8 {
|
||||||
@ -85,7 +94,7 @@ const Socket = struct {
|
|||||||
else => |err| return std.os.windows.unexpectedWSAError(err),
|
else => |err| return std.os.windows.unexpectedWSAError(err),
|
||||||
}
|
}
|
||||||
} else if(length == 0) {
|
} else if(length == 0) {
|
||||||
std.time.sleep(1000000); // Manually sleep, since WSAPoll is blocking.
|
std.Thread.sleep(1000000); // Manually sleep, since WSAPoll is blocking.
|
||||||
return error.Timeout;
|
return error.Timeout;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -139,7 +148,7 @@ pub const Address = struct {
|
|||||||
|
|
||||||
pub const localHost = 0x0100007f;
|
pub const localHost = 0x0100007f;
|
||||||
|
|
||||||
pub fn format(self: Address, _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
pub fn format(self: Address, writer: anytype) !void {
|
||||||
if(self.isSymmetricNAT) {
|
if(self.isSymmetricNAT) {
|
||||||
try writer.print("{}.{}.{}.{}:?{}", .{self.ip & 255, self.ip >> 8 & 255, self.ip >> 16 & 255, self.ip >> 24, self.port});
|
try writer.print("{}.{}.{}.{}:?{}", .{self.ip & 255, self.ip >> 8 & 255, self.ip >> 16 & 255, self.ip >> 24, self.port});
|
||||||
} else {
|
} else {
|
||||||
@ -295,7 +304,7 @@ const STUN = struct { // MARK: STUN
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if(oldAddress) |other| {
|
if(oldAddress) |other| {
|
||||||
std.log.info("{}", .{result});
|
std.log.info("{f}", .{result});
|
||||||
if(other.ip == result.ip and other.port == result.port) {
|
if(other.ip == result.ip and other.port == result.port) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
@ -556,17 +565,17 @@ pub const ConnectionManager = struct { // MARK: ConnectionManager
|
|||||||
}
|
}
|
||||||
if(self.allowNewConnections.load(.monotonic) or source.ip == Address.localHost) {
|
if(self.allowNewConnections.load(.monotonic) or source.ip == Address.localHost) {
|
||||||
if(data.len != 0 and data[0] == @intFromEnum(Connection.ChannelId.init)) {
|
if(data.len != 0 and data[0] == @intFromEnum(Connection.ChannelId.init)) {
|
||||||
const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{}", .{source}) catch unreachable;
|
const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{f}", .{source}) catch unreachable;
|
||||||
defer main.stackAllocator.free(ip);
|
defer main.stackAllocator.free(ip);
|
||||||
const user = main.server.User.initAndIncreaseRefCount(main.server.connectionManager, ip) catch |err| {
|
const user = main.server.User.initAndIncreaseRefCount(main.server.connectionManager, ip) catch |err| {
|
||||||
std.log.err("Cannot connect user from external IP {}: {s}", .{source, @errorName(err)});
|
std.log.err("Cannot connect user from external IP {f}: {s}", .{source, @errorName(err)});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
user.decreaseRefCount();
|
user.decreaseRefCount();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: Reduce the number of false alarms in the short period after a disconnect.
|
// TODO: Reduce the number of false alarms in the short period after a disconnect.
|
||||||
std.log.warn("Unknown connection from address: {}", .{source});
|
std.log.warn("Unknown connection from address: {f}", .{source});
|
||||||
std.log.debug("Message: {any}", .{data});
|
std.log.debug("Message: {any}", .{data});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2025,7 +2034,7 @@ pub const Connection = struct { // MARK: Connection
|
|||||||
self.tryReceive(data) catch |err| {
|
self.tryReceive(data) catch |err| {
|
||||||
std.log.err("Got error while processing received network data: {s}", .{@errorName(err)});
|
std.log.err("Got error while processing received network data: {s}", .{@errorName(err)});
|
||||||
if(@errorReturnTrace()) |trace| {
|
if(@errorReturnTrace()) |trace| {
|
||||||
std.log.info("{}", .{trace});
|
std.log.info("{f}", .{trace});
|
||||||
}
|
}
|
||||||
self.disconnect();
|
self.disconnect();
|
||||||
};
|
};
|
||||||
@ -2218,7 +2227,7 @@ pub const Connection = struct { // MARK: Connection
|
|||||||
self.manager.send(&.{@intFromEnum(ChannelId.disconnect)}, self.remoteAddress, null);
|
self.manager.send(&.{@intFromEnum(ChannelId.disconnect)}, self.remoteAddress, null);
|
||||||
self.connectionState.store(.disconnectDesired, .unordered);
|
self.connectionState.store(.disconnectDesired, .unordered);
|
||||||
if(builtin.os.tag == .windows and !self.isServerSide() and main.server.world != null) {
|
if(builtin.os.tag == .windows and !self.isServerSide() and main.server.world != null) {
|
||||||
std.time.sleep(10000000); // Windows is too eager to close the socket, without waiting here we get a ConnectionResetByPeer on the other side.
|
std.Thread.sleep(10000000); // Windows is too eager to close the socket, without waiting here we get a ConnectionResetByPeer on the other side.
|
||||||
}
|
}
|
||||||
self.manager.removeConnection(self);
|
self.manager.removeConnection(self);
|
||||||
if(self.user) |user| {
|
if(self.user) |user| {
|
||||||
|
@ -1717,7 +1717,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
|
|||||||
}
|
}
|
||||||
self.culledSortingCount += @intCast(self.blockBreakingFaces.items.len);
|
self.culledSortingCount += @intCast(self.blockBreakingFaces.items.len);
|
||||||
// Upload:
|
// Upload:
|
||||||
faceBuffers[std.math.log2_int(u32, self.pos.voxelSize)].uploadData(self.sortingOutputBuffer[0..self.culledSortingCount], &self.transparentMesh.bufferAllocation);
|
faceBuffers[self.transparentMesh.lod].uploadData(self.sortingOutputBuffer[0..self.culledSortingCount], &self.transparentMesh.bufferAllocation);
|
||||||
self.uploadChunkPosition();
|
self.uploadChunkPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +444,7 @@ pub fn start(name: []const u8, port: ?u16) void {
|
|||||||
while(running.load(.monotonic)) {
|
while(running.load(.monotonic)) {
|
||||||
const newTime = std.time.nanoTimestamp();
|
const newTime = std.time.nanoTimestamp();
|
||||||
if(newTime -% lastTime < updateNanoTime) {
|
if(newTime -% lastTime < updateNanoTime) {
|
||||||
std.time.sleep(@intCast(lastTime +% updateNanoTime -% newTime));
|
std.Thread.sleep(@intCast(lastTime +% updateNanoTime -% newTime));
|
||||||
lastTime +%= updateNanoTime;
|
lastTime +%= updateNanoTime;
|
||||||
} else {
|
} else {
|
||||||
std.log.warn("The server is lagging behind by {d:.1} ms", .{@as(f32, @floatFromInt(newTime -% lastTime -% updateNanoTime))/1000000.0});
|
std.log.warn("The server is lagging behind by {d:.1} ms", .{@as(f32, @floatFromInt(newTime -% lastTime -% updateNanoTime))/1000000.0});
|
||||||
|
@ -48,7 +48,7 @@ pub const RegionFile = struct { // MARK: RegionFile
|
|||||||
defer main.stackAllocator.free(data);
|
defer main.stackAllocator.free(data);
|
||||||
self.load(path, data) catch {
|
self.load(path, data) catch {
|
||||||
std.log.err("Corrupted region file: {s}", .{path});
|
std.log.err("Corrupted region file: {s}", .{path});
|
||||||
if(@errorReturnTrace()) |trace| std.log.info("{}", .{trace});
|
if(@errorReturnTrace()) |trace| std.log.info("{f}", .{trace});
|
||||||
};
|
};
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -751,7 +751,7 @@ pub const ServerWorld = struct { // MARK: ServerWorld
|
|||||||
updateRequest.region.decreaseRefCount();
|
updateRequest.region.decreaseRefCount();
|
||||||
}
|
}
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
std.time.sleep(1_000_000);
|
std.Thread.sleep(1_000_000);
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
if(main.threadPool.queueSize() == 0 and self.chunkUpdateQueue.peek() == null and self.regionUpdateQueue.peek() == null) break;
|
if(main.threadPool.queueSize() == 0 and self.chunkUpdateQueue.peek() == null and self.regionUpdateQueue.peek() == null) break;
|
||||||
}
|
}
|
||||||
|
@ -655,7 +655,7 @@ pub fn BlockingMaxHeap(comptime T: type) type { // MARK: BlockingMaxHeap
|
|||||||
self.waitingThreads.broadcast();
|
self.waitingThreads.broadcast();
|
||||||
while(self.waitingThreadCount != 0) {
|
while(self.waitingThreadCount != 0) {
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
std.time.sleep(1000000);
|
std.Thread.sleep(1000000);
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
}
|
}
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
@ -899,7 +899,7 @@ pub const ThreadPool = struct { // MARK: ThreadPool
|
|||||||
// Wait for active tasks:
|
// Wait for active tasks:
|
||||||
for(self.currentTasks) |*task| {
|
for(self.currentTasks) |*task| {
|
||||||
while(task.load(.monotonic) == vtable) {
|
while(task.load(.monotonic) == vtable) {
|
||||||
std.time.sleep(1e6);
|
std.Thread.sleep(1e6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -966,7 +966,7 @@ pub const ThreadPool = struct { // MARK: ThreadPool
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.time.sleep(1000000);
|
std.Thread.sleep(1000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -998,7 +998,7 @@ pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIn
|
|||||||
pub fn initCapacity(bitSize: u5) Self {
|
pub fn initCapacity(bitSize: u5) Self {
|
||||||
std.debug.assert(bitSize == 0 or bitSize & bitSize - 1 == 0); // Must be a power of 2
|
std.debug.assert(bitSize == 0 or bitSize & bitSize - 1 == 0); // Must be a power of 2
|
||||||
return .{
|
return .{
|
||||||
.data = dynamicIntArrayAllocator.allocator().alignedAlloc(u32, 64, @as(usize, @divExact(size, @bitSizeOf(u32)))*bitSize),
|
.data = dynamicIntArrayAllocator.allocator().alignedAlloc(u32, .@"64", @as(usize, @divExact(size, @bitSizeOf(u32)))*bitSize),
|
||||||
.bitSize = bitSize,
|
.bitSize = bitSize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ const LinuxImpl = struct { // MARK: LinuxImpl
|
|||||||
return;
|
return;
|
||||||
}) |entry| {
|
}) |entry| {
|
||||||
if(entry.kind == .directory) {
|
if(entry.kind == .directory) {
|
||||||
const subPath = std.fmt.allocPrintZ(main.stackAllocator.allocator, "{s}/{s}", .{path, entry.name}) catch unreachable;
|
const subPath = std.fmt.allocPrintSentinel(main.stackAllocator.allocator, "{s}/{s}", .{path, entry.name}, 0) catch unreachable;
|
||||||
defer main.stackAllocator.free(subPath);
|
defer main.stackAllocator.free(subPath);
|
||||||
addWatchDescriptor(info, subPath);
|
addWatchDescriptor(info, subPath);
|
||||||
addWatchDescriptorsRecursive(info, subPath);
|
addWatchDescriptorsRecursive(info, subPath);
|
||||||
|
@ -17,7 +17,7 @@ pub const StackAllocator = struct { // MARK: StackAllocator
|
|||||||
pub fn init(backingAllocator: NeverFailingAllocator, size: u31) 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, .fromByteUnits(4096), size),
|
||||||
.index = 0,
|
.index = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -341,9 +341,9 @@ pub const NeverFailingAllocator = struct { // MARK: NeverFailingAllocator
|
|||||||
self: NeverFailingAllocator,
|
self: NeverFailingAllocator,
|
||||||
comptime T: type,
|
comptime T: type,
|
||||||
/// null means naturally aligned
|
/// null means naturally aligned
|
||||||
comptime alignment: ?u29,
|
comptime alignment: ?Alignment,
|
||||||
n: usize,
|
n: usize,
|
||||||
) []align(alignment orelse @alignOf(T)) T {
|
) []align(if(alignment) |a| a.toByteUnits() else @alignOf(T)) T {
|
||||||
return self.allocator.alignedAlloc(T, alignment, n) catch unreachable;
|
return self.allocator.alignedAlloc(T, alignment, n) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,10 +351,10 @@ pub const NeverFailingAllocator = struct { // MARK: NeverFailingAllocator
|
|||||||
self: NeverFailingAllocator,
|
self: NeverFailingAllocator,
|
||||||
comptime T: type,
|
comptime T: type,
|
||||||
/// null means naturally aligned
|
/// null means naturally aligned
|
||||||
comptime alignment: ?u29,
|
comptime alignment: ?Alignment,
|
||||||
n: usize,
|
n: usize,
|
||||||
return_address: usize,
|
return_address: usize,
|
||||||
) []align(alignment orelse @alignOf(T)) T {
|
) []align(if(alignment) |a| a.toByteUnits() else @alignOf(T)) T {
|
||||||
return self.allocator.allocAdvancedWithRetAddr(T, alignment, n, return_address) catch unreachable;
|
return self.allocator.allocAdvancedWithRetAddr(T, alignment, n, return_address) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,6 +483,7 @@ pub const NeverFailingArenaAllocator = struct { // MARK: NeverFailingArena
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn shrinkAndFree(self: *NeverFailingArenaAllocator) void {
|
pub fn shrinkAndFree(self: *NeverFailingArenaAllocator) void {
|
||||||
|
if(true) return;
|
||||||
const node = self.arena.state.buffer_list.first orelse return;
|
const node = self.arena.state.buffer_list.first orelse return;
|
||||||
const allocBuf = @as([*]u8, @ptrCast(node))[0..node.data];
|
const allocBuf = @as([*]u8, @ptrCast(node))[0..node.data];
|
||||||
const dataSize = std.mem.alignForward(usize, @sizeOf(std.SinglyLinkedList(usize).Node) + self.arena.state.end_index, @alignOf(std.SinglyLinkedList(usize).Node));
|
const dataSize = std.mem.alignForward(usize, @sizeOf(std.SinglyLinkedList(usize).Node) + self.arena.state.end_index, @alignOf(std.SinglyLinkedList(usize).Node));
|
||||||
@ -570,7 +571,7 @@ pub fn MemoryPool(Item: type) type { // MARK: MemoryPool
|
|||||||
main.utils.assertLocked(&pool.mutex);
|
main.utils.assertLocked(&pool.mutex);
|
||||||
pool.totalAllocations += 1;
|
pool.totalAllocations += 1;
|
||||||
pool.freeAllocations += 1;
|
pool.freeAllocations += 1;
|
||||||
const mem = pool.arena.allocator().alignedAlloc(u8, item_alignment, item_size);
|
const mem = pool.arena.allocator().alignedAlloc(u8, .fromByteUnits(item_alignment), item_size);
|
||||||
return mem[0..item_size]; // coerce slice to array pointer
|
return mem[0..item_size]; // coerce slice to array pointer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -634,7 +635,7 @@ pub fn PowerOfTwoPoolAllocator(minSize: comptime_int, maxSize: comptime_int, max
|
|||||||
fn allocNew(self: *Bucket, arena: NeverFailingAllocator, size: usize) [*]align(alignment) u8 {
|
fn allocNew(self: *Bucket, arena: NeverFailingAllocator, size: usize) [*]align(alignment) u8 {
|
||||||
self.totalAllocations += 1;
|
self.totalAllocations += 1;
|
||||||
self.freeAllocations += 1;
|
self.freeAllocations += 1;
|
||||||
return arena.alignedAlloc(u8, alignment, size).ptr;
|
return arena.alignedAlloc(u8, .fromByteUnits(alignment), size).ptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ pub fn List(comptime T: type) type {
|
|||||||
@compileError("The Writer interface is only defined for ArrayList(u8) " ++
|
@compileError("The Writer interface is only defined for ArrayList(u8) " ++
|
||||||
"but the given type is ArrayList(" ++ @typeName(T) ++ ")")
|
"but the given type is ArrayList(" ++ @typeName(T) ++ ")")
|
||||||
else
|
else
|
||||||
std.io.Writer(*@This(), error{}, appendWrite);
|
std.io.GenericWriter(*@This(), error{}, appendWrite);
|
||||||
|
|
||||||
pub fn writer(self: *@This()) Writer {
|
pub fn writer(self: *@This()) Writer {
|
||||||
return .{.context = self};
|
return .{.context = self};
|
||||||
|
@ -351,11 +351,10 @@ pub const ZonElement = union(enum) { // MARK: Zon
|
|||||||
fn recurseToString(zon: ZonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) void {
|
fn recurseToString(zon: ZonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) void {
|
||||||
switch(zon) {
|
switch(zon) {
|
||||||
.int => |value| {
|
.int => |value| {
|
||||||
std.fmt.formatInt(value, 10, .lower, .{}, list.writer()) catch unreachable;
|
list.writer().print("{d}", .{value}) catch unreachable;
|
||||||
},
|
},
|
||||||
.float => |value| {
|
.float => |value| {
|
||||||
var buf: [std.fmt.format_float.bufferSize(.scientific, @TypeOf(value))]u8 = undefined;
|
list.writer().print("{e}", .{value}) catch unreachable;
|
||||||
list.appendSlice(std.fmt.format_float.formatFloat(&buf, value, .{.mode = .scientific}) catch unreachable);
|
|
||||||
},
|
},
|
||||||
.bool => |value| {
|
.bool => |value| {
|
||||||
if(value) {
|
if(value) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Default test runner for unit tests.
|
|
||||||
// Source: https://github.com/ziglang/zig/blob/0.14.0/lib/compiler/test_runner.zig
|
// Source: https://github.com/ziglang/zig/blob/0.14.0/lib/compiler/test_runner.zig
|
||||||
|
//! Default test runner for unit tests.
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
@ -16,7 +16,9 @@ var fba_buffer: [8192]u8 = undefined;
|
|||||||
var fba = std.heap.FixedBufferAllocator.init(&fba_buffer);
|
var fba = std.heap.FixedBufferAllocator.init(&fba_buffer);
|
||||||
|
|
||||||
const crippled = switch(builtin.zig_backend) {
|
const crippled = switch(builtin.zig_backend) {
|
||||||
.stage2_riscv64 => true,
|
.stage2_powerpc,
|
||||||
|
.stage2_riscv64,
|
||||||
|
=> true,
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,8 +70,8 @@ fn mainServer() !void {
|
|||||||
@disableInstrumentation();
|
@disableInstrumentation();
|
||||||
var server = try std.zig.Server.init(.{
|
var server = try std.zig.Server.init(.{
|
||||||
.gpa = fba.allocator(),
|
.gpa = fba.allocator(),
|
||||||
.in = std.io.getStdIn(),
|
.in = .stdin(),
|
||||||
.out = std.io.getStdOut(),
|
.out = .stdout(),
|
||||||
.zig_version = builtin.zig_version_string,
|
.zig_version = builtin.zig_version_string,
|
||||||
});
|
});
|
||||||
defer server.deinit();
|
defer server.deinit();
|
||||||
@ -189,7 +191,7 @@ fn mainTerminal() void {
|
|||||||
.root_name = "Test",
|
.root_name = "Test",
|
||||||
.estimated_total_items = test_fn_list.len,
|
.estimated_total_items = test_fn_list.len,
|
||||||
});
|
});
|
||||||
const doColors = std.io.getStdErr().supportsAnsiEscapeCodes();
|
const doColors = std.fs.File.stderr().supportsAnsiEscapeCodes();
|
||||||
const reset = if(doColors) "\x1b[0m" else "";
|
const reset = if(doColors) "\x1b[0m" else "";
|
||||||
const red = if(doColors) "\x1b[31m" else "";
|
const red = if(doColors) "\x1b[31m" else "";
|
||||||
const yellow = if(doColors) "\x1b[33m" else "";
|
const yellow = if(doColors) "\x1b[33m" else "";
|
||||||
@ -283,6 +285,7 @@ pub fn mainSimple() anyerror!void {
|
|||||||
};
|
};
|
||||||
// is the backend capable of using std.fmt.format to print a summary at the end?
|
// is the backend capable of using std.fmt.format to print a summary at the end?
|
||||||
const print_summary = switch(builtin.zig_backend) {
|
const print_summary = switch(builtin.zig_backend) {
|
||||||
|
.stage2_riscv64 => true,
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -291,7 +294,7 @@ pub fn mainSimple() anyerror!void {
|
|||||||
var failed: u64 = 0;
|
var failed: u64 = 0;
|
||||||
|
|
||||||
// we don't want to bring in File and Writer if the backend doesn't support it
|
// we don't want to bring in File and Writer if the backend doesn't support it
|
||||||
const stderr = if(comptime enable_print) std.io.getStdErr() else {};
|
const stderr = if(comptime enable_print) std.fs.File.stderr() else {};
|
||||||
|
|
||||||
for(builtin.test_functions) |test_fn| {
|
for(builtin.test_functions) |test_fn| {
|
||||||
if(test_fn.func()) |_| {
|
if(test_fn.func()) |_| {
|
||||||
@ -300,7 +303,7 @@ pub fn mainSimple() anyerror!void {
|
|||||||
stderr.writeAll("... ") catch {};
|
stderr.writeAll("... ") catch {};
|
||||||
stderr.writeAll("PASS\n") catch {};
|
stderr.writeAll("PASS\n") catch {};
|
||||||
}
|
}
|
||||||
} else |err| if(enable_print) {
|
} else |err| {
|
||||||
if(enable_print) {
|
if(enable_print) {
|
||||||
stderr.writeAll(test_fn.name) catch {};
|
stderr.writeAll(test_fn.name) catch {};
|
||||||
stderr.writeAll("... ") catch {};
|
stderr.writeAll("... ") catch {};
|
||||||
@ -318,7 +321,7 @@ pub fn mainSimple() anyerror!void {
|
|||||||
passed += 1;
|
passed += 1;
|
||||||
}
|
}
|
||||||
if(enable_print and print_summary) {
|
if(enable_print and print_summary) {
|
||||||
stderr.writer().print("{} passed, {} skipped, {} failed\n", .{passed, skipped, failed}) catch {};
|
stderr.deprecatedWriter().print("{} passed, {} skipped, {} failed\n", .{passed, skipped, failed}) catch {};
|
||||||
}
|
}
|
||||||
if(failed != 0) std.process.exit(1);
|
if(failed != 0) std.process.exit(1);
|
||||||
}
|
}
|
||||||
@ -343,7 +346,7 @@ var is_fuzz_test: bool = undefined;
|
|||||||
extern fn fuzzer_set_name(name_ptr: [*]const u8, name_len: usize) void;
|
extern fn fuzzer_set_name(name_ptr: [*]const u8, name_len: usize) void;
|
||||||
extern fn fuzzer_init(cache_dir: FuzzerSlice) void;
|
extern fn fuzzer_init(cache_dir: FuzzerSlice) void;
|
||||||
extern fn fuzzer_init_corpus_elem(input_ptr: [*]const u8, input_len: usize) void;
|
extern fn fuzzer_init_corpus_elem(input_ptr: [*]const u8, input_len: usize) void;
|
||||||
extern fn fuzzer_start(testOne: *const fn([*]const u8, usize) callconv(.C) void) void;
|
extern fn fuzzer_start(testOne: *const fn([*]const u8, usize) callconv(.c) void) void;
|
||||||
extern fn fuzzer_coverage_id() u64;
|
extern fn fuzzer_coverage_id() u64;
|
||||||
|
|
||||||
pub fn fuzz(
|
pub fn fuzz(
|
||||||
@ -375,7 +378,7 @@ pub fn fuzz(
|
|||||||
const global = struct {
|
const global = struct {
|
||||||
var ctx: @TypeOf(context) = undefined;
|
var ctx: @TypeOf(context) = undefined;
|
||||||
|
|
||||||
fn fuzzer_one(input_ptr: [*]const u8, input_len: usize) callconv(.C) void {
|
fn fuzzer_one(input_ptr: [*]const u8, input_len: usize) callconv(.c) void {
|
||||||
@disableInstrumentation();
|
@disableInstrumentation();
|
||||||
testing.allocator_instance = .{};
|
testing.allocator_instance = .{};
|
||||||
defer if(testing.allocator_instance.deinit() == .leak) std.process.exit(1);
|
defer if(testing.allocator_instance.deinit() == .leak) std.process.exit(1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user