95 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.gui.narration;
 | |
| 
 | |
| import com.google.common.collect.Maps;
 | |
| import java.util.Comparator;
 | |
| import java.util.Map;
 | |
| import java.util.function.Consumer;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class ScreenNarrationCollector {
 | |
| 	int generation;
 | |
| 	final Map<ScreenNarrationCollector.EntryKey, ScreenNarrationCollector.NarrationEntry> entries = Maps.newTreeMap(
 | |
| 		Comparator.comparing(entryKey -> entryKey.type).thenComparing(entryKey -> entryKey.depth)
 | |
| 	);
 | |
| 
 | |
| 	public void update(Consumer<NarrationElementOutput> updater) {
 | |
| 		this.generation++;
 | |
| 		updater.accept(new ScreenNarrationCollector.Output(0));
 | |
| 	}
 | |
| 
 | |
| 	public String collectNarrationText(boolean collectAll) {
 | |
| 		final StringBuilder stringBuilder = new StringBuilder();
 | |
| 		Consumer<String> consumer = new Consumer<String>() {
 | |
| 			private boolean firstEntry = true;
 | |
| 
 | |
| 			public void accept(String str) {
 | |
| 				if (!this.firstEntry) {
 | |
| 					stringBuilder.append(". ");
 | |
| 				}
 | |
| 
 | |
| 				this.firstEntry = false;
 | |
| 				stringBuilder.append(str);
 | |
| 			}
 | |
| 		};
 | |
| 		this.entries.forEach((entryKey, narrationEntry) -> {
 | |
| 			if (narrationEntry.generation == this.generation && (collectAll || !narrationEntry.alreadyNarrated)) {
 | |
| 				narrationEntry.contents.getText(consumer);
 | |
| 				narrationEntry.alreadyNarrated = true;
 | |
| 			}
 | |
| 		});
 | |
| 		return stringBuilder.toString();
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	static class EntryKey {
 | |
| 		final NarratedElementType type;
 | |
| 		final int depth;
 | |
| 
 | |
| 		EntryKey(NarratedElementType type, int depth) {
 | |
| 			this.type = type;
 | |
| 			this.depth = depth;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	static class NarrationEntry {
 | |
| 		NarrationThunk<?> contents = NarrationThunk.EMPTY;
 | |
| 		int generation = -1;
 | |
| 		boolean alreadyNarrated;
 | |
| 
 | |
| 		public ScreenNarrationCollector.NarrationEntry update(int generation, NarrationThunk<?> contents) {
 | |
| 			if (!this.contents.equals(contents)) {
 | |
| 				this.contents = contents;
 | |
| 				this.alreadyNarrated = false;
 | |
| 			} else if (this.generation + 1 != generation) {
 | |
| 				this.alreadyNarrated = false;
 | |
| 			}
 | |
| 
 | |
| 			this.generation = generation;
 | |
| 			return this;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	class Output implements NarrationElementOutput {
 | |
| 		private final int depth;
 | |
| 
 | |
| 		Output(final int depth) {
 | |
| 			this.depth = depth;
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void add(NarratedElementType type, NarrationThunk<?> contents) {
 | |
| 			((ScreenNarrationCollector.NarrationEntry)ScreenNarrationCollector.this.entries
 | |
| 					.computeIfAbsent(new ScreenNarrationCollector.EntryKey(type, this.depth), entryKey -> new ScreenNarrationCollector.NarrationEntry()))
 | |
| 				.update(ScreenNarrationCollector.this.generation, contents);
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public NarrationElementOutput nest() {
 | |
| 			return ScreenNarrationCollector.this.new Output(this.depth + 1);
 | |
| 		}
 | |
| 	}
 | |
| }
 |