164 lines
5.6 KiB
Java
164 lines
5.6 KiB
Java
/* SPDX-License-Identifier: MIT */
|
|
|
|
package li.cil.oc2.common.bus;
|
|
|
|
import li.cil.oc2.api.bus.device.Device;
|
|
import li.cil.oc2.api.bus.device.ItemDevice;
|
|
import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
|
|
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
|
|
import li.cil.oc2.common.bus.device.provider.Providers;
|
|
import li.cil.oc2.common.bus.device.rpc.TypeNameRPCDevice;
|
|
import li.cil.oc2.common.bus.device.util.Devices;
|
|
import li.cil.oc2.common.bus.device.util.ItemDeviceInfo;
|
|
import li.cil.oc2.common.util.ItemDeviceUtils;
|
|
import li.cil.oc2.common.util.NBTTagIds;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraftforge.registries.IForgeRegistry;
|
|
|
|
import javax.annotation.Nullable;
|
|
import java.util.*;
|
|
|
|
import static li.cil.oc2.common.util.RegistryUtils.optionalKey;
|
|
|
|
public abstract class AbstractItemDeviceBusElement extends AbstractGroupingDeviceBusElement<AbstractItemDeviceBusElement.ItemEntry, ItemDeviceQuery> {
|
|
public AbstractItemDeviceBusElement(final int groupCount) {
|
|
super(groupCount);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
public boolean groupContains(final int groupIndex, final Device device) {
|
|
for (final ItemEntry entry : groups.get(groupIndex)) {
|
|
if (Objects.equals(entry.getDevice(), device)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void handleSlotContentsChanged(final int slot, final ItemStack stack) {
|
|
final ItemQueryResult queryResult = collectDevices(stack);
|
|
|
|
setEntriesForGroup(slot, queryResult);
|
|
}
|
|
|
|
public void exportDeviceDataToItemStack(final int slot, final ItemStack stack) {
|
|
if (stack.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
final CompoundTag exportedTag = new CompoundTag();
|
|
for (final ItemEntry entry : groups.get(slot)) {
|
|
entry.getDeviceDataKey().ifPresent(key -> {
|
|
final CompoundTag deviceTag = new CompoundTag();
|
|
entry.getDevice().exportToItemStack(deviceTag);
|
|
if (!deviceTag.isEmpty()) {
|
|
exportedTag.put(key, deviceTag);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (!exportedTag.isEmpty()) {
|
|
ItemDeviceUtils.setItemDeviceData(stack, exportedTag);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
protected abstract ItemDeviceQuery makeQuery(final ItemStack stack);
|
|
|
|
protected ItemQueryResult collectDevices(final ItemStack stack) {
|
|
final ItemDeviceQuery query = makeQuery(stack);
|
|
final HashSet<ItemEntry> entries = new HashSet<>();
|
|
|
|
for (final ItemDeviceInfo deviceInfo : Devices.getDevices(query)) {
|
|
entries.add(new ItemEntry(deviceInfo));
|
|
}
|
|
|
|
collectSyntheticDevices(query, entries);
|
|
|
|
importDeviceDataFromItemStack(query, entries);
|
|
|
|
return new ItemQueryResult(query, entries);
|
|
}
|
|
|
|
@SuppressWarnings("ConstantValue")
|
|
protected void collectSyntheticDevices(final ItemDeviceQuery query, final HashSet<ItemEntry> entries) {
|
|
if (entries.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
if (query.getItemStack().getDisplayName() != null) {
|
|
entries.add(new ItemEntry(new ItemDeviceInfo(null, new TypeNameRPCDevice(query.getItemStack().getDisplayName().toString()), 0)));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onEntryRemoved(final String dataKey, final CompoundTag tag, @Nullable final ItemDeviceQuery query) {
|
|
super.onEntryRemoved(dataKey, tag, query);
|
|
final IForgeRegistry<ItemDeviceProvider> registry = Providers.itemDeviceProviderRegistry();
|
|
final ItemDeviceProvider provider = registry.getValue(ResourceLocation.parse(dataKey));
|
|
if (provider != null) {
|
|
provider.unmount(query, tag);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
private void importDeviceDataFromItemStack(final ItemDeviceQuery query, final HashSet<ItemEntry> entries) {
|
|
final CompoundTag exportedTag = ItemDeviceUtils.getItemDeviceData(query.getItemStack());
|
|
if (!exportedTag.isEmpty()) {
|
|
for (final ItemEntry entry : entries) {
|
|
entry.getDeviceDataKey().ifPresent(key -> {
|
|
if (exportedTag.contains(key, NBTTagIds.TAG_COMPOUND)) {
|
|
entry.deviceInfo.device.importFromItemStack(exportedTag.getCompound(key));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
protected final class ItemQueryResult extends QueryResult {
|
|
@Nullable private final ItemDeviceQuery query;
|
|
private final Set<ItemEntry> entries;
|
|
|
|
public ItemQueryResult(@Nullable final ItemDeviceQuery query, final Set<ItemEntry> entries) {
|
|
this.query = query;
|
|
this.entries = entries;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public ItemDeviceQuery getQuery() {
|
|
return query;
|
|
}
|
|
|
|
@Override
|
|
public Set<ItemEntry> getEntries() {
|
|
return entries;
|
|
}
|
|
}
|
|
|
|
protected record ItemEntry(ItemDeviceInfo deviceInfo) implements Entry {
|
|
@Override
|
|
public Optional<String> getDeviceDataKey() {
|
|
return optionalKey(deviceInfo.provider);
|
|
}
|
|
|
|
@Override
|
|
public OptionalInt getDeviceEnergyConsumption() {
|
|
return OptionalInt.of(deviceInfo.getEnergyConsumption());
|
|
}
|
|
|
|
@Override
|
|
public ItemDevice getDevice() {
|
|
return deviceInfo.device;
|
|
}
|
|
}
|
|
}
|