From b0555963cc156e07938f4dc34b879eb33843230d Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 29 May 2026 12:04:57 +1000 Subject: [PATCH 1/5] move some stuff around --- .../gtceu/api/block/MetaMachineBlock.java | 28 +---------- .../gtceu/api/block/PipeBlock.java | 20 +------- .../api/blockentity/IGregtechBlockEntity.java | 2 +- .../api/blockentity/PipeBlockEntity.java | 2 +- .../gtceu/api/capability/ICoverable.java | 2 +- .../gtceu/api/cover/CoverBehavior.java | 2 +- .../gtceu/api/cover/filter/FilterHandler.java | 2 +- .../api/cover/filter/FilterHandlers.java | 2 +- .../api/machine/MachineCoverContainer.java | 2 +- .../gtceu/api/machine/MetaMachine.java | 2 +- .../gtceu/api/machine/trait/MachineTrait.java | 2 +- .../gtceu/api/pipenet/PipeCoverContainer.java | 2 +- .../gtceu/api/sync_system/ClassSyncData.java | 2 + .../gtceu/api/sync_system/SyncDataHolder.java | 1 + .../SyncAnnotatedTransformer.java | 2 +- .../data_transformers/ValueTransformers.java | 4 +- .../{ => managed}/ISyncAnnotated.java | 2 +- .../{ => managed}/ISyncManaged.java | 3 +- .../sync_system/managed/ManagedSavedData.java | 46 +++++++++++++++++++ .../{ => managed}/ManagedSyncBlockEntity.java | 11 ++++- .../managed/ManagedSyncEntityBlock.java | 35 ++++++++++++++ .../api/sync_system/managed/package-info.java | 4 ++ .../behavior/PortableScannerBehavior.java | 2 +- .../electric/research/HPCAMachine.java | 2 +- 24 files changed, 120 insertions(+), 62 deletions(-) rename src/main/java/com/gregtechceu/gtceu/api/sync_system/{ => managed}/ISyncAnnotated.java (95%) rename src/main/java/com/gregtechceu/gtceu/api/sync_system/{ => managed}/ISyncManaged.java (93%) create mode 100644 src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSavedData.java rename src/main/java/com/gregtechceu/gtceu/api/sync_system/{ => managed}/ManagedSyncBlockEntity.java (93%) create mode 100644 src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSyncEntityBlock.java create mode 100644 src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/package-info.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java index 8461256f6d7..e780ba51986 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java @@ -8,6 +8,7 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition; import com.gregtechceu.gtceu.api.machine.feature.*; +import com.gregtechceu.gtceu.api.sync_system.managed.ManagedSyncEntityBlock; import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; import com.gregtechceu.gtceu.utils.ExtendedUseOnContext; import com.gregtechceu.gtceu.utils.GTUtil; @@ -34,12 +35,9 @@ import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityTicker; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.storage.loot.LootParams; @@ -59,7 +57,7 @@ @SuppressWarnings("deprecation") @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public class MetaMachineBlock extends Block implements EntityBlock { +public class MetaMachineBlock extends Block implements ManagedSyncEntityBlock { @Getter public final MachineDefinition definition; @@ -380,26 +378,4 @@ public static int colorTinted(BlockState blockState, @Nullable BlockAndTintGette public final BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return getDefinition().getBlockEntityType().create(pos, state); } - - @Nullable - @Override - public BlockEntityTicker getTicker(Level level, BlockState state, - BlockEntityType blockEntityType) { - if (blockEntityType == getDefinition().getBlockEntityType()) { - if (!level.isClientSide) { - return (pLevel, pPos, pState, pTile) -> { - if (pTile instanceof MetaMachine metaMachine) { - metaMachine.serverTick(); - } - }; - } else { - return (pLevel, pPos, pState, pTile) -> { - if (pTile instanceof MetaMachine metaMachine) { - metaMachine.clientTick(); - } - }; - } - } - return null; - } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java index 9d51a646986..58975ba08df 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java @@ -14,6 +14,7 @@ import com.gregtechceu.gtceu.api.pipenet.LevelPipeNet; import com.gregtechceu.gtceu.api.pipenet.PipeNet; import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider; +import com.gregtechceu.gtceu.api.sync_system.managed.ManagedSyncEntityBlock; import com.gregtechceu.gtceu.client.model.pipe.PipeModel; import com.gregtechceu.gtceu.common.data.GTItems; import com.gregtechceu.gtceu.common.data.GTMaterialBlocks; @@ -43,7 +44,6 @@ import net.minecraft.world.level.*; import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; @@ -73,7 +73,7 @@ @MethodsReturnNonnullByDefault public abstract class PipeBlock & IPipeType, NodeDataType, WorldPipeNetType extends LevelPipeNet>> extends Block - implements EntityBlock, SimpleWaterloggedBlock { + implements ManagedSyncEntityBlock, SimpleWaterloggedBlock { public final PipeType pipeType; @@ -436,22 +436,6 @@ public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, return getShapes(connections); } - @Nullable - @Override - public BlockEntityTicker getTicker(Level level, BlockState state, - BlockEntityType blockEntityType) { - if (blockEntityType == getBlockEntityType()) { - if (!level.isClientSide) { - return (pLevel, pPos, pState, pTile) -> { - if (pTile instanceof IPipeNode pipeNode) { - pipeNode.serverTick(); - } - }; - } - } - return null; - } - @Override public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/IGregtechBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/IGregtechBlockEntity.java index 821f057094f..2c62873c5e6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/IGregtechBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/IGregtechBlockEntity.java @@ -1,7 +1,7 @@ package com.gregtechceu.gtceu.api.blockentity; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java index 5742b0bee21..a14cb7ca6f3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java @@ -10,10 +10,10 @@ import com.gregtechceu.gtceu.api.item.tool.IToolGridHighlight; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.pipenet.*; -import com.gregtechceu.gtceu.api.sync_system.ManagedSyncBlockEntity; import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.api.sync_system.managed.ManagedSyncBlockEntity; import com.gregtechceu.gtceu.common.data.GTMaterialBlocks; import com.gregtechceu.gtceu.common.data.GTMaterials; import com.gregtechceu.gtceu.utils.ExtendedUseOnContext; diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/ICoverable.java b/src/main/java/com/gregtechceu/gtceu/api/capability/ICoverable.java index e775e766df1..0069e47392c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/ICoverable.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/ICoverable.java @@ -8,7 +8,7 @@ import com.gregtechceu.gtceu.api.cover.CoverDefinition; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.registry.GTRegistries; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.utils.GTUtil; diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java b/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java index 0ffe41c6806..1f7ad88b5d1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java @@ -8,10 +8,10 @@ import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.item.tool.IToolGridHighlight; import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.client.renderer.cover.ICoverRenderer; import com.gregtechceu.gtceu.client.renderer.cover.IDynamicCoverRenderer; diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FilterHandler.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FilterHandler.java index 73b7f459616..025cfde1674 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FilterHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FilterHandler.java @@ -6,10 +6,10 @@ import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; import com.gregtechceu.gtceu.api.machine.MachineCoverContainer; import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FilterHandlers.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FilterHandlers.java index cb269e0aa23..fec94000830 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FilterHandlers.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/FilterHandlers.java @@ -1,6 +1,6 @@ package com.gregtechceu.gtceu.api.cover.filter; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/MachineCoverContainer.java b/src/main/java/com/gregtechceu/gtceu/api/machine/MachineCoverContainer.java index 270aad6f1fb..94ee65ad6ca 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/MachineCoverContainer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/MachineCoverContainer.java @@ -9,11 +9,11 @@ import com.gregtechceu.gtceu.api.machine.trait.MachineTraitType; import com.gregtechceu.gtceu.api.machine.trait.feature.IFrontFacingTrait; import com.gregtechceu.gtceu.api.machine.trait.feature.IRenderingTrait; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.utils.GTUtil; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java index b7c9731b56f..10e8a522d9e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java @@ -30,11 +30,11 @@ import com.gregtechceu.gtceu.api.machine.trait.feature.IRenderingTrait; import com.gregtechceu.gtceu.api.misc.*; import com.gregtechceu.gtceu.api.pattern.util.RelativeDirection; -import com.gregtechceu.gtceu.api.sync_system.ManagedSyncBlockEntity; import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.api.sync_system.managed.ManagedSyncBlockEntity; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.client.model.IBlockEntityRendererBakedModel; import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/MachineTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/MachineTrait.java index 71413e83175..19942004bfb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/MachineTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/MachineTrait.java @@ -2,8 +2,8 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.TickableSubscription; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; import com.gregtechceu.gtceu.common.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.common.machine.trait.CleanroomProviderTrait; diff --git a/src/main/java/com/gregtechceu/gtceu/api/pipenet/PipeCoverContainer.java b/src/main/java/com/gregtechceu/gtceu/api/pipenet/PipeCoverContainer.java index 7b0f8337c4a..4fb9587c39f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/pipenet/PipeCoverContainer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/pipenet/PipeCoverContainer.java @@ -4,11 +4,11 @@ import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.cover.CoverBehavior; import com.gregtechceu.gtceu.api.cover.CoverDefinition; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity; import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java index 9deabe394d5..561f084efa6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java @@ -6,6 +6,8 @@ import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformers; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncAnnotated; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java index d745e5a8a06..1dfa653aa95 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/SyncAnnotatedTransformer.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/SyncAnnotatedTransformer.java index eb4c93225f1..ba0236d898b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/SyncAnnotatedTransformer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/SyncAnnotatedTransformer.java @@ -3,7 +3,7 @@ import com.gregtechceu.gtceu.api.sync_system.ClassSyncData; import com.gregtechceu.gtceu.api.sync_system.FieldSyncData; import com.gregtechceu.gtceu.api.sync_system.FieldSyncHandler; -import com.gregtechceu.gtceu.api.sync_system.ISyncAnnotated; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncAnnotated; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformers.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformers.java index 5dbecd397d5..6ddfde01df0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformers.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformers.java @@ -5,8 +5,6 @@ import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.registry.GTRegistries; -import com.gregtechceu.gtceu.api.sync_system.ISyncAnnotated; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import com.gregtechceu.gtceu.api.sync_system.TypeDeclaration; import com.gregtechceu.gtceu.api.sync_system.data_transformers.collections.ListTransformer; @@ -16,6 +14,8 @@ import com.gregtechceu.gtceu.api.sync_system.data_transformers.gtceu.CoverBehaviorTransformer; import com.gregtechceu.gtceu.api.sync_system.data_transformers.gtceu.GTRecipeTransformer; import com.gregtechceu.gtceu.api.sync_system.data_transformers.gtceu.MonitorGroupTransformer; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncAnnotated; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ISyncAnnotated.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncAnnotated.java similarity index 95% rename from src/main/java/com/gregtechceu/gtceu/api/sync_system/ISyncAnnotated.java rename to src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncAnnotated.java index 9991a4f1626..a5a5d47a360 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ISyncAnnotated.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncAnnotated.java @@ -1,4 +1,4 @@ -package com.gregtechceu.gtceu.api.sync_system; +package com.gregtechceu.gtceu.api.sync_system.managed; import com.gregtechceu.gtceu.api.sync_system.annotations.ClientFieldChangeListener; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ISyncManaged.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncManaged.java similarity index 93% rename from src/main/java/com/gregtechceu/gtceu/api/sync_system/ISyncManaged.java rename to src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncManaged.java index 18907a69ac9..5bb83155429 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ISyncManaged.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncManaged.java @@ -1,5 +1,6 @@ -package com.gregtechceu.gtceu.api.sync_system; +package com.gregtechceu.gtceu.api.sync_system.managed; +import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; import net.minecraftforge.common.util.INBTSerializable; diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSavedData.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSavedData.java new file mode 100644 index 00000000000..e9e63a482e1 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSavedData.java @@ -0,0 +1,46 @@ +package com.gregtechceu.gtceu.api.sync_system.managed; + +import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.saveddata.SavedData; + +import lombok.Getter; +import org.jetbrains.annotations.Nullable; + +/** + * A {@link SavedData} object that stores and loads its data via the sync system.
+ * {@link ManagedSavedData} is not synced to clients. + */ +public abstract class ManagedSavedData extends SavedData implements ISyncManaged { + + @Getter + protected final SyncDataHolder syncDataHolder = new SyncDataHolder(this); + + public ManagedSavedData(CompoundTag tag) { + getSyncDataHolder().deserializeNBT(tag, false); + } + + @Override + public @Nullable ISyncManaged getParentSyncObject() { + return null; + } + + // No functionality, not synced to clients + @Override + public void markAsChanged() {} + + @Override + public void scheduleRenderUpdate() {} + + @Override + public boolean isDirty() { + return true; + } + + // No functionality, not synced to clients + @Override + public CompoundTag save(CompoundTag compoundTag) { + return getSyncDataHolder().serializeNBT(false); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ManagedSyncBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSyncBlockEntity.java similarity index 93% rename from src/main/java/com/gregtechceu/gtceu/api/sync_system/ManagedSyncBlockEntity.java rename to src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSyncBlockEntity.java index 17adfc7e530..b93fbb390c3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ManagedSyncBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSyncBlockEntity.java @@ -1,6 +1,7 @@ -package com.gregtechceu.gtceu.api.sync_system; +package com.gregtechceu.gtceu.api.sync_system.managed; import com.gregtechceu.gtceu.api.blockentity.BlockEntityCreationInfo; +import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -120,6 +121,9 @@ public void setChanged() { } } + /** + * Called each tick on the server side. + */ @MustBeInvokedByOverriders public void serverTick() { setChanged(); @@ -129,4 +133,9 @@ public void serverTick() { isDirty = false; } } + + /** + * Called each tick on the client side. + */ + public void clientTick() {} } diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSyncEntityBlock.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSyncEntityBlock.java new file mode 100644 index 00000000000..f282d6c2bc6 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSyncEntityBlock.java @@ -0,0 +1,35 @@ +package com.gregtechceu.gtceu.api.sync_system.managed; + +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +import org.jetbrains.annotations.Nullable; + +/** + * Entity block that implements the default ticker for a {@link ManagedSyncBlockEntity} + */ +public interface ManagedSyncEntityBlock extends EntityBlock { + + @Override + @Nullable + default BlockEntityTicker getTicker(Level level, BlockState state, + BlockEntityType blockEntityType) { + if (!level.isClientSide) { + return (pLevel, pPos, pState, pTile) -> { + if (pTile instanceof ManagedSyncBlockEntity be) { + be.serverTick(); + } + }; + } else { + return (pLevel, pPos, pState, pTile) -> { + if (pTile instanceof ManagedSyncBlockEntity be) { + be.clientTick(); + } + }; + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/package-info.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/package-info.java new file mode 100644 index 00000000000..f757a7a59bb --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package com.gregtechceu.gtceu.api.sync_system.managed; + +import org.jetbrains.annotations.NotNullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/PortableScannerBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/PortableScannerBehavior.java index 54db194be9a..3251acf6594 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/PortableScannerBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/PortableScannerBehavior.java @@ -15,7 +15,7 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; -import com.gregtechceu.gtceu.api.sync_system.ManagedSyncBlockEntity; +import com.gregtechceu.gtceu.api.sync_system.managed.ManagedSyncBlockEntity; import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity; import com.gregtechceu.gtceu.common.capability.EnvironmentalHazardSavedData; import com.gregtechceu.gtceu.common.capability.LocalizedHazardSavedData; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java index cdc199eb0c6..45f447c74d8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java @@ -18,10 +18,10 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.misc.EnergyContainerList; import com.gregtechceu.gtceu.api.pattern.util.RelativeDirection; -import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.api.transfer.fluid.FluidHandlerList; import com.gregtechceu.gtceu.common.machine.multiblock.part.hpca.HPCAComponentPartMachine; import com.gregtechceu.gtceu.common.machine.trait.hpca.HPCAComponentTrait; From 2059cf58ce866c70078763d8bbad72e77dc5014f Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 29 May 2026 13:44:30 +1000 Subject: [PATCH 2/5] docs --- docs/content/Development/Data-Sync-System/Usage.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/content/Development/Data-Sync-System/Usage.md b/docs/content/Development/Data-Sync-System/Usage.md index e7310d3b0c7..0f1edbaa07a 100644 --- a/docs/content/Development/Data-Sync-System/Usage.md +++ b/docs/content/Development/Data-Sync-System/Usage.md @@ -6,15 +6,15 @@ title: "Usage" ### Registering classes with the sync system -At the core of the system are the `ISyncManaged` and `ISyncAnnotated` interfaces, which allow for their fields to have sync annotations.. -All block entities which should be synchronised or saved must extend the abstract class `ManagedSyncBlockEntity`. +At the core of the system are the `ISyncManaged` and `ISyncAnnotated` interfaces, which allow for their fields to have sync annotations. -`ISyncManaged` should be used for classes with any form of persistent state, and cannot be instantiated or reassigned.
-`ISyncAnnotated` should be used for record-like classes that hold data, and must define a no-args constructor. +- `ISyncManaged` should be used for classes with any form of persistent state, and cannot be instantiated or reassigned. +- `ISyncAnnotated` should be used for record-like classes that hold data, and must define a no-args constructor. +All `ISyncManaged` objects must belong to a root managed sync object. There are two default types of root sync objects: -!!! warning - Block entities that inherit `ManagedSyncBlockEntity` must call `ManagedSyncBlockEntity::updateTick`***every tick*** within their ticker, or they will not be saved. +- `ManagedSyncBlockEntity` is a block entity storing its data through the system. The `Block` class using this `BlockEntity` must implement `ManagedSyncEntityBlock`. +- `ManagedSavedData` is a `SavedData` object that stores data through the system. #### Example of `ISyncManaged` usage ```java From 33efbfef3ffbdf1df5e5ca3551fb27a806a4fa9f Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 29 May 2026 13:55:09 +1000 Subject: [PATCH 3/5] ctor update --- .../gtceu/api/sync_system/managed/ManagedSavedData.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSavedData.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSavedData.java index e9e63a482e1..52350f0f199 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSavedData.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ManagedSavedData.java @@ -17,6 +17,8 @@ public abstract class ManagedSavedData extends SavedData implements ISyncManaged @Getter protected final SyncDataHolder syncDataHolder = new SyncDataHolder(this); + public ManagedSavedData() {} + public ManagedSavedData(CompoundTag tag) { getSyncDataHolder().deserializeNBT(tag, false); } @@ -30,6 +32,7 @@ public ManagedSavedData(CompoundTag tag) { @Override public void markAsChanged() {} + // No functionality, not synced to clients @Override public void scheduleRenderUpdate() {} @@ -38,7 +41,6 @@ public boolean isDirty() { return true; } - // No functionality, not synced to clients @Override public CompoundTag save(CompoundTag compoundTag) { return getSyncDataHolder().serializeNBT(false); From 73c1a1450f2b12c13cdfa6e2fc9b8434b472c43a Mon Sep 17 00:00:00 2001 From: Gustavo Date: Sat, 6 Jun 2026 14:18:06 +1000 Subject: [PATCH 4/5] remove the sync annotated iface in favour of seperate ctors --- .../gtceu/api/sync_system/ClassSyncData.java | 28 +++--- .../api/sync_system/FieldSyncHandler.java | 92 ------------------- .../gtceu/api/sync_system/SyncDataHolder.java | 85 ++++++++++++++++- .../ResourceLocationReferenceTransformer.java | 4 +- .../SyncAnnotatedTransformer.java | 57 ------------ .../data_transformers/ValueTransformers.java | 10 +- .../sync_system/managed/ISyncAnnotated.java | 30 ------ .../api/sync_system/managed/ISyncManaged.java | 6 +- 8 files changed, 107 insertions(+), 205 deletions(-) delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/sync_system/FieldSyncHandler.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/SyncAnnotatedTransformer.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncAnnotated.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java index 561f084efa6..6304b6c96bc 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java @@ -6,19 +6,19 @@ import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformers; -import com.gregtechceu.gtceu.api.sync_system.managed.ISyncAnnotated; import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import lombok.Getter; -import lombok.SneakyThrows; +import org.jetbrains.annotations.Nullable; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.lang.reflect.*; import java.util.*; +import java.util.function.Supplier; /** * Static data for {@link ISyncManaged} classes. @@ -47,23 +47,21 @@ public static ClassSyncData getClassData(Class cls) { private final Set clientSyncFields = new ObjectOpenHashSet<>(); @Getter private final Set serverSaveFields = new ObjectOpenHashSet<>(); + @Getter + private @Nullable Supplier clientsideConstructor = null; - @SneakyThrows private ClassSyncData(Class clazz) { var isManaged = ISyncManaged.class.isAssignableFrom(clazz); - var isAnnotated = ISyncAnnotated.class.isAssignableFrom(clazz); - if (!isManaged && !isAnnotated) - throw new IllegalArgumentException("Cannot create class sync data for non-sync class"); - if (isManaged && isAnnotated) throw new IllegalArgumentException( - "Class %s cannot inherit both ISyncAnnotated and ISyncManaged".formatted(clazz.getName())); + if (!isManaged) + throw new IllegalArgumentException("Cannot create class sync data for non sync managed class."); MethodHandles.Lookup privateLookup; try { privateLookup = MethodHandles.privateLookupIn(clazz, LOOKUP); } catch (IllegalAccessException e) { GTCEu.LOGGER.error("Sync: Failed to create method handle lookup for class {}", clazz); - throw e; + throw new RuntimeException(e); } Map> changeListeners = new HashMap<>(); @@ -105,7 +103,7 @@ private ClassSyncData(Class clazz) { } catch (IllegalAccessException e) { GTCEu.LOGGER.error("Sync: Failed to acquire variable handle for field {} {}", field.getName(), clazz.getName()); - throw e; + throw new RuntimeException(e); } FieldSyncData syncData = new FieldSyncData(field, handle, ValueTransformers.get(field.getGenericType()), @@ -116,7 +114,7 @@ private ClassSyncData(Class clazz) { } Class parent = clazz.getSuperclass(); - if (ISyncManaged.class.isAssignableFrom(parent) || ISyncAnnotated.class.isAssignableFrom(parent)) { + if (ISyncManaged.class.isAssignableFrom(parent)) { ClassSyncData parentHandles = CACHE.get(parent); managedFields.addAll(parentHandles.managedFields); clientSyncFields.addAll(parentHandles.clientSyncFields); @@ -136,4 +134,12 @@ public void setCustomTransformerForField(String fieldName, ValueTransformer t .findFirst() .ifPresent(fieldData -> fieldData.setTransformer(transformer)); } + + /** + * Allows this class to be instantiated on the client when being synced. + * @param ctor The constructor/supplier to be called when instantiating this class on the client. + */ + public void setClientsideConstructor(@Nullable Supplier ctor) { + clientsideConstructor = ctor; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/FieldSyncHandler.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/FieldSyncHandler.java deleted file mode 100644 index 9aca87d327e..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/FieldSyncHandler.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.gregtechceu.gtceu.api.sync_system; - -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; -import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformers; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; - -@ApiStatus.Internal -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class FieldSyncHandler { - - @SuppressWarnings("unchecked") - public static Tag serializeField(Object holder, FieldSyncData field, - boolean writeClientFields, boolean fullSync) { - Object currentValue = field.handle.get(holder); - - if (currentValue == null) { - var nullCompound = new CompoundTag(); - nullCompound.putBoolean("null", true); - return nullCompound; - } - - if (field.transformer == null) { - field.setTransformer(ValueTransformers.get(field.type.getRawType())); - if (field.transformer == null) { - GTCEu.LOGGER.error("Sync: Failed to serialize field {} in class {}: Missing value transformer for {}", - field.fieldName, holder.getClass().getName(), field.type); - return new CompoundTag(); - } - } - - try { - return ((ValueTransformer) field.transformer).serializeNBT(currentValue, - new ValueTransformer.TransformerContext<>(holder, field.type, currentValue, field.fieldName, - writeClientFields, fullSync)); - - } catch (Exception e) { - GTCEu.LOGGER.error("Sync: Failed to serialize field {}", field.fieldName, e); - } - - return new CompoundTag(); - } - - @SuppressWarnings("unchecked") - public static void deserializeField(Object holder, FieldSyncData field, - @Nullable Tag savedValue, - boolean readingClientFields) { - if (savedValue == null || savedValue instanceof CompoundTag compound && compound.isEmpty()) return; - - if (savedValue instanceof CompoundTag compound && compound.getBoolean("null")) { - field.handle.set(holder, null); - return; - } - - if (field.transformer == null) { - field.setTransformer(ValueTransformers.get(field.type.getRawType())); - if (field.transformer == null) { - GTCEu.LOGGER.error("Sync: Failed to deserialize field {} in class {}: Missing value transformer for {}", - field.fieldName, holder.getClass().getName(), field.type); - return; - } - } - - try { - ValueTransformer transformer = (ValueTransformer) field.transformer; - var current = field.handle.get(holder); - - Object result = transformer.deserializeNBT(savedValue, new ValueTransformer.TransformerContext<>( - holder, field.type, current, field.fieldName, readingClientFields, false)); - - if (result != current) { - field.handle.set(holder, result); - } - - } catch (Exception e) { - if (e instanceof UnsupportedOperationException) { - GTCEu.LOGGER.error( - "Sync: failed to perform VarHandle set: unsupported op on {} (you are probably trying to sync a final field)", - field.fieldName); - return; - } - GTCEu.LOGGER.error("Sync: Failed to deserialize field {}", field.fieldName, e); - } - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java index 1dfa653aa95..440e7ebd84b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; +import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformers; import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import net.minecraft.nbt.CompoundTag; @@ -57,7 +58,7 @@ public CompoundTag serializeNBT(boolean writeClientFields, boolean fullSync) { CompoundTag tag = new CompoundTag(); for (var field : fieldsToSerialize) { if (shouldSerializeField(field, writeClientFields, fullSync)) { - Tag nbtValue = FieldSyncHandler.serializeField(holder, field, writeClientFields, fullSync); + Tag nbtValue = serializeField(holder, field, writeClientFields, fullSync); tag.put(field.nbtSaveKey, nbtValue); } } @@ -78,7 +79,7 @@ public void deserializeNBT(CompoundTag tag, boolean readingClientFields) { for (var field : fieldsToCheck) { Tag savedValue = tag.get(field.nbtSaveKey); - FieldSyncHandler.deserializeField(holder, field, savedValue, readingClientFields); + deserializeField(holder, field, savedValue, readingClientFields); if (readingClientFields) { try { @@ -99,6 +100,80 @@ public void deserializeNBT(CompoundTag tag, boolean readingClientFields) { } } + @SuppressWarnings("unchecked") + private static Tag serializeField(Object holder, FieldSyncData field, + boolean writeClientFields, boolean fullSync) { + Object currentValue = field.handle.get(holder); + + if (currentValue == null) { + var nullCompound = new CompoundTag(); + nullCompound.putBoolean("null", true); + return nullCompound; + } + + if (field.transformer == null) { + field.setTransformer(ValueTransformers.get(field.type.getRawType())); + if (field.transformer == null) { + GTCEu.LOGGER.error("Sync: Failed to serialize field {} in class {}: Missing value transformer for {}", + field.fieldName, holder.getClass().getName(), field.type); + return new CompoundTag(); + } + } + + try { + return ((ValueTransformer) field.transformer).serializeNBT(currentValue, + new ValueTransformer.TransformerContext<>(holder, field.type, currentValue, field.fieldName, + writeClientFields, fullSync)); + + } catch (Exception e) { + GTCEu.LOGGER.error("Sync: Failed to serialize field {}", field.fieldName, e); + } + + return new CompoundTag(); + } + + @SuppressWarnings("unchecked") + private static void deserializeField(Object holder, FieldSyncData field, + @Nullable Tag newValue, + boolean readingClientFields) { + if (newValue == null || newValue instanceof CompoundTag compound && compound.isEmpty()) return; + + if (newValue instanceof CompoundTag compound && compound.getBoolean("null")) { + field.handle.set(holder, null); + return; + } + + if (field.transformer == null) { + field.setTransformer(ValueTransformers.get(field.type.getRawType())); + if (field.transformer == null) { + GTCEu.LOGGER.error("Sync: Failed to deserialize field {} in class {}: Missing value transformer for {}", + field.fieldName, holder.getClass().getName(), field.type); + return; + } + } + + try { + ValueTransformer transformer = (ValueTransformer) field.transformer; + var current = field.handle.get(holder); + + Object result = transformer.deserializeNBT(newValue, new ValueTransformer.TransformerContext<>( + holder, field.type, current, field.fieldName, readingClientFields, false)); + + if (result != current) { + field.handle.set(holder, result); + } + + } catch (Exception e) { + if (e instanceof UnsupportedOperationException) { + GTCEu.LOGGER.error( + "Sync: failed to perform VarHandle set: unsupported op on {} (you are probably trying to sync a final field)", + field.fieldName); + return; + } + GTCEu.LOGGER.error("Sync: Failed to deserialize field {}", field.fieldName, e); + } + } + public static class SyncManagedTransformer implements ValueTransformer { @Override @@ -109,6 +184,12 @@ public Tag serializeNBT(ISyncManaged value, TransformerContext con @Override public @Nullable ISyncManaged deserializeNBT(Tag tag, TransformerContext context) { ISyncManaged syncManaged = context.currentValue(); + var clazz = context.type().getClassValue(); + + if (syncManaged == null && clazz != null && ISyncManaged.class.isAssignableFrom(clazz)) { + var ctor = ClassSyncData.getClassData(clazz).getClientsideConstructor(); + if (ctor != null) syncManaged = (ISyncManaged)ctor.get(); + } if (syncManaged == null) { GTCEu.LOGGER.error("Sync: ISyncManaged field was null, cannot instantiate {}", diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ResourceLocationReferenceTransformer.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ResourceLocationReferenceTransformer.java index 4f6f6e97057..e40b5cb766e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ResourceLocationReferenceTransformer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ResourceLocationReferenceTransformer.java @@ -11,10 +11,10 @@ public class ResourceLocationReferenceTransformer implements ValueTransformer { private final Function getResourceLocation; - private final Function loadFromLocation; + private final Function loadFromLocation; public ResourceLocationReferenceTransformer(Function getResourceLocation, - Function loadFromLocation) { + Function loadFromLocation) { this.getResourceLocation = getResourceLocation; this.loadFromLocation = loadFromLocation; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/SyncAnnotatedTransformer.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/SyncAnnotatedTransformer.java deleted file mode 100644 index ba0236d898b..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/SyncAnnotatedTransformer.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.gregtechceu.gtceu.api.sync_system.data_transformers; - -import com.gregtechceu.gtceu.api.sync_system.ClassSyncData; -import com.gregtechceu.gtceu.api.sync_system.FieldSyncData; -import com.gregtechceu.gtceu.api.sync_system.FieldSyncHandler; -import com.gregtechceu.gtceu.api.sync_system.managed.ISyncAnnotated; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; - -import lombok.SneakyThrows; -import org.jetbrains.annotations.Nullable; - -import java.util.Objects; -import java.util.Set; - -public class SyncAnnotatedTransformer implements ValueTransformer { - - @Override - public Tag serializeNBT(ISyncAnnotated value, TransformerContext context) { - var syncData = ClassSyncData.getClassData(value.getClass()); - - Set fieldsToSerialize = context.isClientSync() ? syncData.getClientSyncFields() : - syncData.getServerSaveFields(); - - CompoundTag tag = new CompoundTag(); - for (var field : fieldsToSerialize) { - Tag nbtValue = FieldSyncHandler.serializeField(context.holder(), field, context.isClientSync(), true); - tag.put(field.nbtSaveKey, nbtValue); - } - - return tag; - } - - @Override - @SneakyThrows - public @Nullable ISyncAnnotated deserializeNBT(Tag tag, TransformerContext context) { - if (!(tag instanceof CompoundTag compound)) return null; - - var typeData = Objects.requireNonNull(context.type().getClassValue()); - - var syncData = ClassSyncData.getClassData(typeData); - - Set fieldsToCheck = context.isClientSync() ? syncData.getClientSyncFields() : - syncData.getServerSaveFields(); - - var holder = context.currentValue(); - if (holder == null) holder = (ISyncAnnotated) typeData.getConstructor().newInstance(); - - for (var field : fieldsToCheck) { - Tag savedValue = compound.get(field.nbtSaveKey); - FieldSyncHandler.deserializeField(holder, field, savedValue, context.isClientSync()); - } - - return holder; - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformers.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformers.java index 6ddfde01df0..e5538871e06 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformers.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformers.java @@ -14,7 +14,6 @@ import com.gregtechceu.gtceu.api.sync_system.data_transformers.gtceu.CoverBehaviorTransformer; import com.gregtechceu.gtceu.api.sync_system.data_transformers.gtceu.GTRecipeTransformer; import com.gregtechceu.gtceu.api.sync_system.data_transformers.gtceu.MonitorGroupTransformer; -import com.gregtechceu.gtceu.api.sync_system.managed.ISyncAnnotated; import com.gregtechceu.gtceu.api.sync_system.managed.ISyncManaged; import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; @@ -131,7 +130,7 @@ TagType extends Tag> void registerSimpleClassTransformer(Class type, Function * @param type The class to register this {@link ValueTransformer} supplier for * @param func Supplier function */ - public static void registerTransformerSupplier(Class type, Supplier> func) { + public static void registerGenericTransformerSupplier(Class type, Supplier> func) { if (REGISTERED_SUPPLIERS.containsKey(type)) throw new IllegalArgumentException("Attempted to register transformer for %s twice".formatted(type)); REGISTERED_SUPPLIERS.put(type, func); @@ -182,11 +181,10 @@ public static void registerTransformerSupplier(Class type, Supplier - * - * This interface has no functionality on its own, it just marks that a class has sync annotations.
- * - * A sync annotated class cannot be synced on its own, it must be a field of an {@link ISyncManaged} class.
- * - * All {@link ISyncAnnotated} classes should have a no-args constructor.
- * - * {@link ClientFieldChangeListener} does not work for fields in {@link ISyncAnnotated} classes. - * - *

- * A field of type {@code T} can be marked with sync annotations if: - *

    - *
  • {@code T} is primitive - *
  • {@code T} has an {@link ValueTransformer} registered - *
  • {@code T} implements {@link INBTSerializable} - *
  • {@code T} is an {@link ISyncAnnotated} class - *
- * - * @see ISyncManaged - */ -public interface ISyncAnnotated {} diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncManaged.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncManaged.java index 5bb83155429..c9f28a0613f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncManaged.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/managed/ISyncManaged.java @@ -9,20 +9,16 @@ /** * Represents a class with fields that have sync annotations.
- * Differs from {@link ISyncAnnotated} in that more control is provided over syncing.
- * An {@link ISyncManaged} class manages the sync status of itself and its fields, - * while a {@link ISyncAnnotated} must be managed by a field in an {@link ISyncManaged} class. *

* A field of type {@code T} can be marked with sync annotations if: *

    *
  • {@code T} is primitive *
  • {@code T} has an {@link ValueTransformer} registered *
  • {@code T} implements {@link INBTSerializable} - *
  • {@code T} is an {@link ISyncManaged} or {@link ISyncAnnotated} class + *
  • {@code T} is an {@link ISyncManaged} class *
* * @see SyncDataHolder - * @see ISyncAnnotated */ public interface ISyncManaged { From 7ba5e1821e7e26b1aa0add20720caf3579e779ea Mon Sep 17 00:00:00 2001 From: Gustavo Date: Tue, 9 Jun 2026 18:59:18 +1000 Subject: [PATCH 5/5] spotless --- .../gregtechceu/gtceu/api/sync_system/ClassSyncData.java | 1 + .../gregtechceu/gtceu/api/sync_system/SyncDataHolder.java | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java index 6304b6c96bc..56334f5a6a2 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/ClassSyncData.java @@ -137,6 +137,7 @@ public void setCustomTransformerForField(String fieldName, ValueTransformer t /** * Allows this class to be instantiated on the client when being synced. + * * @param ctor The constructor/supplier to be called when instantiating this class on the client. */ public void setClientsideConstructor(@Nullable Supplier ctor) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java index 440e7ebd84b..49ee1cb0e25 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/SyncDataHolder.java @@ -102,7 +102,7 @@ public void deserializeNBT(CompoundTag tag, boolean readingClientFields) { @SuppressWarnings("unchecked") private static Tag serializeField(Object holder, FieldSyncData field, - boolean writeClientFields, boolean fullSync) { + boolean writeClientFields, boolean fullSync) { Object currentValue = field.handle.get(holder); if (currentValue == null) { @@ -134,8 +134,8 @@ private static Tag serializeField(Object holder, FieldSyncData field, @SuppressWarnings("unchecked") private static void deserializeField(Object holder, FieldSyncData field, - @Nullable Tag newValue, - boolean readingClientFields) { + @Nullable Tag newValue, + boolean readingClientFields) { if (newValue == null || newValue instanceof CompoundTag compound && compound.isEmpty()) return; if (newValue instanceof CompoundTag compound && compound.getBoolean("null")) { @@ -188,7 +188,7 @@ public Tag serializeNBT(ISyncManaged value, TransformerContext con if (syncManaged == null && clazz != null && ISyncManaged.class.isAssignableFrom(clazz)) { var ctor = ClassSyncData.getClassData(clazz).getClientsideConstructor(); - if (ctor != null) syncManaged = (ISyncManaged)ctor.get(); + if (ctor != null) syncManaged = (ISyncManaged) ctor.get(); } if (syncManaged == null) {