SynchedEntityData.java

net.minecraft.network.syncher.SynchedEntityData

信息

  • 全限定名:net.minecraft.network.syncher.SynchedEntityData
  • 类型:public class
  • 包:net.minecraft.network.syncher
  • 源码路径:src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
  • 起始行号:L16
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L17
    • 说明:

      TODO

  • MAX_ID_VALUE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L18
    • 说明:

      TODO

  • ID_REGISTRY

    • 类型: ClassTreeIdRegistry
    • 修饰符: private static final
    • 源码定位: L19
    • 说明:

      TODO

  • entity

    • 类型: SyncedDataHolder
    • 修饰符: private final
    • 源码定位: L20
    • 说明:

      TODO

  • itemsById

    • 类型: SynchedEntityData.DataItem<?>[]
    • 修饰符: private final
    • 源码定位: L21
    • 说明:

      TODO

  • isDirty

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L22
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.network.syncher.SynchedEntityData.Builder

    • 类型: class
    • 修饰符: public static
    • 源码定位: L137
    • 说明:

      TODO

  • net.minecraft.network.syncher.SynchedEntityData.DataItem

    • 类型: class
    • 修饰符: public static
    • 源码定位: L171
    • 说明:

      TODO

  • net.minecraft.network.syncher.SynchedEntityData.DataValue

    • 类型: record
    • 修饰符: public
    • 源码定位: L212
    • 说明:

      TODO

构造器

private SynchedEntityData(SyncedDataHolder entity, SynchedEntityData.DataItem<?>[] itemsById) @ L24

  • 构造器名:SynchedEntityData
  • 源码定位:L24
  • 修饰符:private

参数:

  • entity: SyncedDataHolder
  • itemsById: SynchedEntityData.DataItem<?>[]

说明:

TODO

方法

下面的方法块按源码顺序生成。

public static <T> EntityDataAccessor<T> defineId(Class<?extends SyncedDataHolder> clazz, EntityDataSerializer<T> type) @ L29

  • 方法名:defineId
  • 源码定位:L29
  • 返回类型: EntityDataAccessor
  • 修饰符:public static

参数:

  • clazz: Class<?extends SyncedDataHolder>
  • type: EntityDataSerializer

说明:

TODO

private <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> accessor) @ L48

  • 方法名:getItem
  • 源码定位:L48
  • 返回类型: SynchedEntityData.DataItem
  • 修饰符:private

参数:

  • accessor: EntityDataAccessor

说明:

TODO

public <T> T get(EntityDataAccessor<T> accessor) @ L52

  • 方法名:get
  • 源码定位:L52
  • 返回类型: T
  • 修饰符:public

参数:

  • accessor: EntityDataAccessor

说明:

TODO

public <T> void set(EntityDataAccessor<T> accessor, T value) @ L56

  • 方法名:set
  • 源码定位:L56
  • 返回类型: void
  • 修饰符:public

参数:

  • accessor: EntityDataAccessor
  • value: T

说明:

TODO

public <T> void set(EntityDataAccessor<T> accessor, T value, boolean forceDirty) @ L60

  • 方法名:set
  • 源码定位:L60
  • 返回类型: void
  • 修饰符:public

参数:

  • accessor: EntityDataAccessor
  • value: T
  • forceDirty: boolean

说明:

TODO

public boolean isDirty() @ L70

  • 方法名:isDirty
  • 源码定位:L70
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public List<SynchedEntityData.DataValue<?>> packDirty() @ L74

  • 方法名:packDirty
  • 源码定位:L74
  • 返回类型:List<SynchedEntityData.DataValue<?>>
  • 修饰符:public

参数:

说明:

TODO

public List<SynchedEntityData.DataValue<?>> getNonDefaultValues() @ L92

  • 方法名:getNonDefaultValues
  • 源码定位:L92
  • 返回类型:List<SynchedEntityData.DataValue<?>>
  • 修饰符:public

参数:

说明:

TODO

public void assignValues(List<SynchedEntityData.DataValue<?>> items) @ L108

  • 方法名:assignValues
  • 源码定位:L108
  • 返回类型:void
  • 修饰符:public

参数:

  • items: List<SynchedEntityData.DataValue<?>>

说明:

TODO

private <T> void assignValue(SynchedEntityData.DataItem<T> dataItem, SynchedEntityData.DataValue<?> item) @ L118

  • 方法名:assignValue
  • 源码定位:L118
  • 返回类型: void
  • 修饰符:private

参数:

  • dataItem: SynchedEntityData.DataItem
  • item: SynchedEntityData.DataValue<?>

说明:

TODO

代码

public class SynchedEntityData {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final int MAX_ID_VALUE = 254;
    private static final ClassTreeIdRegistry ID_REGISTRY = new ClassTreeIdRegistry();
    private final SyncedDataHolder entity;
    private final SynchedEntityData.DataItem<?>[] itemsById;
    private boolean isDirty;
 
    private SynchedEntityData(SyncedDataHolder entity, SynchedEntityData.DataItem<?>[] itemsById) {
        this.entity = entity;
        this.itemsById = itemsById;
    }
 
    public static <T> EntityDataAccessor<T> defineId(Class<? extends SyncedDataHolder> clazz, EntityDataSerializer<T> type) {
        if (LOGGER.isDebugEnabled()) {
            try {
                Class<?> aClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
                if (!aClass.equals(clazz)) {
                    LOGGER.debug("defineId called for: {} from {}", clazz, aClass, new RuntimeException());
                }
            } catch (ClassNotFoundException var3) {
            }
        }
 
        int id = ID_REGISTRY.define(clazz);
        if (id > 254) {
            throw new IllegalArgumentException("Data value id is too big with " + id + "! (Max is 254)");
        } else {
            return type.createAccessor(id);
        }
    }
 
    private <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> accessor) {
        return (SynchedEntityData.DataItem<T>)this.itemsById[accessor.id()];
    }
 
    public <T> T get(EntityDataAccessor<T> accessor) {
        return this.getItem(accessor).getValue();
    }
 
    public <T> void set(EntityDataAccessor<T> accessor, T value) {
        this.set(accessor, value, false);
    }
 
    public <T> void set(EntityDataAccessor<T> accessor, T value, boolean forceDirty) {
        SynchedEntityData.DataItem<T> dataItem = this.getItem(accessor);
        if (forceDirty || ObjectUtils.notEqual(value, dataItem.getValue())) {
            dataItem.setValue(value);
            this.entity.onSyncedDataUpdated(accessor);
            dataItem.setDirty(true);
            this.isDirty = true;
        }
    }
 
    public boolean isDirty() {
        return this.isDirty;
    }
 
    public @Nullable List<SynchedEntityData.DataValue<?>> packDirty() {
        if (!this.isDirty) {
            return null;
        } else {
            this.isDirty = false;
            List<SynchedEntityData.DataValue<?>> result = new ArrayList<>();
 
            for (SynchedEntityData.DataItem<?> dataItem : this.itemsById) {
                if (dataItem.isDirty()) {
                    dataItem.setDirty(false);
                    result.add(dataItem.value());
                }
            }
 
            return result;
        }
    }
 
    public @Nullable List<SynchedEntityData.DataValue<?>> getNonDefaultValues() {
        List<SynchedEntityData.DataValue<?>> result = null;
 
        for (SynchedEntityData.DataItem<?> dataItem : this.itemsById) {
            if (!dataItem.isSetToDefault()) {
                if (result == null) {
                    result = new ArrayList<>();
                }
 
                result.add(dataItem.value());
            }
        }
 
        return result;
    }
 
    public void assignValues(List<SynchedEntityData.DataValue<?>> items) {
        for (SynchedEntityData.DataValue<?> item : items) {
            SynchedEntityData.DataItem<?> dataItem = this.itemsById[item.id];
            this.assignValue(dataItem, item);
            this.entity.onSyncedDataUpdated(dataItem.getAccessor());
        }
 
        this.entity.onSyncedDataUpdated(items);
    }
 
    private <T> void assignValue(SynchedEntityData.DataItem<T> dataItem, SynchedEntityData.DataValue<?> item) {
        if (!Objects.equals(item.serializer(), dataItem.accessor.serializer())) {
            throw new IllegalStateException(
                String.format(
                    Locale.ROOT,
                    "Invalid entity data item type for field %d on entity %s: old=%s(%s), new=%s(%s)",
                    dataItem.accessor.id(),
                    this.entity,
                    dataItem.value,
                    dataItem.value.getClass(),
                    item.value,
                    item.value.getClass()
                )
            );
        } else {
            dataItem.setValue((T)item.value);
        }
    }
 
    public static class Builder {
        private final SyncedDataHolder entity;
        private final SynchedEntityData.@Nullable DataItem<?>[] itemsById;
 
        public Builder(SyncedDataHolder entity) {
            this.entity = entity;
            this.itemsById = new SynchedEntityData.DataItem[SynchedEntityData.ID_REGISTRY.getCount(entity.getClass())];
        }
 
        public <T> SynchedEntityData.Builder define(EntityDataAccessor<T> accessor, T value) {
            int id = accessor.id();
            if (id > this.itemsById.length) {
                throw new IllegalArgumentException("Data value id is too big with " + id + "! (Max is " + this.itemsById.length + ")");
            } else if (this.itemsById[id] != null) {
                throw new IllegalArgumentException("Duplicate id value for " + id + "!");
            } else if (EntityDataSerializers.getSerializedId(accessor.serializer()) < 0) {
                throw new IllegalArgumentException("Unregistered serializer " + accessor.serializer() + " for " + id + "!");
            } else {
                this.itemsById[accessor.id()] = new SynchedEntityData.DataItem<>(accessor, value);
                return this;
            }
        }
 
        public SynchedEntityData build() {
            for (int i = 0; i < this.itemsById.length; i++) {
                if (this.itemsById[i] == null) {
                    throw new IllegalStateException("Entity " + this.entity.getClass() + " has not defined synched data value " + i);
                }
            }
 
            return new SynchedEntityData(this.entity, this.itemsById);
        }
    }
 
    public static class DataItem<T> {
        private final EntityDataAccessor<T> accessor;
        private T value;
        private final T initialValue;
        private boolean dirty;
 
        public DataItem(EntityDataAccessor<T> accessor, T initialValue) {
            this.accessor = accessor;
            this.initialValue = initialValue;
            this.value = initialValue;
        }
 
        public EntityDataAccessor<T> getAccessor() {
            return this.accessor;
        }
 
        public void setValue(T value) {
            this.value = value;
        }
 
        public T getValue() {
            return this.value;
        }
 
        public boolean isDirty() {
            return this.dirty;
        }
 
        public void setDirty(boolean dirty) {
            this.dirty = dirty;
        }
 
        public boolean isSetToDefault() {
            return this.initialValue.equals(this.value);
        }
 
        public SynchedEntityData.DataValue<T> value() {
            return SynchedEntityData.DataValue.create(this.accessor, this.value);
        }
    }
 
    public record DataValue<T>(int id, EntityDataSerializer<T> serializer, T value) {
        public static <T> SynchedEntityData.DataValue<T> create(EntityDataAccessor<T> accessor, T value) {
            EntityDataSerializer<T> serializer = accessor.serializer();
            return new SynchedEntityData.DataValue<>(accessor.id(), serializer, serializer.copy(value));
        }
 
        public void write(RegistryFriendlyByteBuf output) {
            int serializerId = EntityDataSerializers.getSerializedId(this.serializer);
            if (serializerId < 0) {
                throw new EncoderException("Unknown serializer type " + this.serializer);
            } else {
                output.writeByte(this.id);
                output.writeVarInt(serializerId);
                this.serializer.codec().encode(output, this.value);
            }
        }
 
        public static SynchedEntityData.DataValue<?> read(RegistryFriendlyByteBuf input, int id) {
            int type = input.readVarInt();
            EntityDataSerializer<?> serializer = EntityDataSerializers.getSerializer(type);
            if (serializer == null) {
                throw new DecoderException("Unknown serializer type " + type);
            } else {
                return read(input, id, serializer);
            }
        }
 
        private static <T> SynchedEntityData.DataValue<T> read(RegistryFriendlyByteBuf input, int id, EntityDataSerializer<T> serializer) {
            return new SynchedEntityData.DataValue<>(id, serializer, serializer.codec().decode(input));
        }
    }
}

引用的其他类