Skip to content

Commit

Permalink
Optimize MultiPart and ParallelHatch performance (#2684)
Browse files Browse the repository at this point in the history
  • Loading branch information
krossgg authored Jan 8, 2025
1 parent 085e73f commit 2472c9c
Show file tree
Hide file tree
Showing 16 changed files with 134 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.gregtechceu.gtceu.api.machine.feature.multiblock;

import com.gregtechceu.gtceu.api.capability.IParallelHatch;
import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine;
import com.gregtechceu.gtceu.api.machine.feature.IMachineFeature;
import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine;
Expand All @@ -21,6 +22,7 @@
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.locks.Lock;

/**
Expand Down Expand Up @@ -139,6 +141,15 @@ default BlockPattern getPattern() {
*/
List<IMultiPart> getParts();

/**
* The instance of {@link IParallelHatch} attached to this Controller.
* <p>
* Note that this will return a singular instance, and will not account for multiple attached IParallelHatches
*
* @return an {@link Optional} of the attached IParallelHatch, empty if one is not attached
*/
Optional<IParallelHatch> getParallelHatch();

/**
* Called from part, when part is invalid due to chunk unload or broken.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import net.minecraft.world.level.block.state.BlockState;

import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.List;
import java.util.SortedSet;

/**
* @author KilaBash
Expand All @@ -42,9 +44,12 @@ default boolean canShared() {
boolean isFormed();

/**
* Get all attached controllers
* Get this MultiPart's controllers
*
* @return An Unmodifiable View of the part's controllers
*/
List<IMultiController> getControllers();
@UnmodifiableView
SortedSet<IMultiController> getControllers();

/**
* Called when it was removed from a multiblock.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.block.IMachineBlock;
import com.gregtechceu.gtceu.api.block.MetaMachineBlock;
import com.gregtechceu.gtceu.api.capability.IParallelHatch;
import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity;
import com.gregtechceu.gtceu.api.machine.MetaMachine;
import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition;
Expand Down Expand Up @@ -31,10 +32,12 @@
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
Expand All @@ -54,6 +57,7 @@ public class MultiblockControllerMachine extends MetaMachine implements IMultiCo
MultiblockControllerMachine.class, MetaMachine.MANAGED_FIELD_HOLDER);
private MultiblockState multiblockState;
private final List<IMultiPart> parts = new ArrayList<>();
private @Nullable IParallelHatch parallelHatch = null;
@Getter
@DescSynced
@UpdateListener(methodName = "onPartsUpdated")
Expand Down Expand Up @@ -140,6 +144,11 @@ public List<IMultiPart> getParts() {
return this.parts;
}

@Override
public Optional<IParallelHatch> getParallelHatch() {
return Optional.ofNullable(parallelHatch);
}

//////////////////////////////////////
// *** Multiblock LifeCycle ***//
//////////////////////////////////////
Expand Down Expand Up @@ -178,6 +187,9 @@ public void onStructureFormed() {
}
this.parts.sort(getDefinition().getPartSorter());
for (var part : parts) {
if (part instanceof IParallelHatch pHatch) {
parallelHatch = pHatch;
}
part.addedToController(this);
}
updatePartPositions();
Expand All @@ -189,6 +201,7 @@ public void onStructureInvalid() {
for (IMultiPart part : parts) {
part.removedFromController(this);
}
parallelHatch = null;
parts.clear();
updatePartPositions();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.annotation.ParametersAreNonnullByDefault;

Expand Down Expand Up @@ -84,13 +83,10 @@ public void onPartUnload() {

@Override
public void addDisplayText(List<Component> textList) {
int numParallels = 0;
Optional<IParallelHatch> optional = this.getParts().stream().filter(IParallelHatch.class::isInstance)
.map(IParallelHatch.class::cast).findAny();
if (optional.isPresent()) {
IParallelHatch parallelHatch = optional.get();
numParallels = parallelHatch.getCurrentParallel();
}
int numParallels = this.getParallelHatch()
.map(IParallelHatch::getCurrentParallel)
.orElse(0);

MultiblockDisplayText.builder(textList, isFormed())
.setWorkingStatus(recipeLogic.isWorkingEnabled(), recipeLogic.isActive())
.addEnergyUsageLine(energyContainer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,21 @@

import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced;
import com.lowdragmc.lowdraglib.syncdata.annotation.RequireRerender;
import com.lowdragmc.lowdraglib.syncdata.annotation.UpdateListener;
import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder;

import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;

import java.util.ArrayList;
import java.util.HashSet;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

import javax.annotation.ParametersAreNonnullByDefault;

Expand All @@ -35,11 +40,12 @@ public class MultiblockPartMachine extends MetaMachine implements IMultiPart {

@DescSynced
@RequireRerender
protected final Set<BlockPos> controllerPositions;
@UpdateListener(methodName = "onControllersUpdated")
protected final Set<BlockPos> controllerPositions = new ObjectOpenHashSet<>(8);
protected final SortedSet<IMultiController> controllers = new ReferenceLinkedOpenHashSet<>(8);

public MultiblockPartMachine(IMachineBlockEntity holder) {
super(holder);
this.controllerPositions = new HashSet<>();
}

//////////////////////////////////////
Expand All @@ -61,35 +67,50 @@ public boolean isFormed() {
return !controllerPositions.isEmpty();
}

@Override
public List<IMultiController> getControllers() {
List<IMultiController> result = new ArrayList<>();
for (var blockPos : controllerPositions) {
// Not sure if necessary, but added to match the Controller class
@SuppressWarnings("unused")
public void onControllersUpdated(Set<BlockPos> newPositions, Set<BlockPos> old) {
controllers.clear();
for (BlockPos blockPos : newPositions) {
if (MetaMachine.getMachine(getLevel(), blockPos) instanceof IMultiController controller) {
result.add(controller);
controllers.add(controller);
}
}
return result;
}

@Override
@UnmodifiableView
public SortedSet<IMultiController> getControllers() {
// Necessary to rebuild the set of controllers on client-side
if (controllers.size() != controllerPositions.size()) {
onControllersUpdated(controllerPositions, Collections.emptySet());
}
return Collections.unmodifiableSortedSet(controllers);
}

@Override
public List<IRecipeHandlerTrait> getRecipeHandlers() {
return traits.stream().filter(IRecipeHandlerTrait.class::isInstance).map(IRecipeHandlerTrait.class::cast)
return traits.stream()
.filter(IRecipeHandlerTrait.class::isInstance)
.map(IRecipeHandlerTrait.class::cast)
.toList();
}

@Override
public void onUnload() {
super.onUnload();
var level = getLevel();
for (BlockPos pos : controllerPositions) {
if (level instanceof ServerLevel && level.isLoaded(pos) &&
MetaMachine.getMachine(level, pos) instanceof IMultiController controller) {
removedFromController(controller);
controller.onPartUnload();
if (getLevel() instanceof ServerLevel serverLevel) {
// Need to copy if > 1 so that we can call removedFromController safely without CME
Set<IMultiController> toIter = controllers.size() > 1 ? new ObjectOpenHashSet<>(controllers) : controllers;
for (IMultiController controller : toIter) {
if (serverLevel.isLoaded(controller.self().getPos())) {
removedFromController(controller);
controller.onPartUnload();
}
}
}
controllerPositions.clear();
controllers.clear();
}

//////////////////////////////////////
Expand All @@ -99,10 +120,12 @@ public void onUnload() {
@Override
public void removedFromController(IMultiController controller) {
controllerPositions.remove(controller.self().getPos());
controllers.remove(controller);
}

@Override
public void addedToController(IMultiController controller) {
controllerPositions.add(controller.self().getPos());
controllers.add(controller);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public int requestCWUt(int cwut, boolean simulate, @NotNull Collection<IOpticalC
if (machine instanceof IOpticalComputationProvider provider) {
return provider.requestCWUt(cwut, simulate, seen);
} else if (machine instanceof IMultiPart part) {
if (part.getControllers().isEmpty()) {
if (!part.isFormed()) {
return 0;
}
for (IMultiController controller : part.getControllers()) {
Expand Down Expand Up @@ -104,7 +104,7 @@ public int getMaxCWUt(@NotNull Collection<IOpticalComputationProvider> seen) {
if (machine instanceof IOpticalComputationProvider provider) {
return provider.getMaxCWUt(seen);
} else if (machine instanceof IMultiPart part) {
if (part.getControllers().isEmpty()) {
if (!part.isFormed()) {
return 0;
}
for (IMultiController controller : part.getControllers()) {
Expand Down Expand Up @@ -147,7 +147,7 @@ public boolean canBridge(@NotNull Collection<IOpticalComputationProvider> seen)
if (machine instanceof IOpticalComputationProvider provider) {
return provider.canBridge(seen);
} else if (machine instanceof IMultiPart part) {
if (part.getControllers().isEmpty()) {
if (!part.isFormed()) {
return false;
}
for (IMultiController controller : part.getControllers()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void renderMachine(List<BakedQuad> quads, MachineDefinition definition, @
super.renderMachine(quads, definition, machine, frontFacing, side, rand, modelFacing, modelState);
if (machine instanceof HPCAComponentPartMachine hpcaComponent) {
ResourceLocation texture, emissiveTexture = null;
var controller = hpcaComponent.getControllers().isEmpty() ? null : hpcaComponent.getControllers().get(0);
var controller = hpcaComponent.isFormed() ? hpcaComponent.getControllers().first() : null;
if (controller != null && (controller instanceof IWorkable workable && workable.isActive())) {
if (hpcaComponent.isDamaged()) {
texture = damagedActiveTexture;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void renderMachine(List<BakedQuad> quads, MachineDefinition definition, @
modelState));
if (machine instanceof IRotorHolderMachine rotorHolderMachine) {
var aabb = new AABB(-1, -1, -0.01, 2, 2, 1.01);
if (!rotorHolderMachine.getControllers().isEmpty()) {
if (rotorHolderMachine.isFormed()) {
quads.add(StaticFaceBakery.bakeFace(aabb, modelFacing, ModelFactory.getBlockSprite(BASE_RING),
modelState, -101, 0, true, false));
quads.add(StaticFaceBakery.bakeFace(aabb, modelFacing, ModelFactory.getBlockSprite(BASE_BG),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.gregtechceu.gtceu.common.data;

import com.gregtechceu.gtceu.api.GTValues;
import com.gregtechceu.gtceu.api.capability.IParallelHatch;
import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability;
import com.gregtechceu.gtceu.api.data.medicalcondition.MedicalCondition;
import com.gregtechceu.gtceu.api.machine.MetaMachine;
Expand Down Expand Up @@ -92,10 +91,7 @@ public class GTRecipeModifiers {
*/
public static @NotNull ModifierFunction hatchParallel(@NotNull MetaMachine machine, @NotNull GTRecipe recipe) {
if (machine instanceof IMultiController controller && controller.isFormed()) {
int parallels = controller.getParts().stream()
.filter(IParallelHatch.class::isInstance)
.map(IParallelHatch.class::cast)
.findAny()
int parallels = controller.getParallelHatch()
.map(hatch -> ParallelLogic.getParallelAmount(machine, recipe, hatch.getCurrentParallel()))
.orElse(1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,13 @@ protected NotifiableItemStackHandler createImportItemHandler() {
@Override
public void onContentsChanged() {
super.onContentsChanged();
rebuildData(!getControllers().isEmpty() && getControllers().get(0) instanceof DataBankMachine);
rebuildData(isFormed() && getControllers().first() instanceof DataBankMachine);
}

@NotNull
@Override
public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) {
var controller = DataAccessHatchMachine.this.getControllers().isEmpty() ? null :
DataAccessHatchMachine.this.getControllers().get(0);
boolean isDataBank = controller instanceof DataBankMachine;
boolean isDataBank = isFormed() && getControllers().first() instanceof DataBankMachine;
if (ResearchManager.isStackDataItem(stack, isDataBank) &&
ResearchManager.hasResearchTag(stack)) {
return super.insertItem(slot, stack, simulate);
Expand Down
Loading

0 comments on commit 2472c9c

Please sign in to comment.