Tech Reborn

Tech Reborn

30M Downloads

[Feature Request] Make slots configurable output order or maintain output order

ZurrTum opened this issue · 1 comments

commented

what is it:

slots
What is the output order? 🤣

Why is it needed?

I need to sort the items using storage units, but looking at the TechReborn code I see that the slot output is handled via a HashMap and the order changes every time I launch the game.

If there is a better way please tell me

How I use storage units for sorting:

  1. use all directions from the output to get the lowest priority direction (eg: North)
  2. use storage units to pass items in that direction (eg: South to North)
  3. If storage units are placed around a route (eg: in addition to South and North), items can be collected as the route passes
    in game
    slot
    Warning: unstable because it is implemented based on HashMap. The hashCode used is different every time you enter the game, causing the priority to change, and then a certain storage unit will be skipped.
  4. Principle: By trying each direction until failure becomes the Low priority direction

View Source Code:

Use the minecraft Direction when creating:

public SlotConfigHolder(int slotID) {
this.slotID = slotID;
sideMap = new HashMap<>();
Arrays.stream(Direction.values()).forEach(facing -> sideMap.put(facing, new SlotConfig(facing, slotID)));
}

But HashMap uses the hashCode function return value of the minecraft Direction object, which will change, resulting in inconsistent ordering.

public List<SlotConfig> getAllSides() {
return new ArrayList<>(sideMap.values());
}
public void updateSlotConfig(SlotConfig config) {
SlotConfig toEdit = sideMap.get(config.side);
toEdit.slotIO = config.slotIO;
}
private void handleItemIO(MachineBaseBlockEntity machineBase) {
if (!input && !output) {
return;
}
getAllSides().stream()
.filter(config -> config.getSlotIO().getIoConfig() != ExtractConfig.NONE)
.forEach(config -> {
if (input && config.getSlotIO().getIoConfig() == ExtractConfig.INPUT) {
config.handleItemInput(machineBase);
}
if (output && config.getSlotIO().getIoConfig() == ExtractConfig.OUTPUT) {
config.handleItemOutput(machineBase);
}
});
}

  1. A simple idea is to use a LinkedHashMap implementation instead of a HashMap, so that the sorting maintains the insertion order, which is the enumeration order using Minecraft Direction. But it will maintain an extra list and I'm not sure how much of an impact it will have on performance
  2. Another idea is to add reverse output option under "Auto Output" and use LinkedHashMap in reverse order
  3. It would be better if you could set its priority via numeric keypad, but I feel the UI is too complicated

Diff:

I fixed the output order to the order of minecraft Direction Enum through my own local modification.
diff

commented

screenshots
I rewrote the UI selection method, let me know if you need it

  1. The default is switching mode, you can click to switch
  2. Added support for holding down the mouse to select multiple
  3. Below you can choose pencil to doodle directly
  4. Instead of using LinkedHashMap, use two variables. Support first or last
// RebornCore/src/main/java/reborncore/common/blockentity/SlotConfiguration.java
private void handleItemIO(MachineBaseBlockEntity machineBase) {
	if (!input && !output) {
		return;
	}
	if (first != null) {
		handleItemSideIo(machineBase, sideMap.get(first));
	}
	sideMap.forEach((key, config) -> {
		if (key == first || key == last) return;
		handleItemSideIo(machineBase, config);
	});
	if (last != null) {
		handleItemSideIo(machineBase, sideMap.get(last));
	}
}

private void handleItemSideIo(MachineBaseBlockEntity machineBase, SlotConfig config) {
	switch (config.getSlotIO().getIoConfig()) {
		case INPUT -> {
			if (input) config.handleItemInput(machineBase);
		}
		case OUTPUT -> {
			if (output) config.handleItemOutput(machineBase);
		}
	}
}