mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-25 09:59:20 +00:00
稍作优化
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package net.momirealms.craftengine.bukkit.world;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.injector.WorldStorageInjector;
|
||||
@@ -9,6 +8,7 @@ import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.util.ConcurrentUUID2ReferenceChainedHashTable;
|
||||
import net.momirealms.craftengine.core.world.CEWorld;
|
||||
import net.momirealms.craftengine.core.world.ChunkPos;
|
||||
import net.momirealms.craftengine.core.world.SectionPos;
|
||||
@@ -29,27 +29,21 @@ import org.bukkit.event.world.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class BukkitWorldManager implements WorldManager, Listener {
|
||||
private static BukkitWorldManager instance;
|
||||
private final BukkitCraftEngine plugin;
|
||||
private final Map<UUID, CEWorld> worlds;
|
||||
private CEWorld[] worldArray = new CEWorld[0];
|
||||
private final ReentrantReadWriteLock worldMapLock = new ReentrantReadWriteLock();
|
||||
// cache
|
||||
private UUID lastVisitedUUID;
|
||||
private CEWorld lastVisitedWorld;
|
||||
private final ConcurrentUUID2ReferenceChainedHashTable<CEWorld> worlds;
|
||||
private CEWorld[] worldArray;
|
||||
private StorageAdaptor storageAdaptor;
|
||||
private boolean initialized = false;
|
||||
|
||||
public BukkitWorldManager(BukkitCraftEngine plugin) {
|
||||
instance = this;
|
||||
this.plugin = plugin;
|
||||
this.worlds = new Object2ObjectOpenHashMap<>(32, 0.5f);
|
||||
this.worlds = ConcurrentUUID2ReferenceChainedHashTable.createWithCapacity(10, 0.5f);
|
||||
this.storageAdaptor = new DefaultStorageAdaptor();
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
this.worlds.put(world.getUID(), new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));
|
||||
@@ -71,20 +65,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
||||
|
||||
@Override
|
||||
public CEWorld getWorld(UUID uuid) {
|
||||
if (uuid.equals(this.lastVisitedUUID)) {
|
||||
return this.lastVisitedWorld;
|
||||
}
|
||||
this.worldMapLock.readLock().lock();
|
||||
try {
|
||||
CEWorld world = worlds.get(uuid);
|
||||
if (world != null) {
|
||||
this.lastVisitedUUID = uuid;
|
||||
this.lastVisitedWorld = world;
|
||||
}
|
||||
return world;
|
||||
} finally {
|
||||
this.worldMapLock.readLock().unlock();
|
||||
}
|
||||
return this.worlds.get(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,23 +79,18 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
||||
|
||||
public void delayedInit() {
|
||||
// load loaded chunks
|
||||
this.worldMapLock.writeLock().lock();
|
||||
try {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
try {
|
||||
CEWorld ceWorld = this.worlds.computeIfAbsent(world.getUID(), k -> new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
handleChunkLoad(ceWorld, chunk);
|
||||
}
|
||||
ceWorld.setTicking(true);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Error loading world: " + world.getName(), e);
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
try {
|
||||
CEWorld ceWorld = this.worlds.computeIfAbsent(world.getUID(), k -> new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
handleChunkLoad(ceWorld, chunk);
|
||||
}
|
||||
ceWorld.setTicking(true);
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Error loading world: " + world.getName(), e);
|
||||
}
|
||||
this.resetWorldArray();
|
||||
} finally {
|
||||
this.worldMapLock.writeLock().unlock();
|
||||
}
|
||||
this.resetWorldArray();
|
||||
Bukkit.getPluginManager().registerEvents(this, this.plugin.javaPlugin());
|
||||
this.initialized = true;
|
||||
}
|
||||
@@ -147,35 +123,25 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
||||
|
||||
@Override
|
||||
public void loadWorld(net.momirealms.craftengine.core.world.World world) {
|
||||
this.worldMapLock.writeLock().lock();
|
||||
try {
|
||||
if (this.worlds.containsKey(world.uuid())) return;
|
||||
CEWorld ceWorld = new BukkitCEWorld(world, this.storageAdaptor);
|
||||
this.worlds.put(world.uuid(), ceWorld);
|
||||
this.resetWorldArray();
|
||||
for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) {
|
||||
handleChunkLoad(ceWorld, chunk);
|
||||
}
|
||||
ceWorld.setTicking(true);
|
||||
} finally {
|
||||
this.worldMapLock.writeLock().unlock();
|
||||
if (this.worlds.containsKey(world.uuid())) return;
|
||||
CEWorld ceWorld = new BukkitCEWorld(world, this.storageAdaptor);
|
||||
this.worlds.put(world.uuid(), ceWorld);
|
||||
this.resetWorldArray();
|
||||
for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) {
|
||||
handleChunkLoad(ceWorld, chunk);
|
||||
}
|
||||
ceWorld.setTicking(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadWorld(CEWorld world) {
|
||||
this.worldMapLock.writeLock().lock();
|
||||
try {
|
||||
if (this.worlds.containsKey(world.world().uuid())) return;
|
||||
this.worlds.put(world.world().uuid(), world);
|
||||
this.resetWorldArray();
|
||||
for (Chunk chunk : ((World) world.world().platformWorld()).getLoadedChunks()) {
|
||||
handleChunkLoad(world, chunk);
|
||||
}
|
||||
world.setTicking(true);
|
||||
} finally {
|
||||
this.worldMapLock.writeLock().unlock();
|
||||
if (this.worlds.containsKey(world.world().uuid())) return;
|
||||
this.worlds.put(world.world().uuid(), world);
|
||||
this.resetWorldArray();
|
||||
for (Chunk chunk : ((World) world.world().platformWorld()).getLoadedChunks()) {
|
||||
handleChunkLoad(world, chunk);
|
||||
}
|
||||
world.setTicking(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -198,20 +164,11 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
||||
@Override
|
||||
public void unloadWorld(net.momirealms.craftengine.core.world.World world) {
|
||||
CEWorld ceWorld;
|
||||
this.worldMapLock.writeLock().lock();
|
||||
try {
|
||||
ceWorld = this.worlds.remove(world.uuid());
|
||||
if (ceWorld == null) {
|
||||
return;
|
||||
}
|
||||
if (ceWorld == this.lastVisitedWorld) {
|
||||
this.lastVisitedWorld = null;
|
||||
this.lastVisitedUUID = null;
|
||||
}
|
||||
this.resetWorldArray();
|
||||
} finally {
|
||||
this.worldMapLock.writeLock().unlock();
|
||||
ceWorld = this.worlds.remove(world.uuid());
|
||||
if (ceWorld == null) {
|
||||
return;
|
||||
}
|
||||
this.resetWorldArray();
|
||||
ceWorld.setTicking(false);
|
||||
for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) {
|
||||
handleChunkUnload(ceWorld, chunk);
|
||||
@@ -238,30 +195,18 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
this.worldMapLock.readLock().lock();
|
||||
CEWorld world;
|
||||
try {
|
||||
world = worlds.get(event.getWorld().getUID());
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
this.worldMapLock.readLock().unlock();
|
||||
CEWorld world = worlds.get(event.getWorld().getUID());
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
handleChunkLoad(world, event.getChunk());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onChunkUnload(ChunkUnloadEvent event) {
|
||||
CEWorld world;
|
||||
this.worldMapLock.readLock().lock();
|
||||
try {
|
||||
world = worlds.get(event.getWorld().getUID());
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
this.worldMapLock.readLock().unlock();
|
||||
CEWorld world = worlds.get(event.getWorld().getUID());
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
handleChunkUnload(world, event.getChunk());
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user