diff --git a/src/main/java/li/cil/oc2/api/bus/BlockDeviceBusElement.java b/src/main/java/li/cil/oc2/api/bus/BlockDeviceBusElement.java index 29129e3f..1a63060f 100644 --- a/src/main/java/li/cil/oc2/api/bus/BlockDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/api/bus/BlockDeviceBusElement.java @@ -3,7 +3,7 @@ package li.cil.oc2.api.bus; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.Level; import javax.annotation.Nullable; @@ -21,7 +21,7 @@ public interface BlockDeviceBusElement extends DeviceBusElement { * @return the level the bus lives in. */ @Nullable - LevelAccessor getLevel(); + Level getLevel(); /** * The position of this bus element. diff --git a/src/main/java/li/cil/oc2/api/bus/device/Device.java b/src/main/java/li/cil/oc2/api/bus/device/Device.java index c121a483..9375d659 100644 --- a/src/main/java/li/cil/oc2/api/bus/device/Device.java +++ b/src/main/java/li/cil/oc2/api/bus/device/Device.java @@ -8,6 +8,8 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraftforge.common.util.INBTSerializable; +import javax.annotation.Nullable; + /** * Base interface for objects that can be registered as devices on a {@link DeviceBus}. *

@@ -21,11 +23,39 @@ import net.minecraftforge.common.util.INBTSerializable; * detected. */ public interface Device extends INBTSerializable { + /** + * Called when the device is picked up by a {@link DeviceContainer}. + *

+ * This only means the device will be hosted by the specified container, it has no implication + * on whether the device is actually used by a computer, or whether that computer is running. + * + * @param container the container hosting this device. + */ + default void setDeviceContainer(@Nullable final DeviceContainer container) { + } + + /** + * Called to serialize this device into its container's persistent storage. + *

+ * When using this method, it may be necessary to call {@link DeviceContainer#setChanged()}, + * similar to how it is necessary to call {@link BlockEntity#setChanged()} when the serialized + * representation of it changed. Unless this is called, no guarantee is made this method will + * be called. + * + * @return the serialized state of this device. + */ @Override default CompoundTag serializeNBT() { return new CompoundTag(); } + /** + * Called to deserialize this device from its container's persistent storage. + *

+ * The passed tag will be what was last returned by {@link #serializeNBT()}. + * + * @param tag the serialized state of this device. + */ @Override default void deserializeNBT(final CompoundTag tag) { } diff --git a/src/main/java/li/cil/oc2/api/bus/device/DeviceContainer.java b/src/main/java/li/cil/oc2/api/bus/device/DeviceContainer.java new file mode 100644 index 00000000..be1bb97f --- /dev/null +++ b/src/main/java/li/cil/oc2/api/bus/device/DeviceContainer.java @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: MIT */ + +package li.cil.oc2.api.bus.device; + +import net.minecraft.world.level.block.entity.BlockEntity; + +/** + * Back-channel for devices to send messages to their containing context, such as Bus Interfaces. + */ +public interface DeviceContainer { + /** + * Notifies the container managing a device it is managing has changed. + *

+ * This should be called by devices when they need to be serialized. It is the equivalent of the + * {@link BlockEntity#setChanged()} method for {@link Device}s . + */ + void setChanged(); +} diff --git a/src/main/java/li/cil/oc2/common/bus/AbstractBlockDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/AbstractBlockDeviceBusElement.java index ffdef153..813cc392 100644 --- a/src/main/java/li/cil/oc2/common/bus/AbstractBlockDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/common/bus/AbstractBlockDeviceBusElement.java @@ -38,6 +38,17 @@ public abstract class AbstractBlockDeviceBusElement extends AbstractGroupingDevi super(Constants.BLOCK_FACE_COUNT); } + /////////////////////////////////////////////////////////////////// + // DeviceContainer + + @Override + public void setChanged() { + final Level level = getLevel(); + if (level != null) { + ChunkUtils.setLazyUnsaved(level, getPosition()); + } + } + /////////////////////////////////////////////////////////////////// // DeviceBusElement diff --git a/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java index 4369a3e8..01a26631 100644 --- a/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java @@ -3,6 +3,7 @@ package li.cil.oc2.common.bus; import li.cil.oc2.api.bus.device.Device; +import li.cil.oc2.api.bus.device.DeviceContainer; import li.cil.oc2.common.util.NBTTagIds; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; @@ -10,7 +11,7 @@ import net.minecraft.nbt.ListTag; import javax.annotation.Nullable; import java.util.*; -public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBusElement { +public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBusElement implements DeviceContainer { private static final String GROUPS_TAG_NAME = "groups"; private static final String GROUP_ID_TAG_NAME = "groupId"; private static final String GROUP_DATA_TAG_NAME = "groupData"; @@ -170,9 +171,11 @@ public abstract class AbstractGroupingDeviceBusElement