package io.gitlab.jfronny.libjf.data.manipulation.api; import io.gitlab.jfronny.commons.LazySupplier; import io.gitlab.jfronny.commons.concurrent.ScopedValue; import io.gitlab.jfronny.commons.throwable.ExceptionWrapper; import io.gitlab.jfronny.commons.throwable.ThrowingRunnable; import io.gitlab.jfronny.commons.throwable.ThrowingSupplier; import io.gitlab.jfronny.libjf.LibJf; import io.gitlab.jfronny.libjf.data.manipulation.impl.ResourcePackHook; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.resource.*; import net.minecraft.resource.metadata.ResourceMetadataReader; import net.minecraft.util.Identifier; import java.io.IOException; import java.io.InputStream; import java.util.function.Supplier; @SuppressWarnings("unused") public class UserResourceEvents { public static TVal disable(ThrowingSupplier then) throws TEx { try { return ScopedValue.getWhere(ResourcePackHook.DISABLED, true, then.orThrow()); } catch (ExceptionWrapper ew) { throw (TEx) ExceptionWrapper.unwrap(ew); } } public static void disable(ThrowingRunnable then) throws TEx { try { ScopedValue.runWhere(ResourcePackHook.DISABLED, true, then.orThrow()); } catch (ExceptionWrapper ew) { throw (TEx) ExceptionWrapper.unwrap(ew); } } public static final Event OPEN_ROOT = EventFactory.createArrayBacked(OpenRoot.class, listeners -> (fileName, previous, pack) -> { InputSupplier lazy = previous; for (OpenRoot listener : listeners) { lazy = listener.openRoot(fileName, lazy, pack); } return lazy; }); public static final Event OPEN = EventFactory.createArrayBacked(Open.class, listeners -> (type, id, previous, pack) -> { InputSupplier lazy = previous; for (Open listener : listeners) { lazy = listener.open(type, id, lazy, pack); } return lazy; }); public static final Event FIND_RESOURCE = EventFactory.createArrayBacked(FindResource.class, listeners -> (type, namespace, prefix, previous, pack) -> { ResourcePack.ResultConsumer lazy = previous; for (int i = listeners.length - 1; i >= 0; i--) { lazy = listeners[i].findResources(type, namespace, prefix, lazy, pack); } return lazy; }); public static final Event PARSE_METADATA = EventFactory.createArrayBacked(ParseMetadata.class, ParseMetadataHandler::new); // Here because generic targets don't work private static class ParseMetadataHandler implements ParseMetadata { private final ParseMetadata[] listeners; public ParseMetadataHandler(ParseMetadata[] listeners) { this.listeners = listeners; } @Override public T parseMetadata(ResourceMetadataReader reader, Supplier previous, ResourcePack pack) throws IOException { LazySupplier lazy = new LazySupplier<>(previous); for (ParseMetadata listener: listeners) { lazy = lazy.andThen(supplier -> { try { return listener.parseMetadata(reader, supplier, pack); } catch (IOException e) { LibJf.LOGGER.error("Could not call ResourcePack.OPEN_ROOT listener", e); return null; } }); } return lazy.get(); } } public interface OpenRoot { InputSupplier openRoot(String[] fileName, InputSupplier previous, ResourcePack pack); } public interface Open { InputSupplier open(ResourceType type, Identifier id, InputSupplier previous, ResourcePack pack); } public interface FindResource { ResourcePack.ResultConsumer findResources(ResourceType type, String namespace, String prefix, ResourcePack.ResultConsumer previous, ResourcePack pack); } public interface ParseMetadata { T parseMetadata(ResourceMetadataReader reader, Supplier previous, ResourcePack pack) throws IOException; } }