// Path: src/main/java/com/github/worldsender/mcanm/common/resource/IResource.java
// public interface IResource extends Closeable {
// 	/**
// 	 * Gets the currently open DataInputStream.
// 	 * 
// 	 * @return
// 	 */
// 	DataInputStream getInputStream();
// 
// 	default String getResourceName() {
// 		return getOrigin().getResourceName();
// 	}
// 
// 	/**
// 	 * Gets the origin of the resource. If the resource has no conventional, then
// 	 * 
// 	 * @return
// 	 */
// 	IResourceLocation getOrigin();
// }
// 
// Path: src/main/java/com/github/worldsender/mcanm/common/resource/IResourceLocation.java
// public interface IResourceLocation {
// 	/**
// 	 * For data that has no definite location, this is suitable (e.g. one-time streams)
// 	 */
// 	public static final IResourceLocation UNKNOWN_LOCATION = new IResourceLocation() {
// 		@Override
// 		public IResource open() throws IOException {
// 			throw new NoSuchFileException("Unknown location");
// 		}
// 
// 		@Override
// 		public String getResourceName() {
// 			return "<unknown resource>";
// 		}
// 
// 		@Override
// 		public boolean shouldCache() {
// 			return false;
// 		}
// 
// 		@Override
// 		public void registerReloadListener(Consumer<IResourceLocation> reloadListener) {
// 			reloadListener.accept(this);
// 			// Don't store it, this location won't change
// 		}
// 	};
// 
// 	/**
// 	 * Opens the resource location described by this resource location.
// 	 * 
// 	 * @return an empty optional if the resource is currently (expectedly) absent
// 	 * @throws IOException
// 	 *             if the resource is absent unexpectedly
// 	 */
// 	IResource open() throws IOException;
// 
// 	/**
// 	 * Registers a listener that is being fired every time this resource changes. What "changes" means is deliberately
// 	 * left unspecified but a good example would be whenever the {@link Minecraft#getResourceManager()} changes, for
// 	 * example when a new resource pack is loaded.<br>
// 	 * <b>The initial stick is considered a change already, so this method should also fire the listener once.</b>
// 	 * 
// 	 * @param reloadListener
// 	 */
// 	void registerReloadListener(Consumer<IResourceLocation> reloadListener);
// 
// 	/**
// 	 * A descriptive name of the resource, perhaps the path
// 	 * 
// 	 * @return
// 	 */
// 	String getResourceName();
// 
// 	/**
// 	 * Returns false if this resource should not be cached, e.g. it is a one-time stream. When a
// 	 * {@link IResourceLocation} may get cached, {@link #open()} should succeed multiple times and return the same data
// 	 * every time, until the resource is reloaded.
// 	 * 
// 	 * @return
// 	 */
// 	boolean shouldCache();
// 
// 	@Override
// 	boolean equals(Object obj);
// 
// 	@Override
// 	int hashCode();
// }


import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import com.github.worldsender.mcanm.common.resource.IResource;
import com.github.worldsender.mcanm.common.resource.IResourceLocation;
package com.github.worldsender.mcanm.common.util;



public class ResourceCache<D> {
	private Map<IResourceLocation, D> cache;

	public ResourceCache() {
		cache = new HashMap<>();
	}

	public D getOrCompute(IResource resource, Function<IResource, D> loadFunc) {
		IResourceLocation location = resource.getOrigin();
		if (location.shouldCache()) {
			location.registerReloadListener(this::changedCallback);
// Path: src/main/java/com/github/worldsender/mcanm/common/resource/IResource.java
// public interface IResource extends Closeable {
// 	/**
// 	 * Gets the currently open DataInputStream.
// 	 * 
// 	 * @return
// 	 */
// 	DataInputStream getInputStream();
// 
// 	default String getResourceName() {
// 		return getOrigin().getResourceName();
// 	}
// 
// 	/**
// 	 * Gets the origin of the resource. If the resource has no conventional, then
// 	 * 
// 	 * @return
// 	 */
// 	IResourceLocation getOrigin();
// }
// 
// Path: src/main/java/com/github/worldsender/mcanm/common/resource/IResourceLocation.java
// public interface IResourceLocation {
// 	/**
// 	 * For data that has no definite location, this is suitable (e.g. one-time streams)
// 	 */
// 	public static final IResourceLocation UNKNOWN_LOCATION = new IResourceLocation() {
// 		@Override
// 		public IResource open() throws IOException {
// 			throw new NoSuchFileException("Unknown location");
// 		}
// 
// 		@Override
// 		public String getResourceName() {
// 			return "<unknown resource>";
// 		}
// 
// 		@Override
// 		public boolean shouldCache() {
// 			return false;
// 		}
// 
// 		@Override
// 		public void registerReloadListener(Consumer<IResourceLocation> reloadListener) {
// 			reloadListener.accept(this);
// 			// Don't store it, this location won't change
// 		}
// 	};
// 
// 	/**
// 	 * Opens the resource location described by this resource location.
// 	 * 
// 	 * @return an empty optional if the resource is currently (expectedly) absent
// 	 * @throws IOException
// 	 *             if the resource is absent unexpectedly
// 	 */
// 	IResource open() throws IOException;
// 
// 	/**
// 	 * Registers a listener that is being fired every time this resource changes. What "changes" means is deliberately
// 	 * left unspecified but a good example would be whenever the {@link Minecraft#getResourceManager()} changes, for
// 	 * example when a new resource pack is loaded.<br>
// 	 * <b>The initial stick is considered a change already, so this method should also fire the listener once.</b>
// 	 * 
// 	 * @param reloadListener
// 	 */
// 	void registerReloadListener(Consumer<IResourceLocation> reloadListener);
// 
// 	/**
// 	 * A descriptive name of the resource, perhaps the path
// 	 * 
// 	 * @return
// 	 */
// 	String getResourceName();
// 
// 	/**
// 	 * Returns false if this resource should not be cached, e.g. it is a one-time stream. When a
// 	 * {@link IResourceLocation} may get cached, {@link #open()} should succeed multiple times and return the same data
// 	 * every time, until the resource is reloaded.
// 	 * 
// 	 * @return
// 	 */
// 	boolean shouldCache();
// 
// 	@Override
// 	boolean equals(Object obj);
// 
// 	@Override
// 	int hashCode();
// }


// Path: src/main/java/com/github/worldsender/mcanm/common/util/ResourceCache.java
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import com.github.worldsender.mcanm.common.resource.IResource;
import com.github.worldsender.mcanm.common.resource.IResourceLocation;

package com.github.worldsender.mcanm.common.util;



public class ResourceCache<D> {
	private Map<IResourceLocation, D> cache;

	public ResourceCache() {
		cache = new HashMap<>();
	}

	public D getOrCompute(IResource resource, Function<IResource, D> loadFunc) {
		IResourceLocation location = resource.getOrigin();
		if (location.shouldCache()) {
			location.registerReloadListener(this::changedCallback);
			synchronized (cache) {