mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00

When I started to use zig, I mostly used `var`. But over time I adapted to using `const` where possible which is more readable and the compiler is currently optimizing it better.
132 lines
4.1 KiB
Zig
132 lines
4.1 KiB
Zig
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
|
|
const main = @import("root");
|
|
const ConnectionManager = main.network.ConnectionManager;
|
|
const settings = main.settings;
|
|
const Vec2f = main.vec.Vec2f;
|
|
|
|
const gui = @import("../gui.zig");
|
|
const GuiComponent = gui.GuiComponent;
|
|
const GuiWindow = gui.GuiWindow;
|
|
const Button = @import("../components/Button.zig");
|
|
const Label = @import("../components/Label.zig");
|
|
const TextInput = @import("../components/TextInput.zig");
|
|
const VerticalList = @import("../components/VerticalList.zig");
|
|
|
|
pub var window = GuiWindow {
|
|
.contentSize = Vec2f{128, 256},
|
|
.id = "multiplayer",
|
|
};
|
|
|
|
var ipAddressLabel: *Label = undefined;
|
|
|
|
const padding: f32 = 8;
|
|
|
|
var connection: ?*ConnectionManager = null;
|
|
var ipAddress: []const u8 = "";
|
|
var gotIpAddress: std.atomic.Atomic(bool) = std.atomic.Atomic(bool).init(false);
|
|
var thread: ?std.Thread = null;
|
|
const width: f32 = 420;
|
|
|
|
fn flawedDiscoverIpAddress() !void {
|
|
connection = try ConnectionManager.init(12347, true); // TODO: default port
|
|
ipAddress = try std.fmt.allocPrint(main.globalAllocator, "{}", .{connection.?.externalAddress});
|
|
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 gpa = std.heap.GeneralPurposeAllocator(.{.thread_safe=false}){};
|
|
main.threadAllocator = gpa.allocator();
|
|
defer if(gpa.deinit() == .leak) {
|
|
@panic("Memory leak");
|
|
};
|
|
|
|
discoverIpAddress();
|
|
}
|
|
|
|
fn join(_: usize) void {
|
|
if(thread) |_thread| {
|
|
_thread.join();
|
|
thread = null;
|
|
}
|
|
if(ipAddress.len != 0) {
|
|
main.globalAllocator.free(ipAddress);
|
|
ipAddress = "";
|
|
}
|
|
if(connection) |_connection| {
|
|
_connection.world = &main.game.testWorld;
|
|
main.game.testWorld.init(settings.lastUsedIPAddress, _connection) catch |err| {
|
|
std.log.err("Encountered error while opening world: {s}", .{@errorName(err)});
|
|
};
|
|
main.game.world = &main.game.testWorld;
|
|
connection = null;
|
|
} else {
|
|
std.log.err("No connection found. Cannot connect.", .{});
|
|
}
|
|
for(gui.openWindows.items) |openWindow| {
|
|
gui.closeWindow(openWindow) catch |err| {
|
|
std.log.err("Encountered error while opening world: {s}", .{@errorName(err)});
|
|
};
|
|
}
|
|
gui.openHud() catch |err| {
|
|
std.log.err("Encountered error while opening world: {s}", .{@errorName(err)});
|
|
};
|
|
}
|
|
|
|
fn copyIp(_: usize) void {
|
|
main.Window.setClipboardString(ipAddress);
|
|
}
|
|
|
|
pub fn onOpen() Allocator.Error!void {
|
|
const list = try VerticalList.init(.{padding, 16 + padding}, 300, 16);
|
|
try list.add(try Label.init(.{0, 0}, width, "Please send your IP to the host of the game and enter the host's IP below.", .center));
|
|
// 255.255.255.255:?65536 (longest possible ip address)
|
|
ipAddressLabel = try Label.init(.{0, 0}, width, " ", .center);
|
|
try list.add(ipAddressLabel);
|
|
try list.add(try Button.initText(.{0, 0}, 100, "Copy IP", .{.callback = ©Ip}));
|
|
try list.add(try TextInput.init(.{0, 0}, width, 32, settings.lastUsedIPAddress, .{.callback = &join}));
|
|
try list.add(try Button.initText(.{0, 0}, 100, "Join", .{.callback = &join}));
|
|
list.finish(.center);
|
|
window.rootComponent = list.toComponent();
|
|
window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @as(Vec2f, @splat(padding));
|
|
gui.updateWindowPositions();
|
|
|
|
thread = std.Thread.spawn(.{}, discoverIpAddressFromNewThread, .{}) catch |err| blk: {
|
|
std.log.err("Error spawning thread: {s}. Doing it in the current thread instead.", .{@errorName(err)});
|
|
discoverIpAddress();
|
|
break :blk null;
|
|
};
|
|
}
|
|
|
|
pub fn onClose() void {
|
|
if(thread) |_thread| {
|
|
_thread.join();
|
|
thread = null;
|
|
}
|
|
if(connection) |_connection| {
|
|
_connection.deinit();
|
|
connection = null;
|
|
}
|
|
if(ipAddress.len != 0) {
|
|
main.globalAllocator.free(ipAddress);
|
|
ipAddress = "";
|
|
}
|
|
|
|
if(window.rootComponent) |*comp| {
|
|
comp.deinit();
|
|
}
|
|
}
|
|
|
|
pub fn update() Allocator.Error!void {
|
|
if(gotIpAddress.load(.Acquire)) {
|
|
gotIpAddress.store(false, .Monotonic);
|
|
try ipAddressLabel.updateText(ipAddress);
|
|
}
|
|
} |