Skip to content

Commit

Permalink
Merge pull request #640 from starforcraft/feat/GH-248/extstoragetests
Browse files Browse the repository at this point in the history
External Storage gametests
  • Loading branch information
raoulvdberge authored Sep 1, 2024
2 parents 25666be + 1de2aeb commit e689ccc
Show file tree
Hide file tree
Showing 10 changed files with 1,429 additions and 76 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.refinedmods.refinedstorage.common.storage.externalstorage;

import com.refinedmods.refinedstorage.api.network.impl.node.externalstorage.ExternalStorageNetworkNode;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;
import com.refinedmods.refinedstorage.api.resource.filter.FilterMode;
import com.refinedmods.refinedstorage.api.storage.AccessMode;
import com.refinedmods.refinedstorage.common.Platform;
import com.refinedmods.refinedstorage.common.api.RefinedStorageApi;
import com.refinedmods.refinedstorage.common.content.BlockEntities;
Expand All @@ -13,6 +16,7 @@
import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerData;
import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl;

import java.util.Set;
import javax.annotation.Nullable;

import net.minecraft.core.BlockPos;
Expand Down Expand Up @@ -145,6 +149,31 @@ public void readConfiguration(final CompoundTag tag, final HolderLookup.Provider
configContainer.load(tag);
}

void setFilters(final Set<ResourceKey> filters) {
mainNetworkNode.getStorageConfiguration().setFilters(filters);
}

void setFilterMode(final FilterMode mode) {
mainNetworkNode.getStorageConfiguration().setFilterMode(mode);
setChanged();
}

void setFuzzyMode(final boolean fuzzyMode) {
filter.setFuzzyMode(fuzzyMode);
}

void setAccessMode(final AccessMode accessMode) {
mainNetworkNode.getStorageConfiguration().setAccessMode(accessMode);
}

void setPriority(final int priority) {
mainNetworkNode.getStorageConfiguration().setPriority(priority);
}

void setVoidExcess(final boolean voidExcess) {
mainNetworkNode.getStorageConfiguration().setVoidExcess(voidExcess);
}

@Override
public ResourceContainerData getMenuData() {
return ResourceContainerData.of(filter.getFilterContainer());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
package com.refinedmods.refinedstorage.common.storage.externalstorage;

import com.google.common.util.concurrent.RateLimiter;

class ExternalStorageWorkRate {
private static final double[] RATE_LIMITERS = new double[] {
0.5D, // slowest, every 2 sec
0.75D, // faster
1D, // medium, every 1 sec
2D, // faster, every 0.5 sec
3D // fastest
private static final int[] OPERATION_COUNTS = new int[] {
40, // slowest, every 2 sec
30, // faster, every 1.5 sec
20, // medium, every 1 sec
10, // faster, every 0.5 sec
5 // fastest, every 0.25 sec
};

private int idx = 2; // medium
private final RateLimiter rateLimiter = RateLimiter.create(RATE_LIMITERS[idx]);
private int counter = 0;
private int threshold = OPERATION_COUNTS[idx];

boolean canDoWork() {
return rateLimiter.tryAcquire();
counter++;
if (counter >= threshold) {
counter = 0;
return true;
}
return false;
}

void faster() {
if (idx + 1 >= RATE_LIMITERS.length) {
return;
if (idx + 1 < OPERATION_COUNTS.length) {
idx++;
updateThreshold();
}
idx++;
updateRate();
}

void slower() {
if (idx - 1 < 0) {
return;
if (idx - 1 >= 0) {
idx--;
updateThreshold();
}
idx--;
updateRate();
}

private void updateRate() {
rateLimiter.setRate(RATE_LIMITERS[idx]);
private void updateThreshold() {
threshold = OPERATION_COUNTS[idx];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.util.UUID;
import javax.annotation.Nullable;

import com.google.common.util.concurrent.RateLimiter;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
Expand Down Expand Up @@ -46,10 +45,11 @@ public abstract class AbstractBaseNetworkNodeContainerBlockEntity<T extends Abst
private static final String TAG_CUSTOM_NAME = "CustomName";
private static final String TAG_PLACED_BY_PLAYER_ID = "pbpid";
private static final String TAG_REDSTONE_MODE = "rm";
private static final int ACTIVENESS_CHANGE_TICK_RATE = 20;

protected NetworkNodeTicker ticker = NetworkNodeTicker.IMMEDIATE;

private final RateLimiter activenessChangeRateLimiter = RateLimiter.create(1);
private int activenessChangeTicks;

@Nullable
private Component customName;
Expand Down Expand Up @@ -88,7 +88,7 @@ public void updateActiveness(final BlockState state, @Nullable final BooleanProp
final boolean blockStateActivenessNeedsUpdate = activenessProperty != null
&& state.getValue(activenessProperty) != newActive;
final boolean activenessNeedsUpdate = nodeActivenessNeedsUpdate || blockStateActivenessNeedsUpdate;
if (activenessNeedsUpdate && activenessChangeRateLimiter.tryAcquire()) {
if (activenessNeedsUpdate && activenessChangeTicks++ % ACTIVENESS_CHANGE_TICK_RATE == 0) {
if (nodeActivenessNeedsUpdate) {
activenessChanged(newActive);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer;
import com.refinedmods.refinedstorage.common.content.Blocks;
import com.refinedmods.refinedstorage.common.content.Items;
import com.refinedmods.refinedstorage.common.iface.ExportedResourcesContainer;
import com.refinedmods.refinedstorage.common.iface.InterfaceBlockEntity;
import com.refinedmods.refinedstorage.common.support.resource.FluidResource;
import com.refinedmods.refinedstorage.common.support.resource.ItemResource;
Expand Down Expand Up @@ -68,27 +69,99 @@ public static Runnable networkIsAvailable(final GameTestHelper helper,
};
}

public static void insert(final GameTestHelper helper,
final Network network,
final Item resource,
final long amount,
final boolean shouldSucceed) {
insert(helper, network, new ItemResource(resource), amount, shouldSucceed);
}

public static void insert(final GameTestHelper helper,
final Network network,
final Item resource,
final long amount) {
insert(helper, network, new ItemResource(resource), amount);
insert(helper, network, new ItemResource(resource), amount, true);
}

public static void insert(final GameTestHelper helper,
final Network network,
final Fluid resource,
final long amount,
final boolean shouldSucceed) {
insert(helper, network, new FluidResource(resource), amount, shouldSucceed);
}

public static void insert(final GameTestHelper helper,
final Network network,
final Fluid resource,
final long amount) {
insert(helper, network, new FluidResource(resource), amount);
insert(helper, network, new FluidResource(resource), amount, true);
}

public static void insert(final GameTestHelper helper,
final Network network,
final ResourceKey resource,
final long amount) {
insert(helper, network, resource, amount, true);
}

public static void insert(final GameTestHelper helper,
final Network network,
final ResourceKey resource,
final long amount,
final boolean shouldSucceed) {
final StorageNetworkComponent storage = network.getComponent(StorageNetworkComponent.class);
final long inserted = storage.insert(resource, amount, Action.EXECUTE, EmptyActor.INSTANCE);
helper.assertTrue(inserted == amount, "Resource couldn't be inserted");
if (shouldSucceed) {
helper.assertTrue(inserted == amount, "Resource couldn't be inserted");
} else {
helper.assertFalse(inserted == amount, "Resource could be inserted");
}
}

public static void extract(final GameTestHelper helper,
final Network network,
final Item resource,
final long amount,
final boolean shouldSucceed) {
extract(helper, network, new ItemResource(resource), amount, shouldSucceed);
}

public static void extract(final GameTestHelper helper,
final Network network,
final Item resource,
final long amount) {
extract(helper, network, new ItemResource(resource), amount, true);
}

public static void extract(final GameTestHelper helper,
final Network network,
final Fluid resource,
final long amount,
final boolean shouldSucceed) {
extract(helper, network, new FluidResource(resource), amount, shouldSucceed);
}

public static void extract(final GameTestHelper helper,
final Network network,
final Fluid resource,
final long amount) {
extract(helper, network, new FluidResource(resource), amount, true);
}

public static void extract(final GameTestHelper helper,
final Network network,
final ResourceKey resource,
final long amount,
final boolean shouldSucceed) {
final StorageNetworkComponent storage = network.getComponent(StorageNetworkComponent.class);
final long extracted = storage.extract(resource, amount, Action.EXECUTE, EmptyActor.INSTANCE);
if (shouldSucceed) {
helper.assertTrue(extracted == amount, "Resource couldn't be extracted");
} else {
helper.assertFalse(extracted == amount, "Resource could be extracted");
}
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -234,6 +307,83 @@ private static void listContainsExactly(final ResourceList given, final Resource
}
}

public static void prepareChest(final GameTestHelper helper,
final BlockPos pos,
final ItemStack... stacks) {
helper.setBlock(pos, net.minecraft.world.level.block.Blocks.CHEST.defaultBlockState());
final var chestBlockEntity = requireBlockEntity(helper, pos, BaseContainerBlockEntity.class);
for (int i = 0; i < stacks.length; i++) {
chestBlockEntity.setItem(i, stacks[i]);
}
}

public static void addItemToChest(final GameTestHelper helper,
final BlockPos pos,
final ItemStack stack) {
final var chestBlockEntity = requireBlockEntity(helper, pos, BaseContainerBlockEntity.class);
for (int i = 0; i < chestBlockEntity.getContainerSize(); i++) {
if (chestBlockEntity.getItem(i).isEmpty()) {
chestBlockEntity.setItem(i, stack);
return;
}
}
}

public static void removeItemFromChest(final GameTestHelper helper,
final BlockPos pos,
final ItemStack stack) {
final var chestBlockEntity = requireBlockEntity(helper, pos, BaseContainerBlockEntity.class);
for (int i = 0; i < chestBlockEntity.getContainerSize(); i++) {
if (chestBlockEntity.getItem(i).is(stack.getItem())) {
chestBlockEntity.removeItem(i, stack.getCount());
}
}
}

public static void prepareInterface(final GameTestHelper helper,
final BlockPos pos,
final ResourceAmount... resource) {
helper.setBlock(pos, RSBLOCKS.getInterface());
final var interfaceBlockEntity = requireBlockEntity(helper, pos, InterfaceBlockEntity.class);
final ExportedResourcesContainer exportedResources = interfaceBlockEntity.getExportedResources();

for (int i = 0; i < resource.length; i++) {
exportedResources.set(i, resource[i]);
}
}

public static void addFluidToInterface(final GameTestHelper helper,
final BlockPos pos,
final ResourceAmount resource) {
final var interfaceBlockEntity = requireBlockEntity(helper, pos, InterfaceBlockEntity.class);
final ExportedResourcesContainer exportedResources = interfaceBlockEntity.getExportedResources();

exportedResources.insert(resource.resource(), resource.amount(), Action.EXECUTE);
}

public static void removeFluidToInterface(final GameTestHelper helper,
final BlockPos pos,
final ResourceAmount resource) {
final var interfaceBlockEntity = requireBlockEntity(helper, pos, InterfaceBlockEntity.class);
final ExportedResourcesContainer exportedResources = interfaceBlockEntity.getExportedResources();

final long extracted = exportedResources.extract(resource.resource(), resource.amount(), Action.EXECUTE);

if (extracted <= 0) {
throw new GameTestAssertException(
"Resource " + resource.resource() + " with amount " + resource.amount() + " could not be extracted "
);
}
}

public static ItemStack[] createStacks(final Item item, final int count, final int amount) {
final ItemStack[] stacks = new ItemStack[amount];
for (int i = 0; i < amount; i++) {
stacks[i] = item.getDefaultInstance().copyWithCount(count);
}
return stacks;
}

public static ItemResource asResource(final Item item) {
return new ItemResource(item);
}
Expand All @@ -245,4 +395,9 @@ public static ItemResource asResource(final ItemStack itemStack) {
public static FluidResource asResource(final Fluid fluid) {
return new FluidResource(fluid);
}

public static ItemStack getItemAsDamaged(final ItemStack stack, final int damageValue) {
stack.setDamageValue(damageValue);
return stack;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.refinedmods.refinedstorage.common.GameTestUtil.RSITEMS;
import static com.refinedmods.refinedstorage.common.GameTestUtil.asResource;
import static com.refinedmods.refinedstorage.common.GameTestUtil.containerContainsExactly;
import static com.refinedmods.refinedstorage.common.GameTestUtil.getItemAsDamaged;
import static com.refinedmods.refinedstorage.common.GameTestUtil.insert;
import static com.refinedmods.refinedstorage.common.GameTestUtil.interfaceContainsExactly;
import static com.refinedmods.refinedstorage.common.GameTestUtil.networkIsAvailable;
Expand All @@ -38,8 +39,7 @@ private ExporterTest() {
public static void shouldExportItem(final GameTestHelper helper) {
ExporterTestPlots.preparePlot(helper, Blocks.CHEST, Direction.EAST, (exporter, pos, sequence) -> {
// Arrange
final ItemStack damagedDiamondChestplate = DIAMOND_CHESTPLATE.getDefaultInstance();
damagedDiamondChestplate.setDamageValue(500);
final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500);

sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> {
insert(helper, network, DIRT, 10);
Expand Down Expand Up @@ -116,8 +116,7 @@ public static void shouldExportItemWithStackUpgrade(final GameTestHelper helper)
public static void shouldExportItemFuzzy(final GameTestHelper helper) {
ExporterTestPlots.preparePlot(helper, Blocks.CHEST, Direction.EAST, (exporter, pos, sequence) -> {
// Arrange
final ItemStack damagedDiamondChestplate = DIAMOND_CHESTPLATE.getDefaultInstance();
damagedDiamondChestplate.setDamageValue(500);
final ItemStack damagedDiamondChestplate = getItemAsDamaged(DIAMOND_CHESTPLATE.getDefaultInstance(), 500);

sequence.thenWaitUntil(networkIsAvailable(helper, pos, network -> {
insert(helper, network, DIRT, 10);
Expand Down Expand Up @@ -202,10 +201,7 @@ public static void shouldExportFluidWithStackUpgrade(final GameTestHelper helper
.thenExecute(interfaceContainsExactly(
helper,
pos.east(),
new ResourceAmount(asResource(WATER), Platform.INSTANCE.getBucketAmount() * 16),
new ResourceAmount(asResource(WATER), Platform.INSTANCE.getBucketAmount() * 16),
new ResourceAmount(asResource(WATER), Platform.INSTANCE.getBucketAmount() * 16),
new ResourceAmount(asResource(WATER), Platform.INSTANCE.getBucketAmount() * 16)
new ResourceAmount(asResource(WATER), Platform.INSTANCE.getBucketAmount() * 64)
))

.thenSucceed();
Expand Down
Loading

0 comments on commit e689ccc

Please sign in to comment.