|
2 | 2 |
|
3 | 3 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation; |
4 | 4 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; |
5 | | -import com.llamalad7.mixinextras.sugar.Local; |
| 5 | +import com.llamalad7.mixinextras.sugar.Share; |
| 6 | +import com.llamalad7.mixinextras.sugar.ref.LocalRef; |
6 | 7 | import net.minecraft.client.resources.language.ClientLanguage; |
7 | 8 | import net.minecraft.server.packs.resources.Resource; |
8 | 9 | import org.embeddedt.modernfix.annotation.ClientOnlyMixin; |
|
11 | 12 | import org.spongepowered.asm.mixin.injection.At; |
12 | 13 | import org.spongepowered.asm.mixin.injection.ModifyArg; |
13 | 14 |
|
| 15 | +import java.util.ArrayList; |
14 | 16 | import java.util.List; |
15 | 17 | import java.util.Map; |
16 | | -import java.util.function.BiConsumer; |
| 18 | +import java.util.Objects; |
17 | 19 |
|
18 | 20 | /** |
19 | 21 | * Modifies the language system to load/unload the contents of language entries based on GC pressure. |
20 | 22 | */ |
21 | | -@Mixin(ClientLanguage.class) |
| 23 | +@Mixin(value = ClientLanguage.class, priority = 2000) |
22 | 24 | @ClientOnlyMixin |
23 | 25 | public class ClientLanguageMixin { |
24 | | - private static final ThreadLocal<Boolean> MFIX_MODIFY_APPEND_SEMANTICS = ThreadLocal.withInitial(() -> Boolean.FALSE); |
25 | | - |
26 | | - /** |
27 | | - * @author embeddedt |
28 | | - * @reason modify the semantics of appendFrom so that it's used to do a prepass |
29 | | - */ |
30 | | - @ModifyArg(method = "appendFrom", at = @At(value = "INVOKE", target = "Lnet/minecraft/locale/Language;loadFromJson(Ljava/io/InputStream;Ljava/util/function/BiConsumer;)V"), index = 1) |
31 | | - private static BiConsumer<String, ?> changeSemanticsOfConsumer(BiConsumer<String, ?> consumer, @Local(ordinal = 0, argsOnly = true) Map<String, Object> destinationMap, @Local(ordinal = 0) Resource resource) { |
32 | | - return MFIX_MODIFY_APPEND_SEMANTICS.get() ? ((k, v) -> destinationMap.put(k, resource)) : consumer; |
33 | | - } |
34 | | - |
35 | 26 | /** |
36 | 27 | * @author embeddedt |
37 | | - * @reason collect resources that own keys with a prepass |
| 28 | + * @reason collect the list of all known language resources |
38 | 29 | */ |
39 | | - @WrapOperation(method = "loadFrom", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/language/ClientLanguage;appendFrom(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)V")) |
40 | | - private static void trackEntrySource(String languageName, List<Resource> resources, Map<String, String> destinationMap, Operation<Void> original) { |
41 | | - MFIX_MODIFY_APPEND_SEMANTICS.set(true); |
42 | | - try { |
43 | | - original.call(languageName, resources, destinationMap); |
44 | | - } finally { |
45 | | - MFIX_MODIFY_APPEND_SEMANTICS.remove(); |
| 30 | + @WrapOperation(method = "loadFrom", at = @At(value = "INVOKE", |
| 31 | + target = "Lnet/minecraft/client/resources/language/ClientLanguage;appendFrom(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)V")) |
| 32 | + private static void collectResources(String languageName, List<Resource> resources, |
| 33 | + Map<String, String> destinationMap, Operation<Void> original, |
| 34 | + @Share("usedResources") LocalRef<List<Resource>> usedResources) { |
| 35 | + List<Resource> collected = usedResources.get(); |
| 36 | + if (collected == null) { |
| 37 | + collected = new ArrayList<>(); |
| 38 | + usedResources.set(collected); |
46 | 39 | } |
| 40 | + collected.addAll(resources); |
| 41 | + original.call(languageName, resources, destinationMap); |
47 | 42 | } |
48 | 43 |
|
49 | 44 | /** |
50 | 45 | * @author embeddedt |
51 | 46 | * @reason figure out which keys are dynamically loaded and which are injected by mixins |
52 | 47 | */ |
53 | 48 | @ModifyArg(method = "loadFrom", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/language/ClientLanguage;<init>(Ljava/util/Map;Z)V"), index = 0) |
54 | | - private static Map<String, String> modifyLanguageMap(Map<String, ?> storage) { |
55 | | - return DynamicLanguageMap.forStorage(Map.copyOf(storage)); |
| 49 | + private static Map<String, String> modifyLanguageMap(Map<String, String> storage, @Share("usedResources") LocalRef<List<Resource>> usedResources) { |
| 50 | + List<Resource> collected = Objects.requireNonNullElse(usedResources.get(), List.of()); |
| 51 | + return DynamicLanguageMap.forVanillaData(storage, collected); |
56 | 52 | } |
57 | 53 | } |
0 commit comments