From a6a33c2341024b0cb632286cc31b13177db35503 Mon Sep 17 00:00:00 2001 From: Up Date: Tue, 31 Dec 2024 16:35:28 +0100 Subject: [PATCH] add test cases --- .../block/StaticBlockComponentPlugin.java | 11 +++-- .../cca/test/block/CcaBlockTestMod.java | 6 +-- .../cca/test/block/CcaBlockTestSuite.java | 45 ++++++++++++++++- .../test/block/GlobalTickingComponent.java | 48 +++++++++++++++++++ .../src/testmod/resources/fabric.mod.json | 3 +- 5 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/GlobalTickingComponent.java diff --git a/cardinal-components-block/src/main/java/dev/onyxstudios/cca/internal/block/StaticBlockComponentPlugin.java b/cardinal-components-block/src/main/java/dev/onyxstudios/cca/internal/block/StaticBlockComponentPlugin.java index ed7ed6af..7f832f96 100644 --- a/cardinal-components-block/src/main/java/dev/onyxstudios/cca/internal/block/StaticBlockComponentPlugin.java +++ b/cardinal-components-block/src/main/java/dev/onyxstudios/cca/internal/block/StaticBlockComponentPlugin.java @@ -40,6 +40,7 @@ import net.minecraft.block.entity.BlockEntityTicker; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.Collections; @@ -63,8 +64,10 @@ private StaticBlockComponentPlugin() { private final List> dynamicFactories = new ArrayList<>(); private final Map, Map, QualifiedComponentFactory>>> beComponentFactories = new Reference2ObjectOpenHashMap<>(); - private final Set> clientTicking = new ReferenceOpenHashSet<>(); - private final Set> serverTicking = new ReferenceOpenHashSet<>(); + @VisibleForTesting + public final Set> clientTicking = new ReferenceOpenHashSet<>(); + @VisibleForTesting + public final Set> serverTicking = new ReferenceOpenHashSet<>(); @Nullable public BlockEntityTicker getComponentTicker(World world, T be, @Nullable BlockEntityTicker base) { @@ -97,12 +100,12 @@ public boolean requiresStaticFactory(Class entityClass) { public ComponentContainer.Factory buildDedicatedFactory(Class entityClass) { StaticBlockComponentPlugin.INSTANCE.ensureInitialized(); - var compiled = new LinkedHashMap<>(this.beComponentFactories.getOrDefault(entityClass, Collections.emptyMap())); + var compiled = new LinkedHashMap<>(this.beComponentFactories.getOrDefault(entityClass, Map.of())); Class type = entityClass; while (type != BlockEntity.class) { type = type.getSuperclass().asSubclass(BlockEntity.class); - for (var e : this.beComponentFactories.getOrDefault(type, Collections.emptyMap()).entrySet()) { + for (var e : this.beComponentFactories.getOrDefault(type, Map.of()).entrySet()) { compiled.putIfAbsent(e.getKey(), e.getValue()); } } diff --git a/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/CcaBlockTestMod.java b/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/CcaBlockTestMod.java index 5fca1c0f..8cf4cd58 100644 --- a/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/CcaBlockTestMod.java +++ b/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/CcaBlockTestMod.java @@ -30,10 +30,7 @@ import dev.onyxstudios.cca.test.base.Vita; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.block.entity.CommandBlockBlockEntity; -import net.minecraft.block.entity.EndGatewayBlockEntity; -import net.minecraft.block.entity.EndPortalBlockEntity; +import net.minecraft.block.entity.*; import net.minecraft.util.Identifier; import net.minecraft.util.math.Direction; @@ -46,6 +43,7 @@ public void registerBlockComponentFactories(BlockComponentFactoryRegistry regist registry.registerFor(EndGatewayBlockEntity.class, VitaCompound.KEY, VitaCompound::new); registry.registerFor(EndPortalBlockEntity.class, TickingTestComponent.KEY, be -> new TickingTestComponent()); registry.registerFor(CommandBlockBlockEntity.class, LoadAwareTestComponent.KEY, be -> new LoadAwareTestComponent()); + registry.registerFor(BlockEntity.class, GlobalTickingComponent.KEY, GlobalTickingComponent::new); } @Override diff --git a/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/CcaBlockTestSuite.java b/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/CcaBlockTestSuite.java index 458efafd..d144170e 100644 --- a/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/CcaBlockTestSuite.java +++ b/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/CcaBlockTestSuite.java @@ -22,6 +22,7 @@ */ package dev.onyxstudios.cca.test.block; +import dev.onyxstudios.cca.internal.block.StaticBlockComponentPlugin; import dev.onyxstudios.cca.test.base.LoadAwareTestComponent; import dev.onyxstudios.cca.test.base.TickingTestComponent; import dev.onyxstudios.cca.test.base.Vita; @@ -39,6 +40,8 @@ import org.jetbrains.annotations.NotNull; import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BooleanSupplier; public class CcaBlockTestSuite implements FabricGameTest { @GameTest(templateName = EMPTY_STRUCTURE) @@ -92,8 +95,17 @@ public void canQueryThroughLookup(TestContext ctx) { @GameTest(templateName = EMPTY_STRUCTURE) public void beComponentsTick(TestContext ctx) { ctx.setBlockState(BlockPos.ORIGIN, Blocks.END_PORTAL); + + var blockentity = ctx.getBlockEntity(BlockPos.ORIGIN); + GameTestUtil.assertTrue("Block entity should not be null", blockentity != null); + GameTestUtil.assertTrue("BlockEntity should have TickingTestComponent", TickingTestComponent.KEY.getNullable(blockentity) != null); + GameTestUtil.assertTrue("Class should be registered as server ticker", StaticBlockComponentPlugin.INSTANCE.serverTicking.contains(blockentity.getClass())); + GameTestUtil.assertTrue("Class should be registered as client ticker", StaticBlockComponentPlugin.INSTANCE.clientTicking.contains(blockentity.getClass())); + ctx.waitAndRun(5, () -> { - int ticks = Objects.requireNonNull(ctx.getBlockEntity(BlockPos.ORIGIN)).getComponent(TickingTestComponent.KEY).serverTicks(); + var blockentity2 = ctx.getBlockEntity(BlockPos.ORIGIN); + GameTestUtil.assertTrue("Block entity should still exist", blockentity2 != null); + int ticks = blockentity2.getComponent(TickingTestComponent.KEY).serverTicks(); GameTestUtil.assertTrue("Component should tick 5 times", ticks == 5); ctx.complete(); }); @@ -121,4 +133,35 @@ public void beComponentsLoadUnload(TestContext ctx) { ctx.complete(); }); } + + @GameTest(templateName = EMPTY_STRUCTURE) + public void rootClassServerTicker(TestContext ctx) { + ctx.setBlockState(BlockPos.ORIGIN, Blocks.BARREL); + + var blockentity = ctx.getBlockEntity(BlockPos.ORIGIN); + GameTestUtil.assertTrue("Block entity should not be null", blockentity != null); + + GameTestUtil.assertTrue("Class should be registered as server ticker", StaticBlockComponentPlugin.INSTANCE.serverTicking.contains(blockentity.getClass())); + GameTestUtil.assertFalse("Class should NOT be registered as client ticker", StaticBlockComponentPlugin.INSTANCE.clientTicking.contains(blockentity.getClass())); + + var component = GlobalTickingComponent.KEY.getNullable(blockentity); + GameTestUtil.assertTrue("Component should exist", component != null); + + AtomicInteger flag = new AtomicInteger(0); + BooleanSupplier action = () -> { + flag.getAndIncrement(); + return false; + }; + component.setTickAction(action); + GameTestUtil.assertTrue("Tick action should be set", component.getTickAction().isPresent()); + + ctx.waitAndRun(5, () -> { + var blockentity2 = ctx.getBlockEntity(BlockPos.ORIGIN); + GameTestUtil.assertTrue("Block entity should still exist", blockentity2 != null); + GameTestUtil.assertTrue("Tick action should be cleared", blockentity2.getComponent(GlobalTickingComponent.KEY).getTickAction().isEmpty()); + GameTestUtil.assertTrue("Tick action should have run exactly once", flag.get() == 1); + + ctx.complete(); + }); + } } diff --git a/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/GlobalTickingComponent.java b/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/GlobalTickingComponent.java new file mode 100644 index 00000000..43b6b53b --- /dev/null +++ b/cardinal-components-block/src/testmod/java/dev/onyxstudios/cca/test/block/GlobalTickingComponent.java @@ -0,0 +1,48 @@ +package dev.onyxstudios.cca.test.block; + +import dev.onyxstudios.cca.api.v3.component.Component; +import dev.onyxstudios.cca.api.v3.component.ComponentKey; +import dev.onyxstudios.cca.api.v3.component.ComponentRegistry; +import dev.onyxstudios.cca.api.v3.component.tick.ServerTickingComponent; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.function.BooleanSupplier; + +public class GlobalTickingComponent implements Component, ServerTickingComponent { + + public static final ComponentKey KEY = ComponentRegistry.getOrCreate(new Identifier(CcaBlockTestMod.MOD_ID, "global_ticking_test"), GlobalTickingComponent.class); + + public GlobalTickingComponent(Object provider) { + // NO-OP + } + + @Nullable + private BooleanSupplier onTick; + + void setTickAction(@Nullable BooleanSupplier onTick) { + this.onTick = onTick; + } + + @Override public void serverTick() { + if(this.onTick != null) { + if(!this.onTick.getAsBoolean()) { + this.onTick = null; + } + } + } + + public Optional getTickAction() { + return Optional.ofNullable(this.onTick); + } + + @Override public void readFromNbt(NbtCompound tag) { + // NO-OP + } + + @Override public void writeToNbt(NbtCompound tag) { + // NO-OP + } +} diff --git a/cardinal-components-block/src/testmod/resources/fabric.mod.json b/cardinal-components-block/src/testmod/resources/fabric.mod.json index 4190d2a1..ed7fdf14 100644 --- a/cardinal-components-block/src/testmod/resources/fabric.mod.json +++ b/cardinal-components-block/src/testmod/resources/fabric.mod.json @@ -25,7 +25,8 @@ "license": "MIT", "custom": { "cardinal-components": [ - "cca-block-test:vita_compound" + "cca-block-test:vita_compound", + "cca-block-test:global_ticking_test" ] } }