Merge pull request #454 from RinesThaix/anvilBlockHandler

Block handlers improvements
This commit is contained in:
TheMode 2021-09-10 18:11:20 +02:00 committed by GitHub
commit f77ccfa342
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 13 deletions

View File

@ -139,8 +139,12 @@ public class AnvilLoader implements IChunkLoader {
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) { for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
try { try {
final BlockState blockState = section.get(x, y, z); final BlockState blockState = section.get(x, y, z);
final Block block = Objects.requireNonNull(Block.fromNamespaceId(blockState.getName())) Block block = Objects.requireNonNull(Block.fromNamespaceId(blockState.getName()))
.withProperties(blockState.getProperties()); .withProperties(blockState.getProperties());
BlockHandler handler = MinecraftServer.getBlockManager().getHandler(block.name());
if (handler != null) {
block = block.withHandler(handler);
}
chunk.setBlock(x, y + yOffset, z, block); chunk.setBlock(x, y + yOffset, z, block);
} catch (Exception e) { } catch (Exception e) {
EXCEPTION_MANAGER.handleException(e); EXCEPTION_MANAGER.handleException(e);

View File

@ -295,23 +295,23 @@ public interface BlockHandler {
* Handler used for loaded blocks with unknown namespace * Handler used for loaded blocks with unknown namespace
* in order to do not lose the information while saving, and for runtime debugging purpose. * in order to do not lose the information while saving, and for runtime debugging purpose.
*/ */
class Dummy implements BlockHandler { @ApiStatus.Internal
final class Dummy implements BlockHandler {
private static final Map<String, BlockHandler> DUMMY_CACHE = new ConcurrentHashMap<>(); private static final Map<String, BlockHandler> DUMMY_CACHE = new ConcurrentHashMap<>();
@ApiStatus.Internal
public static @NotNull BlockHandler get(@NotNull String namespace) { public static @NotNull BlockHandler get(@NotNull String namespace) {
return DUMMY_CACHE.computeIfAbsent(namespace, s -> new Dummy(NamespaceID.from(namespace))); return DUMMY_CACHE.computeIfAbsent(namespace, Dummy::new);
} }
private final NamespaceID namespaceID; private final NamespaceID namespace;
private Dummy(NamespaceID namespaceID) { private Dummy(String name) {
this.namespaceID = namespaceID; namespace = NamespaceID.from(name);
} }
@Override @Override
public @NotNull NamespaceID getNamespaceId() { public @NotNull NamespaceID getNamespaceId() {
return namespaceID; return namespace;
} }
} }
} }

View File

@ -3,6 +3,7 @@ package net.minestom.server.instance.block;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minestom.server.instance.block.rule.BlockPlacementRule; import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -23,17 +24,21 @@ public class BlockManager {
// block id -> block placement rule // block id -> block placement rule
private final Int2ObjectMap<BlockPlacementRule> placementRuleMap = new Int2ObjectOpenHashMap<>(); private final Int2ObjectMap<BlockPlacementRule> placementRuleMap = new Int2ObjectOpenHashMap<>();
public synchronized void registerHandler(@NotNull String namespace, @NotNull Supplier<@NotNull BlockHandler> handlerSupplier) { public void registerHandler(@NotNull String namespace, @NotNull Supplier<@NotNull BlockHandler> handlerSupplier) {
this.blockHandlerMap.put(namespace, handlerSupplier); blockHandlerMap.put(namespace, handlerSupplier);
} }
public synchronized @Nullable BlockHandler getHandler(@NotNull String namespace) { public void registerHandler(@NotNull NamespaceID namespace, @NotNull Supplier<@NotNull BlockHandler> handlerSupplier) {
registerHandler(namespace.toString(), handlerSupplier);
}
public @Nullable BlockHandler getHandler(@NotNull String namespace) {
final var handler = blockHandlerMap.get(namespace); final var handler = blockHandlerMap.get(namespace);
return handler != null ? handler.get() : null; return handler != null ? handler.get() : null;
} }
@ApiStatus.Internal @ApiStatus.Internal
public synchronized @Nullable BlockHandler getHandlerOrDummy(@NotNull String namespace) { public @NotNull BlockHandler getHandlerOrDummy(@NotNull String namespace) {
BlockHandler handler = getHandler(namespace); BlockHandler handler = getHandler(namespace);
if (handler == null) { if (handler == null) {
LOGGER.warn("Block {} does not have any corresponding handler, default to dummy.", namespace); LOGGER.warn("Block {} does not have any corresponding handler, default to dummy.", namespace);
@ -51,7 +56,7 @@ public class BlockManager {
public synchronized void registerBlockPlacementRule(@NotNull BlockPlacementRule blockPlacementRule) { public synchronized void registerBlockPlacementRule(@NotNull BlockPlacementRule blockPlacementRule) {
final int id = blockPlacementRule.getBlock().id(); final int id = blockPlacementRule.getBlock().id();
Check.argCondition(id < 0, "Block ID must be >= 0, got: " + id); Check.argCondition(id < 0, "Block ID must be >= 0, got: " + id);
this.placementRuleMap.put(id, blockPlacementRule); placementRuleMap.put(id, blockPlacementRule);
} }
/** /**