Skip to content

Commit

Permalink
refactor: chunk
Browse files Browse the repository at this point in the history
  • Loading branch information
smartcmd committed Sep 1, 2023
1 parent 9133376 commit 047016f
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public record FullContainerType<T extends Container>(int id, boolean canBeOpened
Set<ContainerSlotType> heldSlotTypes) {

public static final Map<ContainerSlotType, FullContainerType<? extends Container>> SLOT_TYPE_TO_TYPE_MAP = new EnumMap<>(ContainerSlotType.class);

public static final int UNKNOWN_NETWORK_ID = -1;

public static final FullContainerType<PlayerCursorContainer> CURSOR = builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public interface ChunkService extends ChunkAccessible {

CompletableFuture<Chunk> getOrLoadChunk(int x, int z);

CompletableFuture<Set<Chunk>> getOrLoadRangedChunk(int x, int z, int range);

CompletableFuture<Chunk> loadChunk(int x, int z);

@SlowOperation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import cn.allay.api.item.type.ItemTypeRegistry;
import cn.allay.api.math.location.Location3f;
import cn.allay.api.math.position.Position3ic;
import cn.allay.api.client.data.AdventureSettings;
import cn.allay.api.client.data.LoginData;
import cn.allay.api.server.Server;
import cn.allay.api.utils.MathUtils;
import cn.allay.api.world.biome.BiomeTypeRegistry;
Expand Down Expand Up @@ -202,13 +200,15 @@ public void initializePlayer() {
initPlayerEntity();
sendBasicGameData();
online = true;
if (playerEntity.getCurrentChunk() == null) {
getWorld().getChunkService().loadChunk(
(int) playerEntity.getLocation().x() >> 4,
(int) playerEntity.getLocation().z() >> 4
).join();
}
getWorld().addClient(this);
getWorld().getChunkService().getOrLoadChunk(
(int) playerEntity.getLocation().x() >> 4,
(int) playerEntity.getLocation().z() >> 4
).thenAcceptAsync((c) -> getWorld().addClient(this), Server.getInstance().getVirtualThreadPool()).exceptionally(
t -> {
log.error("Error while initialize player " + getName() + "!", t);
return null;
}
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,15 @@ public void removeEntity(Entity entity) {
@Override
public void addClient(Client client) {
clients.add(client);
addEntity(client.getPlayerEntity());
chunkService.addChunkLoader(client);
addEntity(client.getPlayerEntity());
}

@Override
public void removeClient(Client client) {
clients.remove(client);
removeEntity(client.getPlayerEntity());
chunkService.removeChunkLoader(client);
clients.remove(client);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.cloudburstmc.protocol.bedrock.data.SubChunkData;
import org.cloudburstmc.protocol.bedrock.data.SubChunkRequestResult;
import org.cloudburstmc.protocol.bedrock.packet.SubChunkPacket;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnmodifiableView;
import org.joml.Vector3i;
Expand All @@ -34,6 +33,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
* Allay Project 2023/7/1
Expand Down Expand Up @@ -186,7 +186,8 @@ public void addChunkLoader(ChunkLoader chunkLoader) {

@Override
public void removeChunkLoader(ChunkLoader chunkLoader) {
this.chunkLoaderManagers.remove(chunkLoader).onRemoved();
var removed = this.chunkLoaderManagers.remove(chunkLoader);
if (removed != null) removed.onRemoved();
}

@Override
Expand All @@ -203,6 +204,29 @@ public CompletableFuture<Chunk> getOrLoadChunk(int x, int z) {
return loadChunk(x, z);
}

@Override
public CompletableFuture<Set<Chunk>> getOrLoadRangedChunk(int x, int z, int range) {
// 用于存储CompletableFuture的集合
Set<CompletableFuture<Chunk>> futureSet = new HashSet<>();

// 遍历(x, z)为中心,半径为range的区块
for (int dx = -range; dx <= range; dx++) {
for (int dz = -range; dz <= range; dz++) {
if (dx * dx + dz * dz <= range * range) {
// 获取或加载每一个块,并将返回的CompletableFuture添加到集合中
futureSet.add(getOrLoadChunk(x + dx, z + dz));
}
}
}

// 当所有的CompletableFuture都完成时,返回一个新的CompletableFuture
return CompletableFuture.allOf(futureSet.toArray(new CompletableFuture[0]))
.thenApplyAsync(v -> futureSet.stream()
.map(CompletableFuture::join)
.collect(Collectors.toSet()), Server.getInstance().getVirtualThreadPool());
}


@Override
public CompletableFuture<Chunk> loadChunk(int x, int z) {
var hashXZ = HashUtils.hashXZ(x, z);
Expand All @@ -213,26 +237,31 @@ public CompletableFuture<Chunk> loadChunk(int x, int z) {
if (loadingChunk != null) {
return loadingChunk;
}
var future = worldStorage.readChunk(x, z);
var future = worldStorage.readChunk(x, z).exceptionally(t -> {
log.error("Error while reading chunk (" + x + "," + z + ") !", t);
return null;
}).thenApplyAsync(loadedChunk -> generateChunkIfNullAndSetChunk(x, z, loadedChunk), Server.getInstance().getComputeThreadPool()).exceptionally(t -> {
log.error("Error while generating chunk (" + x + "," + z + ") !", t);
return null;
});
loadingChunks.put(hashXZ, future);
future.thenApplyAsync(loadedChunk -> generateChunkIfNull(x, z, loadedChunk), Server.getInstance().getComputeThreadPool());
return future;
}

@SneakyThrows
@SlowOperation
@Override
public Chunk loadChunkImmediately(int x, int z) {
if (isChunkLoaded(x, z)) {
throw new IllegalStateException("Chunk is already loaded");
if (isChunkLoaded(x, z) || isChunkLoading(x, z)) {
throw new IllegalStateException("Chunk is already loaded or under loading");
}
return generateChunkIfNull(
return generateChunkIfNullAndSetChunk(
x, z,
worldStorage.readChunk(x, z).get()
);
}

private Chunk generateChunkIfNull(int x, int z, Chunk loadedChunk) {
private Chunk generateChunkIfNullAndSetChunk(int x, int z, Chunk loadedChunk) {
long hashXZ = HashUtils.hashXZ(x, z);
if (loadedChunk == null) {
loadedChunk = generateChunkImmediately(x, z);
Expand Down

0 comments on commit 047016f

Please sign in to comment.