Skip to content

Commit cb2eb9e

Browse files
committed
Deserialize terminal packets off-thread
Related to CyclopsMC/IntegratedCrafting#156
1 parent b6873e0 commit cb2eb9e

4 files changed

Lines changed: 59 additions & 44 deletions

File tree

src/main/java/org/cyclops/integratedterminals/GeneralConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public class GeneralConfig extends DummyConfig {
5656
public static boolean craftingPlannerEnableMultithreading = false;
5757
@ConfigurableProperty(category = "core", comment = "If client-directed packets should be serialized in a separate thread.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
5858
public static boolean packetSerializationEnableMultithreading = true;
59+
@ConfigurableProperty(category = "core", comment = "If client-received packets should be deserialized in a separate thread.", isCommandable = true, configLocation = ModConfig.Type.CLIENT)
60+
public static boolean packetDeserializationEnableMultithreading = true;
5961

6062
@ConfigurableProperty(category = "general", comment = "The base energy usage for the crafting terminal.", minimalValue = 0, configLocation = ModConfig.Type.SERVER)
6163
public static int terminalCraftingBaseConsumption = 1;

src/main/java/org/cyclops/integratedterminals/core/terminalstorage/TerminalStorageTabIngredientComponentServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ private void sendCraftingOptionsToClient(int channel, Collection<HandlerWrappedT
384384
// Only allow collection of a max given size to be sent in a packet
385385
if (channeledCraftingOptions.size() <= GeneralConfig.terminalStoragePacketMaxRecipes) {
386386
IntegratedTerminals._instance.getPacketHandler().sendToPlayer(
387-
new TerminalStorageIngredientCraftingOptionsPacket(this.getName().toString(), channel, channeledCraftingOptions, reset, firstChannel), player);
387+
new TerminalStorageIngredientCraftingOptionsPacket(this.getName().toString(), channel, channeledCraftingOptions, reset, firstChannel, ingredientComponent), player);
388388
} else {
389389
List<Pair<Boolean, List<HandlerWrappedTerminalCraftingOption<T>>>> chunks = Lists.newArrayList();
390390
List<HandlerWrappedTerminalCraftingOption<T>> buffer = Lists.newArrayListWithExpectedSize(GeneralConfig.terminalStoragePacketMaxRecipes);

src/main/java/org/cyclops/integratedterminals/network/packet/TerminalStorageIngredientChangeEventPacket.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.cyclops.integratedterminals.network.packet;
22

3+
import net.minecraft.client.Minecraft;
34
import net.minecraft.world.entity.player.Player;
45
import net.minecraft.server.level.ServerPlayer;
56
import net.minecraft.nbt.CompoundTag;
@@ -13,6 +14,7 @@
1314
import org.cyclops.cyclopscore.network.CodecField;
1415
import org.cyclops.cyclopscore.network.PacketCodec;
1516
import org.cyclops.integrateddynamics.api.ingredient.IIngredientComponentStorageObservable;
17+
import org.cyclops.integratedterminals.GeneralConfig;
1618
import org.cyclops.integratedterminals.core.terminalstorage.TerminalStorageTabIngredientComponentClient;
1719
import org.cyclops.integratedterminals.core.terminalstorage.TerminalStorageTabIngredientComponentItemStackCrafting;
1820
import org.cyclops.integratedterminals.inventory.container.ContainerTerminalStorageBase;
@@ -52,30 +54,32 @@ public TerminalStorageIngredientChangeEventPacket(String tabId,
5254

5355
@Override
5456
public boolean isAsync() {
55-
return false;
57+
return GeneralConfig.packetDeserializationEnableMultithreading;
5658
}
5759

5860
@Override
5961
@OnlyIn(Dist.CLIENT)
6062
public void actionClient(Level world, Player player) {
61-
if(player.containerMenu instanceof ContainerTerminalStorageBase) {
62-
ContainerTerminalStorageBase container = ((ContainerTerminalStorageBase) player.containerMenu);
63-
IIngredientComponentStorageObservable.Change changeType = IIngredientComponentStorageObservable.Change.values()[changeData.getInt("changeType")];
64-
IngredientArrayList ingredients = IngredientCollections.deserialize(changeData);
63+
IIngredientComponentStorageObservable.Change changeType = IIngredientComponentStorageObservable.Change.values()[changeData.getInt("changeType")];
64+
IngredientArrayList ingredients = IngredientCollections.deserialize(changeData);
6565

66-
TerminalStorageTabIngredientComponentClient<?, ?> tab = (TerminalStorageTabIngredientComponentClient<?, ?>) container.getTabClient(tabId);
67-
tab.onChange(channel, changeType, ingredients, enabled);
66+
// Run the following code in the render thread, since this packet runs in a different thread. (isAsync is true)
67+
Minecraft.getInstance().execute(() -> {
68+
if(player.containerMenu instanceof ContainerTerminalStorageBase container) {
69+
TerminalStorageTabIngredientComponentClient<?, ?> tab = (TerminalStorageTabIngredientComponentClient<?, ?>) container.getTabClient(tabId);
70+
tab.onChange(channel, changeType, ingredients, enabled);
6871

69-
// Hard-coded crafting tab
70-
// TODO: abstract this as "auxiliary" tabs
71-
if (tabId.equals(IngredientComponents.ITEMSTACK.getName().toString())) {
72-
TerminalStorageTabIngredientComponentClient<?, ?> tabCrafting = (TerminalStorageTabIngredientComponentClient<?, ?>) container
73-
.getTabClient(TerminalStorageTabIngredientComponentItemStackCrafting.NAME.toString());
74-
tabCrafting.onChange(channel, changeType, ingredients, enabled);
75-
}
72+
// Hard-coded crafting tab
73+
// TODO: abstract this as "auxiliary" tabs
74+
if (tabId.equals(IngredientComponents.ITEMSTACK.getName().toString())) {
75+
TerminalStorageTabIngredientComponentClient<?, ?> tabCrafting = (TerminalStorageTabIngredientComponentClient<?, ?>) container
76+
.getTabClient(TerminalStorageTabIngredientComponentItemStackCrafting.NAME.toString());
77+
tabCrafting.onChange(channel, changeType, ingredients, enabled);
78+
}
7679

77-
container.refreshChannelStrings();
78-
}
80+
container.refreshChannelStrings();
81+
}
82+
});
7983
}
8084

8185
@Override

src/main/java/org/cyclops/integratedterminals/network/packet/TerminalStorageIngredientCraftingOptionsPacket.java

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package org.cyclops.integratedterminals.network.packet;
22

33
import com.google.common.collect.Lists;
4+
import net.minecraft.client.Minecraft;
45
import net.minecraft.nbt.CompoundTag;
56
import net.minecraft.nbt.ListTag;
67
import net.minecraft.nbt.Tag;
8+
import net.minecraft.resources.ResourceLocation;
79
import net.minecraft.server.level.ServerPlayer;
810
import net.minecraft.world.entity.player.Player;
911
import net.minecraft.world.level.Level;
@@ -13,6 +15,7 @@
1315
import org.cyclops.commoncapabilities.api.ingredient.IngredientComponent;
1416
import org.cyclops.cyclopscore.network.CodecField;
1517
import org.cyclops.cyclopscore.network.PacketCodec;
18+
import org.cyclops.integratedterminals.GeneralConfig;
1619
import org.cyclops.integratedterminals.core.terminalstorage.TerminalStorageTabIngredientComponentClient;
1720
import org.cyclops.integratedterminals.core.terminalstorage.TerminalStorageTabIngredientComponentItemStackCrafting;
1821
import org.cyclops.integratedterminals.core.terminalstorage.crafting.HandlerWrappedTerminalCraftingOption;
@@ -38,6 +41,8 @@ public class TerminalStorageIngredientCraftingOptionsPacket extends PacketCodec
3841
private boolean reset;
3942
@CodecField
4043
private boolean firstChannel;
44+
@CodecField
45+
private String ingredientComponentName;
4146

4247
public TerminalStorageIngredientCraftingOptionsPacket() {
4348

@@ -47,7 +52,8 @@ public <T> TerminalStorageIngredientCraftingOptionsPacket(String tabId,
4752
int channel,
4853
Collection<HandlerWrappedTerminalCraftingOption<T>> craftingOptions,
4954
boolean reset,
50-
boolean firstChannel) {
55+
boolean firstChannel,
56+
IngredientComponent<?, ?> ingredientComponent) {
5157
this.tabId = tabId;
5258
this.channel = channel;
5359
this.data = new CompoundTag();
@@ -58,43 +64,46 @@ public <T> TerminalStorageIngredientCraftingOptionsPacket(String tabId,
5864
this.data.put("craftingOptions", list);
5965
this.reset = reset;
6066
this.firstChannel = firstChannel;
67+
this.ingredientComponentName = IngredientComponent.REGISTRY.getKey(ingredientComponent).toString();
6168
}
6269

6370
@Override
6471
public boolean isAsync() {
65-
return false;
72+
return GeneralConfig.packetDeserializationEnableMultithreading;
6673
}
6774

6875
@Override
6976
@OnlyIn(Dist.CLIENT)
7077
public void actionClient(Level world, Player player) {
71-
if(player.containerMenu instanceof ContainerTerminalStorageBase) {
72-
ContainerTerminalStorageBase container = ((ContainerTerminalStorageBase) player.containerMenu);
73-
74-
75-
TerminalStorageTabIngredientComponentClient<?, ?> tab = (TerminalStorageTabIngredientComponentClient<?, ?>) container.getTabClient(tabId);
76-
IngredientComponent<?, ?> ingredientComponent = tab.getIngredientComponent();
77-
78-
ListTag list = this.data.getList("craftingOptions", Tag.TAG_COMPOUND);
79-
List<HandlerWrappedTerminalCraftingOption<?>> craftingOptions = Lists.newArrayListWithExpectedSize(list.size());
80-
for (int i = 0; i < list.size(); i++) {
81-
HandlerWrappedTerminalCraftingOption<?> option = HandlerWrappedTerminalCraftingOption
82-
.deserialize(ingredientComponent, list.getCompound(i));
83-
craftingOptions.add(option);
84-
}
85-
86-
tab.addCraftingOptions(channel, (List) craftingOptions, this.reset, this.firstChannel);
78+
IngredientComponent<?, ?> ingredientComponent = IngredientComponent.REGISTRY.getValue(new ResourceLocation(ingredientComponentName));
79+
if (ingredientComponentName == null) {
80+
throw new IllegalArgumentException("Could not find the ingredient component type " + ingredientComponentName);
81+
}
82+
ListTag list = this.data.getList("craftingOptions", Tag.TAG_COMPOUND);
83+
List<HandlerWrappedTerminalCraftingOption<?>> craftingOptions = Lists.newArrayListWithExpectedSize(list.size());
84+
for (int i = 0; i < list.size(); i++) {
85+
HandlerWrappedTerminalCraftingOption<?> option = HandlerWrappedTerminalCraftingOption
86+
.deserialize(ingredientComponent, list.getCompound(i));
87+
craftingOptions.add(option);
88+
}
8789

88-
// Hard-coded crafting tab
89-
// TODO: abstract this as "auxiliary" tabs
90-
if (tabId.equals(IngredientComponents.ITEMSTACK.getName().toString())) {
91-
TerminalStorageTabIngredientComponentClient<?, ?> tabCrafting = (TerminalStorageTabIngredientComponentClient<?, ?>) container
92-
.getTabClient(TerminalStorageTabIngredientComponentItemStackCrafting.NAME.toString());
93-
tabCrafting.addCraftingOptions(channel, (List) craftingOptions, this.reset, this.firstChannel);
90+
// Run the following code in the render thread, since this packet runs in a different thread. (isAsync is true)
91+
Minecraft.getInstance().execute(() -> {
92+
if(player.containerMenu instanceof ContainerTerminalStorageBase container) {
93+
TerminalStorageTabIngredientComponentClient<?, ?> tab = (TerminalStorageTabIngredientComponentClient<?, ?>) container.getTabClient(tabId);
94+
tab.addCraftingOptions(channel, (List) craftingOptions, this.reset, this.firstChannel);
95+
96+
// Hard-coded crafting tab
97+
// TODO: abstract this as "auxiliary" tabs
98+
if (tabId.equals(IngredientComponents.ITEMSTACK.getName().toString())) {
99+
TerminalStorageTabIngredientComponentClient<?, ?> tabCrafting = (TerminalStorageTabIngredientComponentClient<?, ?>) container
100+
.getTabClient(TerminalStorageTabIngredientComponentItemStackCrafting.NAME.toString());
101+
tabCrafting.addCraftingOptions(channel, (List) craftingOptions, this.reset, this.firstChannel);
102+
}
103+
104+
container.refreshChannelStrings();
94105
}
95-
96-
container.refreshChannelStrings();
97-
}
106+
});
98107
}
99108

100109
@Override

0 commit comments

Comments
 (0)