Skip to content

Instantly share code, notes, and snippets.

@octylFractal
Created July 12, 2020 18:11
Show Gist options
  • Save octylFractal/cdd92710b05b50613d96d2fee35427f2 to your computer and use it in GitHub Desktop.
Save octylFractal/cdd92710b05b50613d96d2fee35427f2 to your computer and use it in GitHub Desktop.
/**
* Utility to render any config placeholders in a component using a given {@link ConfigHolder}.
*/
public class ConfigRenderer implements ComponentRenderer<ConfigHolder> {
private static final ConfigRenderer INSTANCE = new ConfigRenderer();
/**
* Get an instance of the renderer.
*/
public static ConfigRenderer getInstance() {
return INSTANCE;
}
private ConfigRenderer() {
}
@Override
public @NonNull Component render(@NonNull Component component, @NonNull ConfigHolder context) {
component = replaceSubcomponents(component, context);
if (component instanceof TranslatableComponent) {
// check if replacing
TranslatableComponent tc = (TranslatableComponent) component;
Config<?> config = context.getConfigs().get(tc.key());
if (config != null) {
component = config.apply(tc);
}
}
return component;
}
private Component replaceSubcomponents(Component component, ConfigHolder context) {
if (component instanceof TranslatableComponent) {
TranslatableComponent tc = (TranslatableComponent) component;
List<Component> originalArgs = tc.args();
List<Component> replacementArgs = renderList(originalArgs, context);
if (originalArgs != replacementArgs) {
component = tc.args(replacementArgs);
}
// fall-through to replace children if needed
}
List<Component> original = component.children();
List<Component> replacement = renderList(original, context);
return original != replacement
? component.children(replacement)
: component;
}
private List<Component> renderList(List<Component> input, ConfigHolder context) {
if (input.isEmpty()) {
return input;
}
ImmutableList.Builder<Component> copy = ImmutableList.builder();
boolean modified = false;
for (Component component : input) {
Component replacement = render(component, context);
if (replacement != component) {
modified = true;
}
copy.add(replacement);
}
return modified ? copy.build() : input;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment