Sort button attempt 2 - #3194
Conversation
Wunka
left a comment
There was a problem hiding this comment.
I still think that std.sort is probably way nicer and easier. Here is an example (not tested) based on your current code (but of course not completly mapped and I with an added getTags method for the Item struct):
pub fn sortItems(source: ClientInventory, ignoredSlotCount: usize) void {
compressItems(source);
const ctx: SortContext = .{.inv = source};
std.sort.insertionContext(ignoredSlotCount, source.super._items.len, ctx);
}
const SortContext = struct {
inv: ClientInventory,
pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
const itemA = ctx.inv.getItem(a);
const itemB = ctx.inv.getItem(b);
if(itemA == .null) return false;
if(itemB == .null) return true;
const itemATags = itemA.getTags().?;
const itemBTags = itemB.getTags().?;
for(0..@min(itemATags.len, itemBTags.len)) |i| {
if(itemATags[i] == itemBTags[i]) continue;
return std.mem.lessThan(u8, itemATags[i].getName(), itemBTags[i].getName());
}
if(itemATags.len != itemBTags.len) return itemATags.len < itemBTags.len;
return std.mem.lessThan(u8, itemA.id().?, itemB.id().?);
}
pub fn swap(ctx: @This(), a: usize, b: usize) void {
main.sync.client.executeCommand(.{.depositOrSwap = .{
.dest = .{.inv = ctx.inv.super, .slot = @intCast(a)},
.source = .{.inv = ctx.inv.super, .slot = @intCast(b)},
}});
}
};|
also fixes #3195 |
I realized how to turn tags into numbers so I’m gonna try this |
|
is ready for rereview |
Wunka
left a comment
There was a problem hiding this comment.
Nice. Now the code looks much better
IntegratedQuantum
left a comment
There was a problem hiding this comment.
Before my next review please figure out how to get leak checking working. It still leaks.
To use leak checking you need to build in debug mode, test your feature, and then you need to exit the game normally (do not kill it through Ctrl+C or whatever), then you will see the leaks in the terminal output.
Please ask someone for help if you can't figure it out on your own. But we cannot have you as a contributor if every time I review I need to run the leak check for you.
|
ok what allocator is leaking? |
|
I don't think the sort button should be that big. The UI / UX is pretty bad on it. Maybe it should live in the toolbar as a small filter icon |
Are you looking at the old pictures? |
| const index = items.BaseItemIndex.fromId(stringId).?; | ||
| const item = &items.itemList[@intFromEnum(index)]; | ||
| item.block = block; | ||
| const combinedTags = std.mem.concat(main.worldArena.allocator, Tag, &.{blocks.parseBlock(stringId).tags(), item.tags}) catch unreachable; |
There was a problem hiding this comment.
I'm still not sure if we want this.
Also it's not needed now that sorting no longer uses tags
| } | ||
| } | ||
|
|
||
| pub fn getTags(self: Item) []const Tag { |
| return std.mem.lessThan(u8, itemA.id().?, itemB.id().?); | ||
| } | ||
|
|
||
| pub fn swap(ctx: *@This(), a: usize, b: usize) void { |
| var SortList = main.ListManaged(usize).init(main.stackAllocator); | ||
| var intermediaryList = main.ListManaged(usize).init(main.stackAllocator); | ||
| defer SortList.deinit(); | ||
| defer intermediaryList.deinit(); |
There was a problem hiding this comment.
defer should always be directly after the line that does the init
| pub fn sortItems(source: ClientInventory, options: SortOptions) void { | ||
| compressItems(source, options); | ||
| const InventorySize: usize = source.super.size() - options.ignoredSlotCount; | ||
| var SortList = main.ListManaged(usize).init(main.stackAllocator); |
There was a problem hiding this comment.
| var SortList = main.ListManaged(usize).init(main.stackAllocator); | |
| var sortList = main.ListManaged(usize).init(main.stackAllocator); |
|
I don't see any changes since my last review. Did you forget to push? |
|
testing finished |
| } | ||
| if ((ctx.inv.getAmount(a) > ctx.inv.getAmount(b)) and std.mem.eql(u8, itemA.id().?, itemB.id().?)) return true; | ||
|
|
||
| return std.mem.lessThan(u8, itemA.id().?, itemB.id().?); |
There was a problem hiding this comment.
They should still sort by id first (you did accound for that with items, but not tools).
| .disabled = options.disabled, | ||
| .hideBackground = options.hideBackground, | ||
| }; | ||
| if (self.hideBackground) self.child.mutSize().* = self.size; |
| if ((itemA == .proceduralItem) and (itemB != .proceduralItem)) return true; | ||
| if ((itemA == .proceduralItem) and (itemB == .proceduralItem)) { | ||
| const itemADurabilityPercent: f32 = @as(f32, @floatFromInt(itemA.proceduralItem.durability))/itemA.proceduralItem.getProperty(.maxDurability); | ||
| const itemBDurabilityPercent: f32 = @as(f32, @floatFromInt(itemB.proceduralItem.durability))/itemB.proceduralItem.getProperty(.maxDurability); |
There was a problem hiding this comment.
I'm not sure if this is reliable.
Does the floating point spec guarantee that x/x is always exactly 1?
There was a problem hiding this comment.
does it matter?
at the point that happens the durabilty will be close enough anyway
There was a problem hiding this comment.
If it doesn't matter, then why do you have a separate sort criterion afterwards?
Also I think it does matter at tools with full durability (which is why I'm asking whether they are guaranteed to be exactly 1).





Sort button now functions as normal
Before sorting it will compress all items into their max stacks and push them all to the lowest index getting rid of any holes
Then the sort button will first seperate items into procederal items and nonprocedural items
then they will be sorted by tag
items that share the same first tag will be internally sorted by their second tag and so on and so forth
procedural items are sorted by durability
Also allows buttons to be hidden
if a button is hidden the icon within it is extended to the size of the whole button (its scaled up).