扩展ISyncManager支持指定Key来查询Data
This commit is contained in:
parent
ce77003875
commit
7fca59b84c
|
|
@ -33,7 +33,7 @@ mod_name=3944Realms 's Lib Mod
|
|||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=MIT
|
||||
# The mod version. See https://semver.org/
|
||||
mod_version=0.0.11
|
||||
mod_version=0.0.12
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ public class SyncManagerRegisterEvent extends Event {
|
|||
/**
|
||||
* 类型安全的同步管理器注册
|
||||
*/
|
||||
public <T extends ISyncData<?>> void registerSyncManager(
|
||||
public <K, T extends ISyncData<?>> void registerSyncManager(
|
||||
ResourceLocation id,
|
||||
ISyncManager<T> syncManager,
|
||||
ISyncManager<K, T> syncManager,
|
||||
Capability<T> capability
|
||||
) {
|
||||
syncs2Manager.registerManager(id, syncManager, capability);
|
||||
|
|
@ -68,9 +68,9 @@ public class SyncManagerRegisterEvent extends Event {
|
|||
/**
|
||||
* 完整的类型安全注册
|
||||
*/
|
||||
public <T extends ISyncData<?>> void registerComplete(
|
||||
public <K, T extends ISyncData<?>> void registerComplete(
|
||||
ResourceLocation id,
|
||||
ISyncManager<T> syncManager,
|
||||
ISyncManager<K, T> syncManager,
|
||||
Capability<T> capability,
|
||||
Class<?>... allowedEntityClasses
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -36,14 +36,9 @@ public class CommonHandler {
|
|||
|
||||
@SubscribeEvent
|
||||
public static void onWorldLoad(LevelEvent.Load event) {
|
||||
if (event.getLevel().isClientSide() || !(event.getLevel() instanceof ServerLevel serverLevel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getLevel().isClientSide() || !(event.getLevel() instanceof ServerLevel serverLevel)) return;
|
||||
// 只处理主世界(避免多次初始化)
|
||||
if (!serverLevel.dimension().equals(Level.OVERWORLD)) {
|
||||
return;
|
||||
}
|
||||
if (!serverLevel.dimension().equals(Level.OVERWORLD)) return;
|
||||
|
||||
synchronized (Game.class) {
|
||||
if (!isInitialized) {
|
||||
|
|
@ -56,25 +51,17 @@ public class CommonHandler {
|
|||
}
|
||||
@SubscribeEvent
|
||||
public static void onWorldLoad(LevelEvent.Unload event) {
|
||||
if (event.getLevel().isClientSide() || !(event.getLevel() instanceof ServerLevel serverLevel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!serverLevel.dimension().equals(Level.OVERWORLD)) {
|
||||
return;
|
||||
}
|
||||
if (event.getLevel().isClientSide() || !(event.getLevel() instanceof ServerLevel serverLevel)) return;
|
||||
if (!serverLevel.dimension().equals(Level.OVERWORLD)) return;
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onServerTick(TickEvent.ServerTickEvent event) {
|
||||
if (event.phase == TickEvent.Phase.END) {
|
||||
if (syncData2Manager == null) {
|
||||
return;
|
||||
}
|
||||
if (event.getServer().getTickCount() % 10 == 0) {
|
||||
if (syncData2Manager == null) return;
|
||||
if (event.getServer().getTickCount() % 10 == 0)
|
||||
syncData2Manager.forEach(((resourceLocation, iSyncManager) -> iSyncManager.foreach(ISyncData::makeDirty)));
|
||||
}
|
||||
syncData2Manager.forEach(((resourceLocation, iSyncManager) -> iSyncManager.foreach(ISyncData::checkIfDirtyThenUpdate)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,21 @@ package top.r3944realms.lib39.core.sync;
|
|||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface ISyncManager<T extends ISyncData<?>> {
|
||||
Set<T> getSyncSet();
|
||||
default void track(T instance) {
|
||||
public interface ISyncManager<K,T extends ISyncData<?>> {
|
||||
Map<K, T> getSyncMap();
|
||||
default Set<T> getSyncSet() {
|
||||
return new HashSet<>(getSyncMap().values());
|
||||
}
|
||||
default void track(K key, T instance) {
|
||||
Set<T> syncSet = checkAndGetSet();
|
||||
syncSet.add(instance);
|
||||
}
|
||||
default void untrack(T instance) {
|
||||
default void untrack(K key, T instance) {
|
||||
Set<T> syncSet = checkAndGetSet();
|
||||
syncSet.remove(instance);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,29 +6,31 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class SyncData2Manager {
|
||||
private final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap();
|
||||
private final Map<ResourceLocation, TypedSyncEntry<?, ?>> typedEntries = Maps.newConcurrentMap();
|
||||
|
||||
private static class TypedSyncEntry<T extends ISyncData<?>> {
|
||||
final ISyncManager<T> manager;
|
||||
final Capability<T> capability;
|
||||
private static class TypedSyncEntry<K, T extends ISyncData<?>> {
|
||||
final ISyncManager<K, T> manager;
|
||||
@Nullable
|
||||
Capability<T> capability;
|
||||
final Set<Class<?>> allowedClasses;
|
||||
|
||||
TypedSyncEntry(ISyncManager<T> manager, Capability<T> capability) {
|
||||
TypedSyncEntry(ISyncManager<K, T> manager, @Nullable Capability<T> capability) {
|
||||
this.manager = manager;
|
||||
this.capability = capability;
|
||||
this.allowedClasses = Sets.newConcurrentHashSet();
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends ISyncData<?>> void registerManager(
|
||||
public <K, T extends ISyncData<?>> void registerManager(
|
||||
ResourceLocation key,
|
||||
ISyncManager<T> manager,
|
||||
ISyncManager<K, T> manager,
|
||||
Capability<T> capability
|
||||
) {
|
||||
Objects.requireNonNull(key, "ResourceLocation key cannot be null");
|
||||
|
|
@ -42,27 +44,27 @@ public class SyncData2Manager {
|
|||
* 向后兼容的注册方法(只注册管理器,不注册能力)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void registerManager(ResourceLocation key, ISyncManager<? extends ISyncData<?>> manager) {
|
||||
public void registerManager(ResourceLocation key, ISyncManager<?, ? extends ISyncData<?>> manager) {
|
||||
Objects.requireNonNull(key, "ResourceLocation key cannot be null");
|
||||
Objects.requireNonNull(manager, "Sync manager cannot be null");
|
||||
|
||||
// 创建一个虚拟的 TypedSyncEntry,但 capability 为 null
|
||||
// 注意:这种方法会限制类型安全的功能
|
||||
typedEntries.put(key, new TypedSyncEntry<>(
|
||||
(ISyncManager<ISyncData<?>>) manager,
|
||||
(ISyncManager<?, ISyncData<?>>) manager,
|
||||
null
|
||||
));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends ISyncData<?>> Optional<ISyncManager<T>> getManager(ResourceLocation key) {
|
||||
TypedSyncEntry<?> entry = typedEntries.get(key);
|
||||
return entry != null ? Optional.of((ISyncManager<T>) entry.manager) : Optional.empty();
|
||||
public <K, T extends ISyncData<?>> Optional<ISyncManager<K, T>> getManager(ResourceLocation key) {
|
||||
TypedSyncEntry<?,?> entry = typedEntries.get(key);
|
||||
return entry != null ? Optional.of((ISyncManager<K,T>) entry.manager) : Optional.empty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends ISyncData<?>> Optional<Capability<T>> getCapability(ResourceLocation key) {
|
||||
TypedSyncEntry<?> entry = typedEntries.get(key);
|
||||
TypedSyncEntry<?, ?> entry = typedEntries.get(key);
|
||||
if (entry != null && entry.capability != null) {
|
||||
return Optional.of((Capability<T>) entry.capability);
|
||||
}
|
||||
|
|
@ -77,7 +79,7 @@ public class SyncData2Manager {
|
|||
return;
|
||||
}
|
||||
|
||||
TypedSyncEntry<?> entry = typedEntries.get(key);
|
||||
TypedSyncEntry<?, ?> entry = typedEntries.get(key);
|
||||
if (entry != null) {
|
||||
entry.allowedClasses.addAll(Arrays.asList(classes));
|
||||
}
|
||||
|
|
@ -90,7 +92,7 @@ public class SyncData2Manager {
|
|||
Objects.requireNonNull(key, "ResourceLocation key cannot be null");
|
||||
Objects.requireNonNull(classes, "Classes array cannot be null");
|
||||
|
||||
TypedSyncEntry<?> entry = typedEntries.get(key);
|
||||
TypedSyncEntry<?, ?> entry = typedEntries.get(key);
|
||||
if (entry != null && classes.length > 0) {
|
||||
Arrays.asList(classes).forEach(entry.allowedClasses::remove);
|
||||
|
||||
|
|
@ -104,10 +106,10 @@ public class SyncData2Manager {
|
|||
Objects.requireNonNull(key, "ResourceLocation key cannot be null");
|
||||
Objects.requireNonNull(capability, "Capability cannot be null");
|
||||
|
||||
TypedSyncEntry<?> entry = typedEntries.get(key);
|
||||
TypedSyncEntry<?, ?> entry = typedEntries.get(key);
|
||||
if (entry != null) {
|
||||
// 更新现有条目的能力
|
||||
updateCapabilityInEntry(entry, capability);
|
||||
updateCapabilityInEntry(key, entry, capability);
|
||||
} else throw new IllegalArgumentException("No manager found for " + key);
|
||||
}
|
||||
|
||||
|
|
@ -117,10 +119,10 @@ public class SyncData2Manager {
|
|||
public void unbindCapability(ResourceLocation key) {
|
||||
Objects.requireNonNull(key, "ResourceLocation key cannot be null");
|
||||
|
||||
TypedSyncEntry<?> entry = typedEntries.get(key);
|
||||
TypedSyncEntry<?, ?> entry = typedEntries.get(key);
|
||||
if (entry != null) {
|
||||
// 将能力设置为null,但保留管理器和其他配置
|
||||
updateCapabilityInEntry(entry, null);
|
||||
updateCapabilityInEntry(key, entry, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +132,7 @@ public class SyncData2Manager {
|
|||
public void clearAllowedEntityClasses(ResourceLocation key) {
|
||||
Objects.requireNonNull(key, "ResourceLocation key cannot be null");
|
||||
|
||||
TypedSyncEntry<?> entry = typedEntries.get(key);
|
||||
TypedSyncEntry<?, ?> entry = typedEntries.get(key);
|
||||
if (entry != null) {
|
||||
entry.allowedClasses.clear();
|
||||
}
|
||||
|
|
@ -140,7 +142,7 @@ public class SyncData2Manager {
|
|||
Objects.requireNonNull(key, "ResourceLocation key cannot be null");
|
||||
Objects.requireNonNull(entityClass, "Entity class cannot be null");
|
||||
|
||||
TypedSyncEntry<?> entry = typedEntries.get(key);
|
||||
TypedSyncEntry<?, ?> entry = typedEntries.get(key);
|
||||
boolean isAllowed = false;
|
||||
if (entry != null) {
|
||||
for (Class<?> allowedClass : entry.allowedClasses) {
|
||||
|
|
@ -154,31 +156,33 @@ public class SyncData2Manager {
|
|||
}
|
||||
|
||||
// 类型安全的事件处理
|
||||
@SuppressWarnings("unchecked")
|
||||
public void trackEntityForManager(Entity entity, ResourceLocation managerId) {
|
||||
TypedSyncEntry<?> entry = typedEntries.get(managerId);
|
||||
TypedSyncEntry<UUID, ?> entry = (TypedSyncEntry<UUID, ?>) typedEntries.get(managerId);
|
||||
if (entry != null) {
|
||||
trackEntityWithTypedEntry(entity, entry);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends ISyncData<?>> void trackEntityWithTypedEntry(Entity entity, @NotNull TypedSyncEntry<T> entry) {
|
||||
private <T extends ISyncData<?>> void trackEntityWithTypedEntry(Entity entity, @NotNull TypedSyncEntry<UUID, T> entry) {
|
||||
if (entry.capability != null) {
|
||||
entity.getCapability(entry.capability)
|
||||
.ifPresent(entry.manager::track);
|
||||
.ifPresent(cap -> entry.manager.track(entity.getUUID(), cap));
|
||||
}
|
||||
}
|
||||
// 类型安全的事件处理 - 取消跟踪实体
|
||||
@SuppressWarnings("unchecked")
|
||||
public void untrackEntityForManager(Entity entity, ResourceLocation managerId) {
|
||||
TypedSyncEntry<?> entry = typedEntries.get(managerId);
|
||||
TypedSyncEntry<UUID, ?> entry = (TypedSyncEntry<UUID, ?>) typedEntries.get(managerId);
|
||||
if (entry != null) {
|
||||
untrackEntityWithTypedEntry(entity, entry);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends ISyncData<?>> void untrackEntityWithTypedEntry(Entity entity, @NotNull TypedSyncEntry<T> entry) {
|
||||
private <T extends ISyncData<?>> void untrackEntityWithTypedEntry(Entity entity, @NotNull TypedSyncEntry<UUID, T> entry) {
|
||||
if (entry.capability != null) {
|
||||
entity.getCapability(entry.capability)
|
||||
.ifPresent(entry.manager::untrack);
|
||||
.ifPresent(cap -> entry.manager.track(entity.getUUID(), cap));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -215,13 +219,13 @@ public class SyncData2Manager {
|
|||
* 强制清理管理器中的所有跟踪数据
|
||||
*/
|
||||
public void clearAllTrackedData(ResourceLocation managerId) {
|
||||
TypedSyncEntry<?> entry = typedEntries.get(managerId);
|
||||
TypedSyncEntry<?, ?> entry = typedEntries.get(managerId);
|
||||
if (entry != null) {
|
||||
clearTrackedDataForEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends ISyncData<?>> void clearTrackedDataForEntry(@NotNull TypedSyncEntry<T> entry) {
|
||||
private <K, T extends ISyncData<?>> void clearTrackedDataForEntry(@NotNull TypedSyncEntry<K, T> entry) {
|
||||
// 获取当前跟踪的集合并清空
|
||||
Set<T> syncSet = entry.manager.getSyncSet();
|
||||
if (syncSet != null) {
|
||||
|
|
@ -240,11 +244,11 @@ public class SyncData2Manager {
|
|||
|
||||
// 辅助方法:更新条目的能力
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends ISyncData<?>> void updateCapabilityInEntry(TypedSyncEntry<?> entry, Capability<T> newCapability) {
|
||||
TypedSyncEntry<T> typedEntry = (TypedSyncEntry<T>) entry;
|
||||
// 由于 capability 是 final,需要替换整个 entry
|
||||
// 在实际实现中,可能需要将 capability 改为非 final 或使用不同的设计
|
||||
// 这里假设重构了 TypedSyncEntry 使 capability 可变
|
||||
private <K, T extends ISyncData<?>> void updateCapabilityInEntry(ResourceLocation id, TypedSyncEntry<?,?> entry, Capability<T> newCapability) {
|
||||
TypedSyncEntry<K, T> typedEntry = (TypedSyncEntry<K, T>) entry;
|
||||
//重构了 TypedSyncEntry 使 capability 可变
|
||||
typedEntry.capability = newCapability;
|
||||
typedEntries.computeIfPresent(id, (resourceLocation, typedSyncEntry) -> typedEntry);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -253,7 +257,7 @@ public class SyncData2Manager {
|
|||
return Collections.unmodifiableSet(typedEntries.keySet());
|
||||
}
|
||||
|
||||
public void forEach(BiConsumer<ResourceLocation, ISyncManager<?>> consumer) {
|
||||
public void forEach(BiConsumer<ResourceLocation, ISyncManager<?,?>> consumer) {
|
||||
Objects.requireNonNull(consumer, "Consumer cannot be null");
|
||||
typedEntries.forEach((key, entry) -> consumer.accept(key, entry.manager));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader string(String key, Consumer<String> setter, String defaultValue) {
|
||||
public NBTReader string(String key, @NotNull Consumer<String> setter, String defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getString(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader byteValue(String key, Consumer<Byte> setter, byte defaultValue) {
|
||||
public NBTReader byteValue(String key, @NotNull Consumer<Byte> setter, byte defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getByte(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader shortValue(String key, Consumer<Short> setter, short defaultValue) {
|
||||
public NBTReader shortValue(String key, @NotNull Consumer<Short> setter, short defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getShort(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader intValue(String key, Consumer<Integer> setter, int defaultValue) {
|
||||
public NBTReader intValue(String key, @NotNull Consumer<Integer> setter, int defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getInt(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader longValue(String key, Consumer<Long> setter, long defaultValue) {
|
||||
public NBTReader longValue(String key, @NotNull Consumer<Long> setter, long defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getLong(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader floatValue(String key, Consumer<Float> setter, float defaultValue) {
|
||||
public NBTReader floatValue(String key, @NotNull Consumer<Float> setter, float defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getFloat(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader doubleValue(String key, Consumer<Double> setter, double defaultValue) {
|
||||
public NBTReader doubleValue(String key, @NotNull Consumer<Double> setter, double defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getDouble(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader booleanValue(String key, Consumer<Boolean> setter, boolean defaultValue) {
|
||||
public NBTReader booleanValue(String key, @NotNull Consumer<Boolean> setter, boolean defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getBoolean(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -167,7 +167,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader uuid(String key, Consumer<UUID> setter, UUID defaultValue) {
|
||||
public NBTReader uuid(String key, @NotNull Consumer<UUID> setter, UUID defaultValue) {
|
||||
setter.accept(nbt.hasUUID(key) ? nbt.getUUID(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -180,7 +180,7 @@ public class NBTReader {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NBTReader compound(String key, Consumer<CompoundTag> setter, CompoundTag defaultValue) {
|
||||
public NBTReader compound(String key, @NotNull Consumer<CompoundTag> setter, CompoundTag defaultValue) {
|
||||
setter.accept(nbt.contains(key) ? nbt.getCompound(key) : defaultValue);
|
||||
return this;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user