mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-23 08:59:27 +00:00
Remove World Thread
This commit is contained in:
@@ -5,8 +5,6 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
|||||||
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
||||||
import net.momirealms.craftengine.bukkit.util.*;
|
import net.momirealms.craftengine.bukkit.util.*;
|
||||||
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
|
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
|
||||||
import net.momirealms.craftengine.bukkit.world.BukkitWorldManager;
|
|
||||||
import net.momirealms.craftengine.core.block.EmptyBlock;
|
|
||||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||||
import net.momirealms.craftengine.core.block.PushReaction;
|
import net.momirealms.craftengine.core.block.PushReaction;
|
||||||
import net.momirealms.craftengine.core.block.properties.Property;
|
import net.momirealms.craftengine.core.block.properties.Property;
|
||||||
@@ -18,7 +16,6 @@ import net.momirealms.craftengine.core.plugin.config.ConfigManager;
|
|||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
import net.momirealms.craftengine.core.util.context.ContextHolder;
|
import net.momirealms.craftengine.core.util.context.ContextHolder;
|
||||||
import net.momirealms.craftengine.core.world.BlockPos;
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
import net.momirealms.craftengine.core.world.CEWorld;
|
|
||||||
import net.momirealms.craftengine.core.world.Vec3d;
|
import net.momirealms.craftengine.core.world.Vec3d;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@@ -197,27 +194,25 @@ public class BlockEventListener implements Listener {
|
|||||||
handlePistonEvent(event.getDirection(), event.getBlocks(), event.getBlock());
|
handlePistonEvent(event.getDirection(), event.getBlocks(), event.getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo refactor this method
|
|
||||||
private void handlePistonEvent(BlockFace face, List<Block> blocksList, Block piston) {
|
private void handlePistonEvent(BlockFace face, List<Block> blocksList, Block piston) {
|
||||||
int blocks = blocksList.size();
|
int blocks = blocksList.size();
|
||||||
CEWorld world = BukkitWorldManager.instance().getWorld(piston.getWorld());
|
net.momirealms.craftengine.core.world.World world = new BukkitWorld(piston.getWorld());
|
||||||
for (int i = blocks - 1; i >= 0; --i) {
|
for (int i = blocks - 1; i >= 0; --i) {
|
||||||
Location oldLocation = blocksList.get(i).getLocation();
|
Location oldLocation = blocksList.get(i).getLocation();
|
||||||
BlockPos oldPos = new BlockPos(oldLocation.getBlockX(), oldLocation.getBlockY(), oldLocation.getBlockZ());
|
BlockPos oldPos = new BlockPos(oldLocation.getBlockX(), oldLocation.getBlockY(), oldLocation.getBlockZ());
|
||||||
ImmutableBlockState blockState = world.getBlockStateAtIfLoaded(oldPos);
|
Block block = blocksList.get(i);
|
||||||
if (blockState.pushReaction() == PushReaction.DESTROY) {
|
ImmutableBlockState blockState = manager.getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData()));
|
||||||
|
if (blockState != null && blockState.pushReaction() == PushReaction.DESTROY) {
|
||||||
// break actions
|
// break actions
|
||||||
ContextHolder.Builder builder = ContextHolder.builder();
|
ContextHolder.Builder builder = ContextHolder.builder();
|
||||||
Vec3d vec3d = Vec3d.atCenterOf(oldPos);
|
Vec3d vec3d = Vec3d.atCenterOf(oldPos);
|
||||||
builder.withParameter(LootParameters.LOCATION, vec3d);
|
builder.withParameter(LootParameters.LOCATION, vec3d);
|
||||||
builder.withParameter(LootParameters.WORLD, world.world());
|
builder.withParameter(LootParameters.WORLD, world);
|
||||||
for (Item<Object> item : blockState.getDrops(builder, world.world())) {
|
for (Item<Object> item : blockState.getDrops(builder, world)) {
|
||||||
world.world().dropItemNaturally(vec3d, item);
|
world.dropItemNaturally(vec3d, item);
|
||||||
}
|
}
|
||||||
world.world().playBlockSound(vec3d, blockState.sounds().breakSound(),1f, 1f);
|
world.playBlockSound(vec3d, blockState.sounds().breakSound(),1f, 1f);
|
||||||
}
|
}
|
||||||
// to prevent duplication in other events
|
|
||||||
world.setBlockStateAtIfLoaded(oldPos, EmptyBlock.INSTANCE.getDefaultState());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import java.util.Collections;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
public abstract class CEWorld {
|
public abstract class CEWorld {
|
||||||
@@ -20,7 +19,6 @@ public abstract class CEWorld {
|
|||||||
protected final Map<Long, CEChunk> loadedChunkMap;
|
protected final Map<Long, CEChunk> loadedChunkMap;
|
||||||
protected final WorldDataStorage worldDataStorage;
|
protected final WorldDataStorage worldDataStorage;
|
||||||
protected final ReentrantReadWriteLock loadedChunkMapLock = new ReentrantReadWriteLock();
|
protected final ReentrantReadWriteLock loadedChunkMapLock = new ReentrantReadWriteLock();
|
||||||
protected final WorldExecutor executor;
|
|
||||||
protected final WorldHeight worldHeightAccessor;
|
protected final WorldHeight worldHeightAccessor;
|
||||||
protected final Set<SectionPos> updatedSectionPositions = Collections.synchronizedSet(new HashSet<>());
|
protected final Set<SectionPos> updatedSectionPositions = Collections.synchronizedSet(new HashSet<>());
|
||||||
|
|
||||||
@@ -31,7 +29,6 @@ public abstract class CEWorld {
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
this.loadedChunkMap = new Long2ObjectOpenHashMap<>(1024, 0.5f);
|
this.loadedChunkMap = new Long2ObjectOpenHashMap<>(1024, 0.5f);
|
||||||
this.worldDataStorage = new DefaultRegionFileStorage(world.directory().resolve(REGION_DIRECTORY));
|
this.worldDataStorage = new DefaultRegionFileStorage(world.directory().resolve(REGION_DIRECTORY));
|
||||||
this.executor = new WorldExecutor(this);
|
|
||||||
this.worldHeightAccessor = world.worldHeight();
|
this.worldHeightAccessor = world.worldHeight();
|
||||||
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
|
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
|
||||||
}
|
}
|
||||||
@@ -73,9 +70,6 @@ public abstract class CEWorld {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public CEChunk getLoadedChunkImmediately(int x, int z) {
|
public CEChunk getLoadedChunkImmediately(int x, int z) {
|
||||||
if (WorldThread.isWorldThreadFor(this)) {
|
|
||||||
return this.getChunkAtIfLoadedWorldThread(x, z);
|
|
||||||
}
|
|
||||||
long longKey = ChunkPos.asLong(x, z);
|
long longKey = ChunkPos.asLong(x, z);
|
||||||
this.loadedChunkMapLock.readLock().lock();
|
this.loadedChunkMapLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
@@ -86,7 +80,7 @@ public abstract class CEWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public CEChunk getChunkAtIfLoadedWorldThread(long chunkPos) {
|
public CEChunk getChunkAtIfLoadedMainThread(long chunkPos) {
|
||||||
if (chunkPos == this.lastChunkPos) {
|
if (chunkPos == this.lastChunkPos) {
|
||||||
return this.lastChunk;
|
return this.lastChunk;
|
||||||
}
|
}
|
||||||
@@ -99,17 +93,14 @@ public abstract class CEWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public CEChunk getChunkAtIfLoadedWorldThread(int x, int z) {
|
public CEChunk getChunkAtIfLoadedMainThread(int x, int z) {
|
||||||
return getChunkAtIfLoadedWorldThread(ChunkPos.asLong(x, z));
|
return getChunkAtIfLoadedMainThread(ChunkPos.asLong(x, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public CEChunk getChunkAtIfLoaded(int x, int z) {
|
public CEChunk getChunkAtIfLoaded(int x, int z) {
|
||||||
if (!WorldThread.isWorldThreadFor(this)) {
|
|
||||||
return CompletableFuture.supplyAsync(() -> this.getChunkAtIfLoaded(x, z), this.executor).join();
|
|
||||||
}
|
|
||||||
long chunkPos = ChunkPos.asLong(x, z);
|
long chunkPos = ChunkPos.asLong(x, z);
|
||||||
return this.getChunkAtIfLoadedWorldThread(chunkPos);
|
return this.getChunkAtIfLoadedMainThread(chunkPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorldHeight worldHeight() {
|
public WorldHeight worldHeight() {
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package net.momirealms.craftengine.core.world;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
public class WorldExecutor implements Executor {
|
|
||||||
|
|
||||||
private final ExecutorService threadPool;
|
|
||||||
|
|
||||||
public WorldExecutor(CEWorld world) {
|
|
||||||
this.threadPool = Executors.newSingleThreadExecutor(r -> new WorldThread(r, "CEWorld-Thread-" + world.world().name(), world));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(@NotNull Runnable command) {
|
|
||||||
this.threadPool.execute(command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package net.momirealms.craftengine.core.world;
|
|
||||||
|
|
||||||
public class WorldThread extends Thread {
|
|
||||||
|
|
||||||
private final CEWorld world;
|
|
||||||
|
|
||||||
public WorldThread(Runnable target, String name, CEWorld world) {
|
|
||||||
super(target, name);
|
|
||||||
this.world = world;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isWorldThreadFor(CEWorld world) {
|
|
||||||
if (Thread.currentThread() instanceof WorldThread worldThread) {
|
|
||||||
return worldThread.world == world;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user