Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/content/Development/Data-Sync-System/Annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,10 @@ public boolean isWorkingEnabled = true;
public void isWorkingChanged() {
setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_WORKING_ENABLED, isWorkingEnabled));
}
```
```

### `@SaveToItemStack`

The `@SaveToItemStack` annotation defines a field on a BlockEntity that should be saved when the block is broken or cloned.

The annotation has two parameters, `saveToDroppedStack` and `saveToPickedStack`, which both default to true.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Client sync fields **do not** automatically detect changes. When changing a clie
- `@RequireRerender` -> `@RerenderOnChanged`
- `@Persisted` -> `@SaveField`
- `@UpdateListener` -> `@ClientFieldChangeListener` on listener method.
- `@DropSaved` - Removed, make machines implement `IDropSaveMachine` instead
- `@DropSaved` -> `@SaveToItemStack`
- `@ReadOnlyManaged` and `@LazyManaged` See usage docs for instructions on complex sync objects

### Other changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties;
import com.gregtechceu.gtceu.api.data.RotationState;
import com.gregtechceu.gtceu.api.item.IGTTool;
import com.gregtechceu.gtceu.api.item.MetaMachineItem;
import com.gregtechceu.gtceu.api.machine.MachineDefinition;
import com.gregtechceu.gtceu.api.machine.MetaMachine;
import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition;
Expand Down Expand Up @@ -171,10 +170,10 @@ public BlockState getStateForPlacement(BlockPlaceContext context) {
@Override
public ItemStack getCloneItemStack(BlockGetter level, BlockPos pos, BlockState state) {
ItemStack itemStack = super.getCloneItemStack(level, pos, state);
if (MetaMachine.getMachine(level, pos) instanceof IDropSaveMachine dropSaveMachine &&
dropSaveMachine.savePickClone()) {
dropSaveMachine.saveToItem(itemStack.getOrCreateTag());
}

var machine = MetaMachine.getMachine(level, pos);
if (machine != null) machine.saveToItem(itemStack, true);

return itemStack;
}

Expand Down Expand Up @@ -225,15 +224,6 @@ public List<ItemStack> getDrops(BlockState state, LootParams.Builder builder) {
BlockEntity be = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
if (be instanceof MetaMachine machine) {
machine.modifyDrops(drops);
if (machine instanceof IDropSaveMachine dropSaveMachine && dropSaveMachine.saveBreak()) {
for (ItemStack drop : drops) {
if (drop.getItem() instanceof MetaMachineItem item && item.getBlock() == this) {
dropSaveMachine.saveToItem(drop.getOrCreateTag());
// break here to not dupe contents if a machine drops multiple of itself for whatever reason.
break;
}
}
}
}
return drops;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.gregtechceu.gtceu.api.data.RotationState;
import com.gregtechceu.gtceu.api.gui.GuiTextures;
import com.gregtechceu.gtceu.api.gui.fancy.IFancyTooltip;
import com.gregtechceu.gtceu.api.item.MetaMachineItem;
import com.gregtechceu.gtceu.api.item.tool.GTToolType;
import com.gregtechceu.gtceu.api.item.tool.IToolGridHighlight;
import com.gregtechceu.gtceu.api.item.tool.ToolHelper;
Expand Down Expand Up @@ -188,12 +189,7 @@ public void onMachinePlaced(@Nullable LivingEntity player, ItemStack stack) {
ownerUUID = sPlayer.getUUID();
}

if (this instanceof IDropSaveMachine dropSaveMachine) {
CompoundTag tag = stack.getTag();
if (tag != null) {
dropSaveMachine.loadFromItem(tag);
}
}
loadFromItem(stack);
}

public void onMachineDestroyed() {
Expand All @@ -202,7 +198,28 @@ public void onMachineDestroyed() {
}
}

public void modifyDrops(List<ItemStack> drops) {}
public void modifyDrops(List<ItemStack> drops) {
for (ItemStack drop : drops) {
if (drop.getItem() instanceof MetaMachineItem item && getBlockState().is(item.getBlock())) {
saveToItem(drop, false);
// break here to not dupe contents if a machine drops multiple of itself for whatever reason.
break;
}
}
}

public void saveToItem(ItemStack stack, boolean pickBlock) {
if (shouldSaveToItemStack(pickBlock)) getSyncDataHolder().saveItemStackTag(stack, pickBlock);
}

public void loadFromItem(ItemStack stack) {
var elem = stack.getTag();
if (elem != null) load(elem);
}

public boolean shouldSaveToItemStack(boolean pickBlock) {
return true;
}

//////////////////////////////////////
// ***** Tickable Manager ****//
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.sync_system.annotations.ClientFieldChangeListener;
import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField;
import com.gregtechceu.gtceu.api.sync_system.annotations.SaveToItemStack;
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 it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import lombok.Getter;

Expand Down Expand Up @@ -39,11 +39,7 @@ public static ClassSyncData getClassData(Class<?> cls) {
}

@Getter
private final List<FieldSyncData> managedFields = new ObjectArrayList<>();
@Getter
private final Set<FieldSyncData> clientSyncFields = new ObjectOpenHashSet<>();
@Getter
private final Set<FieldSyncData> serverSaveFields = new ObjectOpenHashSet<>();
private final Set<FieldSyncData> managedFields = new ObjectOpenHashSet<>();

private ClassSyncData(Class<?> clazz) {
MethodHandles.Lookup privateLookup;
Expand Down Expand Up @@ -82,7 +78,8 @@ private ClassSyncData(Class<?> clazz) {

boolean hasSaveField = field.isAnnotationPresent(SaveField.class);
boolean hasClientSync = field.isAnnotationPresent(SyncToClient.class);
if (!hasSaveField && !hasClientSync) continue;
boolean hasSaveToItemStack = field.isAnnotationPresent(SaveToItemStack.class);
if (!hasSaveField && !hasClientSync && !hasSaveToItemStack) continue;

if (Modifier.isStatic(field.getModifiers()))
throw new IllegalArgumentException("Cannot apply syncdata annotations to static field: %s.%s"
Expand All @@ -101,16 +98,12 @@ private ClassSyncData(Class<?> clazz) {
FieldSyncData syncData = new FieldSyncData(field, handle, ValueTransformers.get(field.getGenericType()),
changeListeners.getOrDefault(field.getName(), List.of()));
managedFields.add(syncData);
if (hasClientSync) clientSyncFields.add(syncData);
if (hasSaveField) serverSaveFields.add(syncData);
}

Class<?> parent = clazz.getSuperclass();
if (parent != Object.class) {
ClassSyncData parentHandles = CACHE.get(parent);
managedFields.addAll(parentHandles.managedFields);
clientSyncFields.addAll(parentHandles.clientSyncFields);
serverSaveFields.addAll(parentHandles.serverSaveFields);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

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.SaveToItemStack;
import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient;
import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer;

import lombok.Setter;
Expand All @@ -18,6 +20,8 @@
public final class FieldSyncData {

public final String fieldName, nbtSaveKey;
public final boolean saveField, syncToClient;
public final boolean saveToDroppedStack, saveToPickedStack;
public final VarHandle handle;
public final boolean triggerClientRerender, isSyncManaged;
@Setter
Expand All @@ -29,7 +33,25 @@ public FieldSyncData(Field field, VarHandle handle, @Nullable ValueTransformer<?
List<MethodHandle> changeListenerHandles) {
fieldName = field.getName();
SaveField saveField = field.getAnnotation(SaveField.class);
this.nbtSaveKey = (saveField != null && !saveField.nbtKey().isBlank()) ? saveField.nbtKey() : fieldName;
SyncToClient syncToClient = field.getAnnotation(SyncToClient.class);
SaveToItemStack saveToStack = field.getAnnotation(SaveToItemStack.class);

this.saveField = saveField != null;
this.syncToClient = syncToClient != null;

if (saveField != null) {
this.nbtSaveKey = !saveField.nbtKey().isBlank() ? saveField.nbtKey() : fieldName;
} else {
this.nbtSaveKey = fieldName;
}

if (saveToStack != null) {
this.saveToDroppedStack = saveToStack.saveToDroppedStack();
this.saveToPickedStack = saveToStack.saveToPickedStack();
} else {
this.saveToDroppedStack = false;
this.saveToPickedStack = false;
}
this.isSyncManaged = ISyncManaged.class.isAssignableFrom(field.getType());
this.handle = handle;
this.triggerClientRerender = field.isAnnotationPresent(RerenderOnChanged.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack;

import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import it.unimi.dsi.fastutil.objects.ObjectSet;
Expand Down Expand Up @@ -53,11 +54,8 @@ public CompoundTag serializeNBT(boolean writeClientFields) {
}

public CompoundTag serializeNBT(boolean writeClientFields, boolean fullSync) {
Set<FieldSyncData> fieldsToSerialize = writeClientFields ? syncData.getClientSyncFields() :
syncData.getServerSaveFields();

CompoundTag tag = new CompoundTag();
for (var field : fieldsToSerialize) {
for (var field : syncData.getManagedFields()) {
if (shouldSerializeField(field, writeClientFields, fullSync)) {
Tag nbtValue = serializeField(holder, field, writeClientFields, fullSync);
tag.put(field.nbtSaveKey, nbtValue);
Expand All @@ -67,15 +65,14 @@ public CompoundTag serializeNBT(boolean writeClientFields, boolean fullSync) {
}

private boolean shouldSerializeField(FieldSyncData field, boolean writeClient, boolean fullSync) {
return !writeClient || fullSync || dirtySyncFields.contains(field.fieldName) || field.isSyncManaged;
if (field.saveField && !writeClient) return true;
if (field.syncToClient && writeClient)
return fullSync || dirtySyncFields.contains(field.fieldName) || field.isSyncManaged;
return false;
}

public void deserializeNBT(CompoundTag tag, boolean readingClientFields) {
Set<FieldSyncData> fieldsToCheck = readingClientFields ? syncData.getClientSyncFields() :
syncData.getServerSaveFields();

for (var field : fieldsToCheck) {

for (var field : syncData.getManagedFields()) {
Tag savedValue = tag.get(field.nbtSaveKey);
deserializeField(holder, field, savedValue, readingClientFields);

Expand All @@ -99,6 +96,15 @@ public void deserializeNBT(CompoundTag tag, boolean readingClientFields) {
}
}

public void saveItemStackTag(ItemStack stack, boolean pickedStack) {
var compound = stack.getOrCreateTag();
for (var field : syncData.getManagedFields()) {
if ((pickedStack && field.saveToPickedStack) || field.saveToDroppedStack) {
compound.put(field.nbtSaveKey, serializeField(holder, field, false, false));
}
}
}

@SuppressWarnings("unchecked")
private static Tag serializeField(ISyncManaged holder, FieldSyncData field,
boolean writeClientFields, boolean fullSync) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.gregtechceu.gtceu.api.sync_system.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Saves a field on a BlockEntity to an item stack when the block is destroyed or picked.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SaveToItemStack {

/**
* If this field should be saved when the block is destroyed.
*/
boolean saveToDroppedStack() default true;

/**
* If this field should be saved when the block is cloned.
*/
boolean saveToPickedStack() default true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public boolean canShared() {

@Override
public void modifyDrops(List<ItemStack> drops) {
super.modifyDrops(drops);
for (int i = 0; i < drops.size(); ++i) {
ItemStack drop = drops.get(i);
if (drop.getItem() == this.getDefinition().getItem()) {
Expand Down
Loading
Loading