Skip to content

Commit 36a4c73

Browse files
Data components map improvements (#894)
* Improve DataComponents class - Added #contains and #remove methods - Make #put allow null values - Add Javadoc to make usage of null values clear * Add fromKey method to DataComponentTypes
1 parent 1e8f791 commit 36a4c73

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentTypes.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ public static DataComponentType<?> from(int id) {
181181
return VALUES.get(id);
182182
}
183183

184+
public static DataComponentType<?> fromKey(Key key) {
185+
return VALUES.stream().filter(component -> component.getKey().equals(key)).findFirst().orElse(null);
186+
}
187+
184188
public static int size() {
185189
return VALUES.size();
186190
}

protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponents.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,24 @@
22

33
import lombok.AllArgsConstructor;
44
import lombok.Data;
5-
import lombok.NonNull;
65
import org.jetbrains.annotations.Nullable;
76

87
import java.util.HashMap;
98
import java.util.Map;
109

10+
/**
11+
* Wrapper around a map of data components and their respective values.
12+
*
13+
* <p>This map can either be a complete data component map, or a data component patch to another map. The meaning of {@code null} values in the map depends on if the map
14+
* is a patch or full map. If the map:</p>
15+
*
16+
* <ul>
17+
* <li>Is a full map, {@code null} means an absence of the component in the map. {@link DataComponents#put(DataComponentType, Object)} should not be used with {@code null} values, rather {@link DataComponents#remove(DataComponentType)} should be used.</li>
18+
* <li>Is a patch, {@code null} can mean an absence of the component in the patch, or that the component should be removed from a map the patch is applied to. Use {@link DataComponents#contains(DataComponentType)}, which returns {@code true} for the latter, to check which is the case.</li>
19+
* </ul>
20+
*
21+
* <p>Make sure to initialise this class with a map that accepts null values if representing a patch.</p>
22+
*/
1123
@Data
1224
@AllArgsConstructor
1325
public class DataComponents {
@@ -25,8 +37,13 @@ public <T> T getOrDefault(DataComponentType<T> type, T def) {
2537
return value != null ? value : def;
2638
}
2739

28-
public <T> void put(DataComponentType<T> type, @NonNull T value) {
29-
if (type instanceof IntComponentType intType) {
40+
/**
41+
* @param value should only be {@code null } if this map is a patch to another map and specifying the removal of the specific component.
42+
*/
43+
public <T> void put(DataComponentType<T> type, @Nullable T value) {
44+
if (value == null) {
45+
dataComponents.put(type, null);
46+
} else if (type instanceof IntComponentType intType) {
3047
dataComponents.put(intType, intType.primitiveFactory.createPrimitive(intType, (Integer) value));
3148
} else if (type instanceof BooleanComponentType boolType) {
3249
dataComponents.put(boolType, boolType.primitiveFactory.createPrimitive(boolType, (Boolean) value));
@@ -35,6 +52,16 @@ public <T> void put(DataComponentType<T> type, @NonNull T value) {
3552
}
3653
}
3754

55+
public boolean contains(DataComponentType<?> component) {
56+
return dataComponents.containsKey(component);
57+
}
58+
59+
@SuppressWarnings("unchecked")
60+
public <T> @Nullable T remove(DataComponentType<T> component) {
61+
DataComponent<T, ?> removed = (DataComponent<T, ?>) dataComponents.remove(component);
62+
return removed == null ? null : removed.getValue();
63+
}
64+
3865
public DataComponents clone() {
3966
return new DataComponents(new HashMap<>(dataComponents));
4067
}

0 commit comments

Comments
 (0)