diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java
index cf16a836e..e0d539a1d 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java
@@ -9,8 +9,10 @@
import dan200.computercraft.api.upgrades.UpgradeData;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.ApiStatus;
import javax.annotation.Nullable;
@@ -21,6 +23,20 @@
*/
@ApiStatus.NonExtendable
public interface IPocketAccess {
+ /**
+ * Get the level in which the pocket computer exists.
+ *
+ * @return The pocket computer's level.
+ */
+ ServerLevel getLevel();
+
+ /**
+ * Get the position of the pocket computer.
+ *
+ * @return The pocket computer's position.
+ */
+ Vec3 getPosition();
+
/**
* Gets the entity holding this item.
*
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java
index 5348c1dab..33b5e8231 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java
@@ -16,8 +16,10 @@
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.phys.Vec3;
import javax.annotation.Nullable;
import java.util.Collections;
@@ -34,6 +36,7 @@ public final class PocketBrain implements IPocketAccess {
private final PocketServerComputer computer;
private PocketHolder holder;
+ private Vec3 position;
private boolean dirty = false;
private @Nullable UpgradeData upgrade;
@@ -43,6 +46,7 @@ public final class PocketBrain implements IPocketAccess {
public PocketBrain(PocketHolder holder, int computerID, @Nullable String label, ComputerFamily family, @Nullable UpgradeData upgrade) {
this.computer = new PocketServerComputer(this, holder, computerID, label, family);
this.holder = holder;
+ this.position = holder.pos();
this.upgrade = UpgradeData.copyOf(upgrade);
invalidatePeripheral();
}
@@ -66,6 +70,7 @@ PocketHolder holder() {
* @param newHolder The new holder
*/
public void updateHolder(PocketHolder newHolder) {
+ position = newHolder.pos();
computer.setPosition(newHolder.level(), newHolder.blockPos());
var oldHolder = this.holder;
@@ -94,6 +99,18 @@ public boolean updateItem(ItemStack stack) {
return true;
}
+ @Override
+ public ServerLevel getLevel() {
+ return computer.getLevel();
+ }
+
+ @Override
+ public Vec3 getPosition() {
+ // This method can be called from off-thread, and so we must use the cached position rather than rereading
+ // from the holder.
+ return position;
+ }
+
@Override
public @Nullable Entity getEntity() {
return holder instanceof PocketHolder.EntityHolder entity && holder.isValid(computer) ? entity.entity() : null;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketHolder.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketHolder.java
index 5e6187a56..16dc81a5d 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketHolder.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketHolder.java
@@ -11,6 +11,7 @@
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
+import net.minecraft.world.phys.Vec3;
/**
* An object that holds a pocket computer item.
@@ -23,6 +24,13 @@ public sealed interface PocketHolder permits PocketHolder.EntityHolder {
*/
ServerLevel level();
+ /**
+ * The position of this holder.
+ *
+ * @return The position of this holder.
+ */
+ Vec3 pos();
+
/**
* The block position of this holder.
*
@@ -59,6 +67,11 @@ default ServerLevel level() {
return (ServerLevel) entity().level();
}
+ @Override
+ default Vec3 pos() {
+ return entity().getEyePosition();
+ }
+
@Override
default BlockPos blockPos() {
return entity().blockPosition();
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java
index 273c5e8a4..6ab3469a0 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java
@@ -31,8 +31,6 @@ public IPeripheral createPeripheral(IPocketAccess access) {
public void update(IPocketAccess access, @Nullable IPeripheral peripheral) {
if (!(peripheral instanceof PocketModemPeripheral modem)) return;
- modem.setLocation(access);
-
var state = modem.getModemState();
if (state.pollChanged()) access.setLight(state.isOpen() ? 0xBA0000 : -1);
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java
index a55c7fa16..bd1d8b289 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java
@@ -14,31 +14,21 @@
import javax.annotation.Nullable;
public class PocketModemPeripheral extends WirelessModemPeripheral {
- private @Nullable Level level = null;
- private Vec3 position = Vec3.ZERO;
+ private final IPocketAccess access;
public PocketModemPeripheral(boolean advanced, IPocketAccess access) {
super(new ModemState(), advanced);
- setLocation(access);
- }
-
- void setLocation(IPocketAccess access) {
- var entity = access.getEntity();
- if (entity != null) {
- level = entity.level();
- position = entity.getEyePosition(1);
- }
+ this.access = access;
}
@Override
public Level getLevel() {
- if (level == null) throw new IllegalStateException("Using modem before position has been defined");
- return level;
+ return access.getLevel();
}
@Override
public Vec3 getPosition() {
- return position;
+ return access.getPosition();
}
@Override
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java
index 538790560..58a8df873 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java
@@ -8,15 +8,11 @@
import dan200.computercraft.api.pocket.IPocketAccess;
import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.phys.Vec3;
import javax.annotation.Nullable;
public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral {
private final IPocketAccess access;
- private @Nullable Level level;
- private Vec3 position = Vec3.ZERO;
public PocketSpeakerPeripheral(IPocketAccess access) {
this.access = access;
@@ -25,7 +21,7 @@ public PocketSpeakerPeripheral(IPocketAccess access) {
@Override
public SpeakerPosition getPosition() {
var entity = access.getEntity();
- return entity == null ? SpeakerPosition.of(level, position) : SpeakerPosition.of(entity);
+ return entity == null ? SpeakerPosition.of(access.getLevel(), access.getPosition()) : SpeakerPosition.of(entity);
}
@Override
@@ -35,12 +31,6 @@ public boolean equals(@Nullable IPeripheral other) {
@Override
public void update() {
- var entity = access.getEntity();
- if (entity != null) {
- level = entity.level();
- position = entity.position();
- }
-
super.update();
access.setLight(madeSound() ? 0x3320fc : -1);