Skip to content

Commit

Permalink
Rewrite some multilingual search logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerozgen committed Oct 27, 2024
1 parent fb92681 commit 87053c7
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

@Environment(EnvType.CLIENT)
public interface ITranslationStorage {
String languagereload_get(String key);

@Nullable String languagereload_getTargetLanguage();

void languagereload_setTargetLanguage(@Nullable String value);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package jerozgen.languagereload.mixin;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import jerozgen.languagereload.access.ILanguage;
import jerozgen.languagereload.access.ITranslationStorage;
import jerozgen.languagereload.config.Config;
Expand All @@ -10,70 +11,54 @@
import net.minecraft.text.TranslatableTextContent;
import net.minecraft.text.TranslationException;
import net.minecraft.util.Language;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

@Mixin(TranslatableTextContent.class)
abstract class TranslatableTextContentMixin implements TextContent {
@Unique private final Map<Long, String> previousTargetLanguageByThread = new HashMap<>();
@Unique private final Map<String, List<StringVisitable>> separateTranslationsCache = Maps.newHashMap();

@Shadow @Final private String key;
@Shadow private @Nullable Language languageCache;
@Shadow private List<StringVisitable> translations;

@Inject(method = "updateTranslations", at = @At("RETURN"))
void onUpdateTranslations(CallbackInfo ci) {
if (Config.getInstance() == null) return;
if (!Config.getInstance().multilingualItemSearch) return;
if (languageCache == null) return;

var translationStorage = ((ILanguage) languageCache).languagereload_getTranslationStorage();
if (translationStorage == null) return;

var targetLanguage = ((ITranslationStorage) translationStorage).languagereload_getTargetLanguage();
if (Objects.equals(getPreviousTargetLanguage(), targetLanguage)) return;
setPreviousTargetLanguage(targetLanguage);

if (targetLanguage == null) {
separateTranslationsCache.clear();
translations = ImmutableList.of();
languageCache = null;
return;
}

translations = separateTranslationsCache.computeIfAbsent(targetLanguage, k -> {
var string = languageCache.get(key);
try {
var builder = new ImmutableList.Builder<StringVisitable>();
this.forEachPart(string, builder::add);
return builder.build();
} catch (TranslationException e) {
return ImmutableList.of(StringVisitable.plain(string));
}
});
@WrapOperation(method = "visit(Lnet/minecraft/text/StringVisitable$Visitor;)Ljava/util/Optional;",
at = @At(value = "FIELD", target = "Lnet/minecraft/text/TranslatableTextContent;translations:Ljava/util/List;"))
List<StringVisitable> onVisit(TranslatableTextContent instance, Operation<List<StringVisitable>> translationsGetter) {
var overriddenTranslations = getOverriddenTranslations();
if (overriddenTranslations != null) return overriddenTranslations;
return translationsGetter.call(instance);
}

@Unique
public @Nullable String getPreviousTargetLanguage() {
return previousTargetLanguageByThread.get(Thread.currentThread().threadId());
@WrapOperation(method = "visit(Lnet/minecraft/text/StringVisitable$StyledVisitor;Lnet/minecraft/text/Style;)Ljava/util/Optional;",
at = @At(value = "FIELD", target = "Lnet/minecraft/text/TranslatableTextContent;translations:Ljava/util/List;"))
List<StringVisitable> onVisitStyled(TranslatableTextContent instance, Operation<List<StringVisitable>> translationsGetter) {
var overriddenTranslations = getOverriddenTranslations();
if (overriddenTranslations != null) return overriddenTranslations;
return translationsGetter.call(instance);
}

@Unique
public void setPreviousTargetLanguage(@Nullable String value) {
previousTargetLanguageByThread.put(Thread.currentThread().threadId(), value);
List<StringVisitable> getOverriddenTranslations() {
if (!Config.getInstance().multilingualItemSearch) return null;

var language = Language.getInstance();
var translationStorage = ((ILanguage) language).languagereload_getTranslationStorage();
if (translationStorage == null) return null;

var targetLanguage = ((ITranslationStorage) translationStorage).languagereload_getTargetLanguage();
if (targetLanguage == null) return null;

var string = ((ITranslationStorage) translationStorage).languagereload_get(key);
try {
var builder = new ImmutableList.Builder<StringVisitable>();
this.forEachPart(string, builder::add);
return builder.build();
} catch (TranslationException e) {
return ImmutableList.of(StringVisitable.plain(string));
}
}

@Shadow protected abstract void forEachPart(String translation, Consumer<StringVisitable> partsConsumer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;

@Mixin(TranslationStorage.class)
abstract class TranslationStorageMixin extends Language implements ITranslationStorage {
@Unique private final Map<Long, String> targetLanguageByThread = new HashMap<>();
@Unique private final Map<Long, String> targetLanguageByThread = Maps.newConcurrentMap();
@Unique private static Map<String, Map<String, String>> separateTranslationsOnLoad;
@Unique private Map<String, Map<String, String>> separateTranslations;

Expand All @@ -48,13 +47,14 @@ private static void onLoad(ResourceManager resourceManager, List<String> definit
} else Language.load(inputStream, entryConsumer);
}

@Inject(method = "get", at = @At(value = "HEAD"), cancellable = true)
void onGet(String key, String fallback, CallbackInfoReturnable<String> cir) {
@Override
public String languagereload_get(String key) {
var targetLanguage = languagereload_getTargetLanguage();
if (targetLanguage != null) {
var targetTranslations = separateTranslations.get(targetLanguage);
cir.setReturnValue(targetTranslations == null ? "" : targetTranslations.getOrDefault(key, ""));
return targetTranslations == null ? "" : targetTranslations.getOrDefault(key, "");
}
return this.get(key);
}

@Override
Expand Down

0 comments on commit 87053c7

Please sign in to comment.