DataComponentPatch.java
net.minecraft.core.component.DataComponentPatch
信息
- 全限定名:net.minecraft.core.component.DataComponentPatch
- 类型:public final class
- 包:net.minecraft.core.component
- 源码路径:src/main/java/net/minecraft/core/component/DataComponentPatch.java
- 起始行号:L21
- 职责:
TODO
字段/常量
-
EMPTY- 类型:
DataComponentPatch - 修饰符:
public static final - 源码定位:
L22 - 说明:
TODO
- 类型:
-
CODEC- 类型:
Codec<DataComponentPatch> - 修饰符:
public static final - 源码定位:
L23 - 说明:
TODO
- 类型:
-
STREAM_CODEC- 类型:
StreamCodec<RegistryFriendlyByteBuf,DataComponentPatch> - 修饰符:
public static final public - 源码定位:
L58 - 说明:
TODO
- 类型:
-
DELIMITED_STREAM_CODEC- 类型:
StreamCodec<RegistryFriendlyByteBuf,DataComponentPatch> - 修饰符:
public static final public - 源码定位:
L64 - 说明:
TODO
- 类型:
-
REMOVED_PREFIX- 类型:
String - 修饰符:
private static final - 源码定位:
L73 - 说明:
TODO
- 类型:
-
map- 类型:
Reference2ObjectMap<DataComponentType<?>,Optional<?>> - 修饰符:
final - 源码定位:
L74 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.core.component.DataComponentPatch.Builder- 类型:
class - 修饰符:
public static - 源码定位:
L251 - 说明:
TODO
- 类型:
-
net.minecraft.core.component.DataComponentPatch.CodecGetter- 类型:
interface - 修饰符:
private - 源码定位:
L285 - 说明:
TODO
- 类型:
-
net.minecraft.core.component.DataComponentPatch.PatchKey- 类型:
record - 修饰符:
private - 源码定位:
L289 - 说明:
TODO
- 类型:
-
net.minecraft.core.component.DataComponentPatch.SplitResult- 类型:
record - 修饰符:
public - 源码定位:
L322 - 说明:
TODO
- 类型:
构造器
DataComponentPatch(Reference2ObjectMap<DataComponentType<?>,Optional<?>> map) @ L151
- 构造器名:DataComponentPatch
- 源码定位:L151
- 修饰符:package-private
参数:
- map: Reference2ObjectMap<DataComponentType,Optional>
说明:
TODO
方法
下面的方法块按源码顺序生成。
private static StreamCodec<RegistryFriendlyByteBuf,DataComponentPatch> createStreamCodec(DataComponentPatch.CodecGetter codecGetter) @ L76
- 方法名:createStreamCodec
- 源码定位:L76
- 返回类型:StreamCodec<RegistryFriendlyByteBuf,DataComponentPatch>
- 修饰符:private static
参数:
- codecGetter: DataComponentPatch.CodecGetter
说明:
TODO
public static DataComponentPatch.Builder builder() @ L155
- 方法名:builder
- 源码定位:L155
- 返回类型:DataComponentPatch.Builder
- 修饰符:public static
参数:
- 无
说明:
TODO
public <T> T get(DataComponentGetter prototype, DataComponentType<?extends T> type) @ L159
- 方法名:get
- 源码定位:L159
- 返回类型:
T - 修饰符:public
参数:
- prototype: DataComponentGetter
- type: DataComponentType<?extends T>
说明:
TODO
static <T> T getFromPatchAndPrototype(Reference2ObjectMap<DataComponentType<?>,Optional<?>> patch, DataComponentGetter prototype, DataComponentType<?extends T> type) @ L163
- 方法名:getFromPatchAndPrototype
- 源码定位:L163
- 返回类型:
T - 修饰符:static
参数:
- patch: Reference2ObjectMap<DataComponentType,Optional>
- prototype: DataComponentGetter
- type: DataComponentType<?extends T>
说明:
TODO
public Set<Entry<DataComponentType<?>,Optional<?>>> entrySet() @ L170
- 方法名:entrySet
- 源码定位:L170
- 返回类型:Set<Entry<DataComponentType,Optional>>
- 修饰符:public
参数:
- 无
说明:
TODO
public int size() @ L174
- 方法名:size
- 源码定位:L174
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public DataComponentPatch forget(Predicate<DataComponentType<?>> test) @ L178
- 方法名:forget
- 源码定位:L178
- 返回类型:DataComponentPatch
- 修饰符:public
参数:
- test: Predicate<DataComponentType<?>>
说明:
TODO
public boolean isEmpty() @ L188
- 方法名:isEmpty
- 源码定位:L188
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public DataComponentPatch.SplitResult split() @ L192
- 方法名:split
- 源码定位:L192
- 返回类型:DataComponentPatch.SplitResult
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean equals(Object obj) @ L209
- 方法名:equals
- 源码定位:L209
- 返回类型:boolean
- 修饰符:public
参数:
- obj: Object
说明:
TODO
public int hashCode() @ L214
- 方法名:hashCode
- 源码定位:L214
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public String toString() @ L219
- 方法名:toString
- 源码定位:L219
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
static String toString(Reference2ObjectMap<DataComponentType<?>,Optional<?>> map) @ L224
- 方法名:toString
- 源码定位:L224
- 返回类型:String
- 修饰符:static
参数:
- map: Reference2ObjectMap<DataComponentType,Optional>
说明:
TODO
代码
public final class DataComponentPatch {
public static final DataComponentPatch EMPTY = new DataComponentPatch(Reference2ObjectMaps.emptyMap());
public static final Codec<DataComponentPatch> CODEC = Codec.<DataComponentPatch.PatchKey, Object>dispatchedMap(DataComponentPatch.PatchKey.CODEC, DataComponentPatch.PatchKey::valueCodec)
.xmap(data -> {
if (data.isEmpty()) {
return EMPTY;
} else {
Reference2ObjectMap<DataComponentType<?>, Optional<?>> map = new Reference2ObjectArrayMap<>(data.size());
for (Entry<DataComponentPatch.PatchKey, ?> entry : data.entrySet()) {
DataComponentPatch.PatchKey key = entry.getKey();
if (key.removed()) {
map.put(key.type(), Optional.empty());
} else {
map.put(key.type(), Optional.of(entry.getValue()));
}
}
return new DataComponentPatch(map);
}
}, patch -> {
Reference2ObjectMap<DataComponentPatch.PatchKey, Object> map = new Reference2ObjectArrayMap<>(patch.map.size());
for (Entry<DataComponentType<?>, Optional<?>> entry : Reference2ObjectMaps.fastIterable(patch.map)) {
DataComponentType<?> type = entry.getKey();
if (!type.isTransient()) {
Optional<?> value = entry.getValue();
if (value.isPresent()) {
map.put(new DataComponentPatch.PatchKey(type, false), value.get());
} else {
map.put(new DataComponentPatch.PatchKey(type, true), Unit.INSTANCE);
}
}
}
return map;
});
public static final StreamCodec<RegistryFriendlyByteBuf, DataComponentPatch> STREAM_CODEC = createStreamCodec(new DataComponentPatch.CodecGetter() {
@Override
public <T> StreamCodec<RegistryFriendlyByteBuf, T> apply(DataComponentType<T> type) {
return type.streamCodec().cast();
}
});
public static final StreamCodec<RegistryFriendlyByteBuf, DataComponentPatch> DELIMITED_STREAM_CODEC = createStreamCodec(
new DataComponentPatch.CodecGetter() {
@Override
public <T> StreamCodec<RegistryFriendlyByteBuf, T> apply(DataComponentType<T> type) {
StreamCodec<RegistryFriendlyByteBuf, T> original = type.streamCodec().cast();
return original.apply(ByteBufCodecs.registryFriendlyLengthPrefixed(Integer.MAX_VALUE));
}
}
);
private static final String REMOVED_PREFIX = "!";
final Reference2ObjectMap<DataComponentType<?>, Optional<?>> map;
private static StreamCodec<RegistryFriendlyByteBuf, DataComponentPatch> createStreamCodec(DataComponentPatch.CodecGetter codecGetter) {
return new StreamCodec<RegistryFriendlyByteBuf, DataComponentPatch>() {
public DataComponentPatch decode(RegistryFriendlyByteBuf input) {
int positiveCount = input.readVarInt();
int negativeCount = input.readVarInt();
if (positiveCount == 0 && negativeCount == 0) {
return DataComponentPatch.EMPTY;
} else {
int expectedSize = positiveCount + negativeCount;
Reference2ObjectMap<DataComponentType<?>, Optional<?>> map = new Reference2ObjectArrayMap<>(Math.min(expectedSize, 65536));
for (int i = 0; i < positiveCount; i++) {
DataComponentType<?> type = DataComponentType.STREAM_CODEC.decode(input);
Object value = codecGetter.apply(type).decode(input);
map.put(type, Optional.of(value));
}
for (int i = 0; i < negativeCount; i++) {
DataComponentType<?> type = DataComponentType.STREAM_CODEC.decode(input);
map.put(type, Optional.empty());
}
return new DataComponentPatch(map);
}
}
public void encode(RegistryFriendlyByteBuf output, DataComponentPatch patch) {
if (patch.isEmpty()) {
output.writeVarInt(0);
output.writeVarInt(0);
} else {
int positiveCount = 0;
int negativeCount = 0;
for (it.unimi.dsi.fastutil.objects.Reference2ObjectMap.Entry<DataComponentType<?>, Optional<?>> entry : Reference2ObjectMaps.fastIterable(
patch.map
)) {
if (entry.getValue().isPresent()) {
positiveCount++;
} else {
negativeCount++;
}
}
output.writeVarInt(positiveCount);
output.writeVarInt(negativeCount);
for (it.unimi.dsi.fastutil.objects.Reference2ObjectMap.Entry<DataComponentType<?>, Optional<?>> entryx : Reference2ObjectMaps.fastIterable(
patch.map
)) {
Optional<?> value = entryx.getValue();
if (value.isPresent()) {
DataComponentType<?> type = entryx.getKey();
DataComponentType.STREAM_CODEC.encode(output, type);
this.encodeComponent(output, type, value.get());
}
}
for (it.unimi.dsi.fastutil.objects.Reference2ObjectMap.Entry<DataComponentType<?>, Optional<?>> entryxx : Reference2ObjectMaps.fastIterable(
patch.map
)) {
if (entryxx.getValue().isEmpty()) {
DataComponentType<?> type = entryxx.getKey();
DataComponentType.STREAM_CODEC.encode(output, type);
}
}
}
}
private <T> void encodeComponent(RegistryFriendlyByteBuf output, DataComponentType<T> type, Object value) {
codecGetter.apply(type).encode(output, (T)value);
}
};
}
DataComponentPatch(Reference2ObjectMap<DataComponentType<?>, Optional<?>> map) {
this.map = map;
}
public static DataComponentPatch.Builder builder() {
return new DataComponentPatch.Builder();
}
public <T> @Nullable T get(DataComponentGetter prototype, DataComponentType<? extends T> type) {
return getFromPatchAndPrototype(this.map, prototype, type);
}
static <T> @Nullable T getFromPatchAndPrototype(
Reference2ObjectMap<DataComponentType<?>, Optional<?>> patch, DataComponentGetter prototype, DataComponentType<? extends T> type
) {
Optional<? extends T> value = (Optional<? extends T>)patch.get(type);
return (T)(value != null ? value.orElse(null) : prototype.get(type));
}
public Set<Entry<DataComponentType<?>, Optional<?>>> entrySet() {
return this.map.entrySet();
}
public int size() {
return this.map.size();
}
public DataComponentPatch forget(Predicate<DataComponentType<?>> test) {
if (this.isEmpty()) {
return EMPTY;
} else {
Reference2ObjectMap<DataComponentType<?>, Optional<?>> newMap = new Reference2ObjectArrayMap<>(this.map);
newMap.keySet().removeIf(test);
return newMap.isEmpty() ? EMPTY : new DataComponentPatch(newMap);
}
}
public boolean isEmpty() {
return this.map.isEmpty();
}
public DataComponentPatch.SplitResult split() {
if (this.isEmpty()) {
return DataComponentPatch.SplitResult.EMPTY;
} else {
DataComponentMap.Builder added = DataComponentMap.builder();
Set<DataComponentType<?>> removed = Sets.newIdentityHashSet();
this.map.forEach((type, optionalValue) -> {
if (optionalValue.isPresent()) {
added.setUnchecked((DataComponentType<?>)type, optionalValue.get());
} else {
removed.add((DataComponentType<?>)type);
}
});
return new DataComponentPatch.SplitResult(added.build(), removed);
}
}
@Override
public boolean equals(Object obj) {
return this == obj ? true : obj instanceof DataComponentPatch patch && this.map.equals(patch.map);
}
@Override
public int hashCode() {
return this.map.hashCode();
}
@Override
public String toString() {
return toString(this.map);
}
static String toString(Reference2ObjectMap<DataComponentType<?>, Optional<?>> map) {
StringBuilder builder = new StringBuilder();
builder.append('{');
boolean first = true;
for (Entry<DataComponentType<?>, Optional<?>> entry : Reference2ObjectMaps.fastIterable(map)) {
if (first) {
first = false;
} else {
builder.append(", ");
}
Optional<?> value = entry.getValue();
if (value.isPresent()) {
builder.append(entry.getKey());
builder.append("=>");
builder.append(value.get());
} else {
builder.append("!");
builder.append(entry.getKey());
}
}
builder.append('}');
return builder.toString();
}
public static class Builder {
private final Reference2ObjectMap<DataComponentType<?>, Optional<?>> map = new Reference2ObjectArrayMap<>();
private Builder() {
}
public <T> DataComponentPatch.Builder set(DataComponentType<T> type, T value) {
this.map.put(type, Optional.of(value));
return this;
}
public <T> DataComponentPatch.Builder remove(DataComponentType<T> type) {
this.map.put(type, Optional.empty());
return this;
}
public <T> DataComponentPatch.Builder set(TypedDataComponent<T> component) {
return this.set(component.type(), component.value());
}
public <T> DataComponentPatch.Builder set(Iterable<TypedDataComponent<?>> components) {
for (TypedDataComponent<?> component : components) {
this.set(component);
}
return this;
}
public DataComponentPatch build() {
return this.map.isEmpty() ? DataComponentPatch.EMPTY : new DataComponentPatch(this.map);
}
}
@FunctionalInterface
private interface CodecGetter {
<T> StreamCodec<? super RegistryFriendlyByteBuf, T> apply(DataComponentType<T> type);
}
private record PatchKey(DataComponentType<?> type, boolean removed) {
public static final Codec<DataComponentPatch.PatchKey> CODEC = Codec.STRING
.flatXmap(
string -> {
boolean removed = string.startsWith("!");
if (removed) {
string = string.substring("!".length());
}
Identifier id = Identifier.tryParse(string);
DataComponentType<?> type = BuiltInRegistries.DATA_COMPONENT_TYPE.getValue(id);
if (type == null) {
return DataResult.error(() -> "No component with type: '" + id + "'");
} else {
return type.isTransient()
? DataResult.error(() -> "'" + id + "' is not a persistent component")
: DataResult.success(new DataComponentPatch.PatchKey(type, removed));
}
},
key -> {
DataComponentType<?> type = key.type();
Identifier id = BuiltInRegistries.DATA_COMPONENT_TYPE.getKey(type);
return id == null
? DataResult.error(() -> "Unregistered component: " + type)
: DataResult.success(key.removed() ? "!" + id : id.toString());
}
);
public Codec<?> valueCodec() {
return this.removed ? Codec.EMPTY.codec() : this.type.codecOrThrow();
}
}
public record SplitResult(DataComponentMap added, Set<DataComponentType<?>> removed) {
public static final DataComponentPatch.SplitResult EMPTY = new DataComponentPatch.SplitResult(DataComponentMap.EMPTY, Set.of());
}
}引用的其他类
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
DataComponentMap.builder()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ByteBufCodecs.registryFriendlyLengthPrefixed()
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Identifier.tryParse()
- 引用位置: