扩展ISyncManager支持指定Key来查询Data

This commit is contained in:
叁玖领域 2025-10-15 18:50:27 +08:00
parent ce77003875
commit 7fca59b84c
6 changed files with 69 additions and 73 deletions

View File

@ -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

View File

@ -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
) {

View File

@ -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)));
}
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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;
}