package dev.isxander.yacl.impl; import com.google.common.collect.ImmutableSet; import dev.isxander.yacl.api.Binding; import dev.isxander.yacl.api.Controller; import dev.isxander.yacl.api.Option; import dev.isxander.yacl.api.OptionFlag; import net.minecraft.text.Text; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.function.BiConsumer; import java.util.function.Function; public class OptionImpl implements Option { private final Text name; private Text tooltip; private final Controller controller; private final Binding binding; private boolean available; private final ImmutableSet flags; private final Class typeClass; private T pendingValue; private final List, T>> listeners; public OptionImpl( @NotNull Text name, @Nullable Function tooltipGetter, @NotNull Function, Controller> controlGetter, @NotNull Binding binding, boolean available, ImmutableSet flags, @NotNull Class typeClass, @NotNull Collection, T>> listeners ) { this.name = name; this.binding = binding; this.available = available; this.flags = flags; this.typeClass = typeClass; this.listeners = new ArrayList<>(listeners); this.controller = controlGetter.apply(this); addListener((opt, pending) -> tooltip = tooltipGetter.apply(pending)); requestSet(binding().getValue()); } @Override public @NotNull Text name() { return name; } @Override public @NotNull Text tooltip() { return tooltip; } @Override public @NotNull Controller controller() { return controller; } @Override public @NotNull Binding binding() { return binding; } @Override public boolean available() { return available; } @Override public void setAvailable(boolean available) { this.available = available; } @Override public @NotNull Class typeClass() { return typeClass; } @Override public @NotNull ImmutableSet flags() { return flags; } @Override public boolean requiresRestart() { return flags.contains(OptionFlag.GAME_RESTART); } @Override public boolean changed() { return !binding().getValue().equals(pendingValue); } @Override public @NotNull T pendingValue() { return pendingValue; } @Override public void requestSet(T value) { pendingValue = value; listeners.forEach(listener -> listener.accept(this, pendingValue)); } @Override public boolean applyValue() { if (changed()) { binding().setValue(pendingValue); return true; } return false; } @Override public void forgetPendingValue() { requestSet(binding().getValue()); } @Override public void requestSetDefault() { requestSet(binding().defaultValue()); } @Override public boolean isPendingValueDefault() { return binding().defaultValue().equals(pendingValue()); } @Override public void addListener(BiConsumer, T> changedListener) { this.listeners.add(changedListener); } }