Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/Inventory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ pub const client = struct { // MARK: client
var maxId: InventoryId = @enumFromInt(0);
var freeIdList: main.List(InventoryId) = .empty;
var serverToClientMap: std.AutoHashMap(InventoryId, Inventory) = undefined;
var loadingInventories: std.AutoHashMap(InventoryId, u32) = undefined;

pub fn init() void {
serverToClientMap = .init(main.globalAllocator.allocator);
loadingInventories = .init(main.globalAllocator.allocator);
}

pub fn deinit() void {
std.debug.assert(freeIdList.items.len == @intFromEnum(maxId)); // leak
freeIdList.clearAndFree(main.globalAllocator);
serverToClientMap.deinit();
loadingInventories.deinit();
}

fn nextId() InventoryId {
Expand Down Expand Up @@ -65,6 +68,7 @@ pub const client = struct { // MARK: client

pub fn unmapServerIdByClientId(clientId: InventoryId) void {
main.sync.client.mutex.assertLocked();
_ = loadingInventories.remove(clientId);
const serverId = blk: {
var it = serverToClientMap.iterator();
while (it.next()) |entry| {
Expand All @@ -75,6 +79,34 @@ pub const client = struct { // MARK: client
unmapServerId(serverId, clientId);
}

fn startLoadTracking(clientId: InventoryId) void {
main.sync.client.mutex.lock();
defer main.sync.client.mutex.unlock();
loadingInventories.put(clientId, 1) catch unreachable;
}

pub fn setExpectedItemCount(clientId: InventoryId, count: u32) void {
main.sync.client.mutex.assertLocked();
if (count == 0) {
_ = loadingInventories.remove(clientId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should never happen right?
(the remove not the == 0, so I would either do an assert that nothing was removed or just do an early return

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well if the client receives that the inventory is empty, I immediately remove it from the inventories being loaded since there's nothing to wait for

} else {
loadingInventories.put(clientId, count) catch unreachable;
}
}

pub fn recordInitialItemReceived(clientId: InventoryId) void {
main.sync.client.mutex.assertLocked();
const entry = loadingInventories.getPtr(clientId) orelse return;
entry.* -= 1;
if (entry.* == 0) _ = loadingInventories.remove(clientId);
}

fn isLoaded(clientId: InventoryId) bool {
main.sync.client.mutex.lock();
defer main.sync.client.mutex.unlock();
return !loadingInventories.contains(clientId);
}

fn getInventory(serverId: InventoryId) ?Inventory {
main.sync.client.mutex.assertLocked();
return serverToClientMap.get(serverId);
Expand Down Expand Up @@ -428,11 +460,17 @@ pub const ClientInventory = struct { // MARK: ClientInventory
.type = clientType,
};
if (clientType == .serverShared) {
client.startLoadTracking(self.super.id);
sync.client.executeCommand(.{.open = .{.inv = self.super, .source = source}});
}
return self;
}

pub fn isLoaded(self: ClientInventory) bool {
if (self.type != .serverShared) return true;
return client.isLoaded(self.super.id);
}

pub fn deinit(self: ClientInventory, allocator: NeverFailingAllocator) void {
if (main.game.world.?.connected) {
sync.client.executeCommand(.{.close = .{.inv = self.super, .allocator = allocator}});
Expand Down
5 changes: 5 additions & 0 deletions src/gui/components/ItemSlot.zig
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ pub fn render(self: *ItemSlot, _: Vec2f) void {
self.text.render(self.pos[0] + self.size[0] - self.textSize[0] - border, self.pos[1] + self.size[1] - self.textSize[1] - border, 8);
}
}
if (!self.inventory.isLoaded()) {
const oldColor = draw.setColor(0x80000000);
defer draw.restoreColor(oldColor);
draw.rect(self.pos, self.size);
}
if (self.mode != .immutable) {
if (self.hovered) {
self.hovered = false;
Expand Down
10 changes: 9 additions & 1 deletion src/sync.zig
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ pub const Command = struct { // MARK: Command
create.inv.ref().amount += create.amount;

create.inv.inv.update();
Inventory.client.recordInitialItemReceived(create.inv.inv.id);
},
.delete => |delete| {
if (delete.inv.ref().amount < delete.amount) {
Expand Down Expand Up @@ -856,12 +857,19 @@ pub const Command = struct { // MARK: Command
if (reader.remaining.len != 0) {
const serverId = try reader.readEnum(InventoryId);
Inventory.client.mapServerId(serverId, self.inv);
const itemCount = try reader.readInt(u32);
Inventory.client.setExpectedItemCount(self.inv.id, itemCount);
}
}

fn confirmationData(self: Open, allocator: NeverFailingAllocator) []const u8 {
var writer = BinaryWriter.initCapacity(allocator, 4);
var writer = BinaryWriter.initCapacity(allocator, 8);
writer.writeEnum(InventoryId, self.inv.id);
var itemCount: u32 = 0;
for (self.inv._items) |stack| {
if (stack.item != .null) itemCount += 1;
}
writer.writeInt(u32, itemCount);
return writer.data.toOwnedSlice();
}

Expand Down
Loading