120 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.sounds;
 | |
| 
 | |
| import com.google.common.collect.Maps;
 | |
| import com.mojang.blaze3d.audio.SoundBuffer;
 | |
| import java.io.IOException;
 | |
| import java.io.InputStream;
 | |
| import java.nio.ByteBuffer;
 | |
| import java.util.Collection;
 | |
| import java.util.Map;
 | |
| import java.util.concurrent.CompletableFuture;
 | |
| import java.util.concurrent.CompletionException;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.Util;
 | |
| import net.minecraft.client.resources.sounds.Sound;
 | |
| import net.minecraft.resources.ResourceLocation;
 | |
| import net.minecraft.server.packs.resources.ResourceProvider;
 | |
| 
 | |
| /**
 | |
|  * The {@linkplain SoundBufferLibrary} class provides a cache containing instances of {@linkplain SoundBuffer} and {@linkplain AudioStream} for use in Minecraft sound handling.
 | |
|  */
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class SoundBufferLibrary {
 | |
| 	/**
 | |
| 	 * The {@linkplain ResourceProvider} used for loading sound resources.
 | |
| 	 */
 | |
| 	private final ResourceProvider resourceManager;
 | |
| 	private final Map<ResourceLocation, CompletableFuture<SoundBuffer>> cache = Maps.<ResourceLocation, CompletableFuture<SoundBuffer>>newHashMap();
 | |
| 
 | |
| 	public SoundBufferLibrary(ResourceProvider resourceManager) {
 | |
| 		this.resourceManager = resourceManager;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * {@return Returns a {@linkplain CompletableFuture} containing the complete {@linkplain SoundBuffer}. The {@linkplain SoundBuffer} is loaded asynchronously and cached.}
 | |
| 	 * 
 | |
| 	 * @param soundID the {@linkplain ResourceLocation} of the sound
 | |
| 	 */
 | |
| 	public CompletableFuture<SoundBuffer> getCompleteBuffer(ResourceLocation soundID) {
 | |
| 		return (CompletableFuture<SoundBuffer>)this.cache.computeIfAbsent(soundID, resourceLocation -> CompletableFuture.supplyAsync(() -> {
 | |
| 			try {
 | |
| 				InputStream inputStream = this.resourceManager.open(resourceLocation);
 | |
| 
 | |
| 				SoundBuffer var5;
 | |
| 				try {
 | |
| 					FiniteAudioStream finiteAudioStream = new JOrbisAudioStream(inputStream);
 | |
| 
 | |
| 					try {
 | |
| 						ByteBuffer byteBuffer = finiteAudioStream.readAll();
 | |
| 						var5 = new SoundBuffer(byteBuffer, finiteAudioStream.getFormat());
 | |
| 					} catch (Throwable var8) {
 | |
| 						try {
 | |
| 							finiteAudioStream.close();
 | |
| 						} catch (Throwable var7) {
 | |
| 							var8.addSuppressed(var7);
 | |
| 						}
 | |
| 
 | |
| 						throw var8;
 | |
| 					}
 | |
| 
 | |
| 					finiteAudioStream.close();
 | |
| 				} catch (Throwable var9) {
 | |
| 					if (inputStream != null) {
 | |
| 						try {
 | |
| 							inputStream.close();
 | |
| 						} catch (Throwable var6) {
 | |
| 							var9.addSuppressed(var6);
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					throw var9;
 | |
| 				}
 | |
| 
 | |
| 				if (inputStream != null) {
 | |
| 					inputStream.close();
 | |
| 				}
 | |
| 
 | |
| 				return var5;
 | |
| 			} catch (IOException var10) {
 | |
| 				throw new CompletionException(var10);
 | |
| 			}
 | |
| 		}, Util.nonCriticalIoPool()));
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * {@return Returns a {@linkplain CompletableFuture} containing the {@linkplain AudioStream}. The {@linkplain AudioStream} is loaded asynchronously.}
 | |
| 	 * 
 | |
| 	 * @param resourceLocation the {@linkplain ResourceLocation} of the sound
 | |
| 	 * @param isWrapper whether the {@linkplain AudioStream} should be a {@linkplain LoopingAudioStream}
 | |
| 	 */
 | |
| 	public CompletableFuture<AudioStream> getStream(ResourceLocation resourceLocation, boolean isWrapper) {
 | |
| 		return CompletableFuture.supplyAsync(() -> {
 | |
| 			try {
 | |
| 				InputStream inputStream = this.resourceManager.open(resourceLocation);
 | |
| 				return (AudioStream)(isWrapper ? new LoopingAudioStream(JOrbisAudioStream::new, inputStream) : new JOrbisAudioStream(inputStream));
 | |
| 			} catch (IOException var4) {
 | |
| 				throw new CompletionException(var4);
 | |
| 			}
 | |
| 		}, Util.nonCriticalIoPool());
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Clears the cache of all {@linkplain SoundBuffer} instances.
 | |
| 	 */
 | |
| 	public void clear() {
 | |
| 		this.cache.values().forEach(completableFuture -> completableFuture.thenAccept(SoundBuffer::discardAlBuffer));
 | |
| 		this.cache.clear();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Preloads the {@linkplain SoundBuffer} objects for the specified collection of sounds.
 | |
| 	 * <p>
 | |
| 	 * @return a {@linkplain CompletableFuture} representing the completion of the preload operation
 | |
| 	 * 
 | |
| 	 * @param sounds the collection of sounds to preload
 | |
| 	 */
 | |
| 	public CompletableFuture<?> preload(Collection<Sound> sounds) {
 | |
| 		return CompletableFuture.allOf((CompletableFuture[])sounds.stream().map(sound -> this.getCompleteBuffer(sound.getPath())).toArray(CompletableFuture[]::new));
 | |
| 	}
 | |
| }
 |