Skip to content

Commit

Permalink
An attempt at fixing thread bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
StewStrong committed Sep 2, 2024
1 parent eac19c8 commit 4645958
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.valkyrienskies.core.api.ships.Ship;
import org.valkyrienskies.mod.common.BlockStateInfo;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.common.util.VSLevelChunk;

@Mixin(LevelChunk.class)
Expand Down Expand Up @@ -61,7 +62,10 @@ public MixinLevelChunk(final Ship ship) {
public void postSetBlockState(final BlockPos pos, final BlockState state, final boolean moved,
final CallbackInfoReturnable<BlockState> cir) {
final BlockState prevState = cir.getReturnValue();
BlockStateInfo.INSTANCE.onSetBlock(level, pos, prevState, state);
// This function is getting invoked by non-game threads for some reason. So use executeOrSchedule() to schedule
// onSetBlock() to be run on the next tick when this function is invoked by a non-game thread.
// See https://github.com/ValkyrienSkies/Valkyrien-Skies-2/issues/913 for more info.
VSGameUtilsKt.executeOrSchedule(level, () -> BlockStateInfo.INSTANCE.onSetBlock(level, pos, prevState, state));
}

@Shadow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.server.MinecraftServer
import net.minecraft.server.level.ServerChunkCache
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.thread.BlockableEventLoop
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.ChunkPos
Expand Down Expand Up @@ -408,6 +409,25 @@ fun Level.transformAabbToWorld(aabb: AABBdc, dest: AABBd): AABBd {
return dest.set(aabb)
}

/**
* Execute [runnable] immediately iff the thread invoking this is the same as the game thread.
* Otherwise, schedule [runnable] to run on the next tick.
*/
fun Level.executeOrSchedule(runnable: Runnable) {
val blockableEventLoop: BlockableEventLoop<Runnable> = if (!this.isClientSide) {
this.server!! as BlockableEventLoop<Runnable>
} else {
Minecraft.getInstance()
}
if (blockableEventLoop.isSameThread) {
// For some reason MinecraftServer wants to schedule even when it's the same thread, so we need to add our own
// logic
runnable.run()
} else {
blockableEventLoop.execute(runnable)
}
}

fun getShipMountedToData(passenger: Entity, partialTicks: Float? = null): ShipMountedToData? {
val vehicle = passenger.vehicle ?: return null
if (vehicle is ShipMountedToDataProvider) {
Expand Down

0 comments on commit 4645958

Please sign in to comment.