Skip to content

Commit

Permalink
Tidied up pack content managers
Browse files Browse the repository at this point in the history
  • Loading branch information
eggohito committed Oct 2, 2024
1 parent 76571c5 commit 8e07f54
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public Power parse(StringReader reader) throws CommandSyntaxException {

@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return CommandSource.suggestIdentifiers(PowerManager.streamIds(), builder);
return CommandSource.suggestIdentifiers(PowerManager.keySet().stream(), builder);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.JsonOps;
import io.github.apace100.apoli.Apoli;
import io.github.apace100.apoli.power.Power;
Expand All @@ -16,7 +17,9 @@
import io.github.apace100.calio.data.SerializableData;
import io.github.apace100.calio.util.TagLike;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
Expand All @@ -29,20 +32,18 @@
import net.minecraft.util.JsonHelper;
import net.minecraft.util.Util;
import net.minecraft.util.profiler.Profiler;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
* TODO: Implement an immutable storage structure like {@link PowerManager} -eggohito
*/
public class GlobalPowerSetManager extends IdentifiableMultiJsonDataLoader implements IdentifiableResourceReloadListener {

public static final Identifier PHASE = Apoli.identifier("phase/global_powers");
public static final Set<Identifier> DEPENDENCIES = Util.make(new HashSet<>(), set -> set.add(Apoli.identifier("powers")));
public static final Identifier ID = Apoli.identifier("global_powers");

public static final Set<Identifier> DISABLED = new HashSet<>();
public static final Map<Identifier, GlobalPowerSet> ALL = new HashMap<>();
private static final Object2ObjectOpenHashMap<Identifier, GlobalPowerSet> SETS_BY_ID = new Object2ObjectOpenHashMap<>();
private static final ObjectOpenHashSet<Identifier> DISABLED_SETS = new ObjectOpenHashSet<>();

private static final Map<Identifier, Integer> LOADING_PRIORITIES = new HashMap<>();
private static final Gson GSON = new GsonBuilder()
Expand All @@ -53,11 +54,11 @@ public class GlobalPowerSetManager extends IdentifiableMultiJsonDataLoader imple
public GlobalPowerSetManager() {
super(GSON, "global_powers", ResourceType.SERVER_DATA);

ServerEntityEvents.ENTITY_LOAD.addPhaseOrdering(PowerManager.PHASE, PHASE);
ServerEntityEvents.ENTITY_LOAD.register(PHASE, (entity, world) -> GlobalPowerSetUtil.applyGlobalPowers(entity));
ServerEntityEvents.ENTITY_LOAD.addPhaseOrdering(PowerManager.ID, ID);
ServerEntityEvents.ENTITY_LOAD.register(ID, (entity, world) -> GlobalPowerSetUtil.applyGlobalPowers(entity));

ServerLifecycleEvents.SYNC_DATA_PACK_CONTENTS.addPhaseOrdering(PowerManager.PHASE, PHASE);
ServerLifecycleEvents.SYNC_DATA_PACK_CONTENTS.register(PHASE, (player, joined) -> {
ServerLifecycleEvents.SYNC_DATA_PACK_CONTENTS.addPhaseOrdering(PowerManager.ID, ID);
ServerLifecycleEvents.SYNC_DATA_PACK_CONTENTS.register(ID, (player, joined) -> {
if (!joined) {
GlobalPowerSetUtil.applyGlobalPowers(player);
}
Expand All @@ -69,19 +70,20 @@ public GlobalPowerSetManager() {
protected void apply(MultiJsonDataContainer prepared, ResourceManager manager, Profiler profiler) {

Apoli.LOGGER.info("Reading global power sets from data packs...");
LOADING_PRIORITIES.clear();

DISABLED.clear();
ALL.clear();

Map<Identifier, List<PrioritizedEntry<GlobalPowerSet>>> loadedGlobalPowerSets = new Object2ObjectLinkedOpenHashMap<>();
DynamicRegistryManager dynamicRegistries = CalioServer.getDynamicRegistries().orElse(null);
startBuilding();

if (dynamicRegistries == null) {

Apoli.LOGGER.error("Can't read global power sets from data packs without access to dynamic registries!");
endBuilding();

return;

}

Map<Identifier, List<PrioritizedEntry<GlobalPowerSet>>> loadedGlobalPowerSets = new Object2ObjectLinkedOpenHashMap<>();
prepared.forEach((packName, id, jsonElement) -> {

try {
Expand Down Expand Up @@ -120,7 +122,7 @@ protected void apply(MultiJsonDataContainer prepared, ResourceManager manager, P
}

loadedGlobalPowerSets.computeIfAbsent(id, k -> new LinkedList<>()).add(entry);
DISABLED.remove(id);
DISABLED_SETS.remove(id);

LOADING_PRIORITIES.put(id, currLoadingPriority);

Expand All @@ -134,7 +136,11 @@ protected void apply(MultiJsonDataContainer prepared, ResourceManager manager, P

});

SerializableData.CURRENT_NAMESPACE = null;
SerializableData.CURRENT_PATH = null;

Apoli.LOGGER.info("Finished reading global power sets from data packs. Merging similar global power sets...");

loadedGlobalPowerSets.forEach((id, entries) -> {

AtomicReference<GlobalPowerSet> currentSet = new AtomicReference<>();
Expand All @@ -152,31 +158,27 @@ protected void apply(MultiJsonDataContainer prepared, ResourceManager manager, P

}

ALL.put(id, currentSet.get());
SETS_BY_ID.put(id, currentSet.get());

});

Apoli.LOGGER.info("Finished merging similar global power sets. Registry contains {} global power sets.", ALL.size());

SerializableData.CURRENT_NAMESPACE = null;
SerializableData.CURRENT_PATH = null;

LOADING_PRIORITIES.clear();
endBuilding();
Apoli.LOGGER.info("Finished merging similar global power sets. Registry contains {} global power sets.", size());

}

@Override
public void onReject(String packName, Identifier resourceId) {

if (!ALL.containsKey(resourceId)) {
DISABLED.add(resourceId);
if (!contains(resourceId)) {
disable(resourceId);
}

}

@Override
public Identifier getFabricId() {
return Apoli.identifier("global_powers");
return ID;
}

@Override
Expand Down Expand Up @@ -220,4 +222,74 @@ private static GlobalPowerSet merge(DynamicRegistryManager dynamicRegistries, Gl

}

public static DataResult<GlobalPowerSet> getResult(Identifier id) {
return contains(id)
? DataResult.success(SETS_BY_ID.get(id))
: DataResult.error(() -> "Couldn't get global power set from ID \"" + id + "\", as it wasn't registered!");
}

public static Optional<GlobalPowerSet> getOptional(Identifier id) {
return getResult(id).result();
}

@Nullable
public static GlobalPowerSet getNullable(Identifier id) {
return SETS_BY_ID.get(id);
}

public static GlobalPowerSet get(Identifier id) {
return getResult(id).getOrThrow();
}

public static Set<Map.Entry<Identifier, GlobalPowerSet>> entrySet() {
return new ObjectOpenHashSet<>(SETS_BY_ID.entrySet());
}

public static Set<Identifier> keySet() {
return new ObjectOpenHashSet<>(SETS_BY_ID.keySet());
}

public static Collection<GlobalPowerSet> values() {
return new ObjectOpenHashSet<>(SETS_BY_ID.values());
}

public static boolean isDisabled(Identifier id) {
return DISABLED_SETS.contains(id);
}

public static boolean contains(Identifier id) {
return SETS_BY_ID.containsKey(id);
}

public static int size() {
return SETS_BY_ID.size();
}

private static GlobalPowerSet remove(Identifier id) {
return SETS_BY_ID.remove(id);
}

public static void disable(Identifier id) {
remove(id);
DISABLED_SETS.add(id);
}

private static void startBuilding() {

LOADING_PRIORITIES.clear();

SETS_BY_ID.clear();
DISABLED_SETS.clear();

}

private static void endBuilding() {

LOADING_PRIORITIES.clear();

SETS_BY_ID.trim();
DISABLED_SETS.trim();

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class GlobalPowerSetUtil {
public static final Identifier POWER_SOURCE = Apoli.identifier("global");

public static List<GlobalPowerSet> getApplicableSets(EntityType<?> type) {
return GlobalPowerSetManager.ALL.values()
return GlobalPowerSetManager.values()
.stream()
.filter(gps -> gps.doesApply(type))
.sorted(GlobalPowerSet::compareTo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import io.github.apace100.apoli.Apoli;
import io.github.apace100.apoli.power.Power;
import io.github.apace100.calio.codec.CalioPacketCodecs;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
Expand All @@ -12,33 +11,45 @@

import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public record SyncPowersS2CPacket(Map<Identifier, Power> powersById) implements CustomPayload {

public static final Id<SyncPowersS2CPacket> PACKET_ID = new Id<>(Apoli.identifier("s2c/sync_power_registry"));
public static final PacketCodec<RegistryByteBuf, SyncPowersS2CPacket> PACKET_CODEC = PacketCodec.of(SyncPowersS2CPacket::write, SyncPowersS2CPacket::read);

private static final PacketCodec<RegistryByteBuf, Collection<Power>> POWERS_PACKET_CODEC = CalioPacketCodecs.collection(ObjectArrayList::new, Power.DATA_TYPE::packetCodec);

public static SyncPowersS2CPacket read(RegistryByteBuf buf) {

try {
return new SyncPowersS2CPacket(POWERS_PACKET_CODEC.decode(buf)

Collection<Power> powers = new ObjectArrayList<>();
int powersCount = buf.readVarInt();

for (int i = 0; i < powersCount; i++) {
powers.add(Power.DATA_TYPE.receive(buf));
}

return new SyncPowersS2CPacket(powers
.stream()
.map(power -> Map.entry(power.getId(), power))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldP, newP) -> newP, Object2ObjectLinkedOpenHashMap::new)));
.collect(Collectors.toMap(Power::getId, Function.identity(), (oldPower, newPower) -> newPower, Object2ObjectOpenHashMap::new)));

}

catch (Exception e) {
Apoli.LOGGER.error(e);
Apoli.LOGGER.error(e.getMessage());
throw e;
}

}

public void write(RegistryByteBuf buf) {
POWERS_PACKET_CODEC.encode(buf, powersById().values());

Collection<Power> powers = powersById().values();

buf.writeVarInt(powers.size());
powers.forEach(power -> Power.DATA_TYPE.send(buf, power));

}

@Override
Expand Down
15 changes: 10 additions & 5 deletions src/main/java/io/github/apace100/apoli/power/Power.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,22 @@ public <T> RecordBuilder<T> encode(Power input, DynamicOps<T> ops, RecordBuilder
serializableData -> PacketCodec.ofStatic(
(buf, value) -> {

PowerTypeFactory<?>.Instance instance = value.getFactoryInstance();
if (instance == null) {
PowerTypeFactory<?>.Instance factoryInstance = value.getFactoryInstance();
if (factoryInstance == null) {
return;
}

buf.writeIdentifier(value.getId());
serializableData.send(buf, serializableData.instance()
.set("id", value.getId())
.set("type", instance.getFactory())
.set("type", factoryInstance.getFactory())
.set("name", value.getName())
.set("description", value.getDescription())
.set("hidden", value.isHidden()));

instance.getSerializableData().send(buf, instance.getData());
SerializableData.Instance factoryInstanceData = factoryInstance.getData();
factoryInstance.getSerializableData().send(buf, factoryInstanceData);

switch (value) {
case MultiplePower multiplePower -> {
buf.writeByte(0);
Expand All @@ -127,7 +129,10 @@ public <T> RecordBuilder<T> encode(Power input, DynamicOps<T> ops, RecordBuilder
try {

PowerTypeFactory<?> factory = powerData.get("type");
Power basePower = new Power(factory.receive(buf), powerData);
SerializableData.Instance factoryInstanceData = factory.getSerializableData().receive(buf);

PowerTypeFactory<?>.Instance factoryInstance = factory.fromData(factoryInstanceData);
Power basePower = new Power(factoryInstance, powerData);

return switch (buf.readByte()) {
case 0 ->
Expand Down
Loading

0 comments on commit 8e07f54

Please sign in to comment.