Skip to content

类型支持 ​

自 2.0.0

LDLib2 已经为同步和持久化提供了大量的类型支持。

内置支持 ​

INFO

请查看 GitHub 以获取最新的支持列表。

  • Java 中的原生类型(数字、布尔值、字符串、枚举等)
类型优先级只读
int / Integer-1-
long / Long-1-
float / Float-1-
double / Double-1-
boolean / Boolean-1-
byte / Byte-1-
short / Short-1-
char / Character-1-
String-1-
Enum<?>-1-
Number1000-
UUID100-
T[]-1取决于 T
Collection<?>-1✅
Map<K, V>-1✅

Map 支持

自 2.2.8

从 2.2.8 起,LDLib2 支持对 Map<K, V> 进行同步和持久化。K 和 V 都会通过各自的 accessor 处理,因此 key 和 value 的类型本身也必须是受支持的类型。

Map 会作为只读容器管理。当 key 和 value 的 accessor 都是 direct 时,LDLib2 可以在反序列化时清空并重建 map。如果 key 或 value 类型是 read-only,则两侧的 map 结构必须已经匹配,或者在字段上使用 @ReadOnlyManaged 来序列化并重建结构。

  • Minecraft 中的类型(Block、Item、Fluid 等)
类型优先级只读
Block100-
Item100-
Fluid100-
EntityType<?>100-
BlockEntityType<?>100-
BlockState100-
ResourceLocation100-
AABB1000-
BlockPos1000-
FluidStack1000-
ItemStack1000-
RecipeHolder<?>1000-
Tag2000-
Component2000-
INBTSerializable<?>2000✅
  • LDLib2 或其他模组中的类型。
类型优先级只读
UIEvent100-
Position100-
Size100-
Pivot100-
Range100-
Vector3f1000-
Vector4f1000-
Vector2f1000-
Vector2i1000-
Quaternionf1000-
IGuiTexture1000-
IRenderer1000-
IResourcePath1000-
IManaged1500✅

添加自定义类型支持 ​

要添加对新类型的支持,你需要注册该类型的 IAccessor<TYPE>。所有类型可以分为两组:direct(直接)和 read-only(只读)。

INFO

  • direct 指的是可以为空,并且在管理生命周期内有已知方法可以创建该类型新实例的类型。
  • read-only 指的是在管理生命周期内不能为空且不可变的类型(例如 INBTSerializable<?> 和 Collection<?>)。所有修改都应通过其 API 完成。

你可以使用 AccessorRegistries.registerAccessor 来注册访问器。一般来说,你可以在任何地方注册你的访问器,但我们建议在 LDLibPlugin#onLoad 中进行。


注册一个 direct 类型 ​

你可以使用 CustomDirectAccessor 轻松注册新类型。

什么是 Mark?

Mark 是管理生命周期中的一个快照。LDLib2 会为当前值生成 mark 并在之后进行比较,以确定其是否发生了变化。 如果未定义 Mark,它将存储当前值作为 mark。如果类型的内部值是不可变的(例如 UUID、ResourceLocation),这是可行的。否则,你最好设置一种获取 mark 的方式。

方法是否可选说明
codec必需提供用于持久化的 codec
streamCodec必需提供用于同步的 StreamCodec
customMark可选提供获取和比较 mark 的函数
copyMark可选从值中复制 mark。这将使用 Objects#equals(Object, Object) 来比较 mark。请确保对象支持 Object#equals(Object)。
codecMark可选这将使用 JavaOps 基于当前值生成 mark。
java
AccessorRegistries.registerAccessor(CustomDirectAccessor.builder(Quaternionf.class)
    .codec(ExtraCodecs.QUATERNIONF)
    .streamCodec(ByteBufCodecs.QUATERNIONF)
    .copyMark(Quaternionf::new)
    .build());

AccessorRegistries.registerAccessor(CustomDirectAccessor.builder(ItemStack.class)
    .codec(ItemStack.OPTIONAL_CODEC)
    .streamCodec(ItemStack.OPTIONAL_STREAM_CODEC)
    .customMark(ItemStack::copy, ItemStack::matches)
    .build());

注册一个 read-only 类型 ​

一般来说,你并不真的需要这样做。因为你可以让你自己的类继承自 INBTSerializable。 如果你确实需要,请实现 IReadOnlyAccessor<TYPE> 并注册它,查看代码注释以获取更多使用细节。

Released under the MIT License.