package tc.oc.pgm.match.inject;
import java.util.Optional;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import org.bukkit.event.Listener;
import tc.oc.commons.core.inject.Binders;
import tc.oc.commons.core.inject.ChildConfigurator;
import tc.oc.commons.core.inject.Keys;
import tc.oc.pgm.match.MatchListenerMeta;
import tc.oc.pgm.match.MatchPlayer;
import tc.oc.pgm.match.MatchScope;
import tc.oc.pgm.match.MatchUserContext;
public interface MatchBinders extends Binders {
default void matchListener(Class<? extends Listener> type) {
matchListener(type, null);
}
default <T extends Listener> void matchListener(Key<T> key) {
matchListener(key, null);
}
default void matchListener(Class<? extends Listener> type, @Nullable MatchScope scope) {
matchListener(Key.get(type), scope);
}
default <T extends Listener> void matchListener(Key<T> key, @Nullable MatchScope scope) {
inSet(MatchListenerMeta.class).addBinding().toInstance(
new MatchListenerMeta((Class<T>) key.getTypeLiteral().getRawType(), scope)
);
inSet(Key.get(Listener.class, ForMatch.class))
.addBinding().to(key);
}
default void matchOptionalListener(Class<? extends Listener> type) {
matchOptionalListener(Key.get(type), null);
}
default <T extends Listener> void matchOptionalListener(Key<T> key, @Nullable MatchScope scope) {
inSet(MatchListenerMeta.class).addBinding().toInstance(
new MatchListenerMeta((Class<T>) key.getTypeLiteral().getRawType(), scope)
);
final Key<Optional<T>> optionalKey = Keys.optional(key);
inSet(Key.get(new TypeLiteral<Optional<? extends Listener>>(){}, ForMatch.class))
.addBinding().to(optionalKey);
}
/**
* Install modules into the private configuration of *every* {@link MatchUserContext}
*/
default void installUserModule(Module... modules) {
final ChildConfigurator<MatchUserContext> configurator = new ChildConfigurator<>(forwardedBinder(), MatchUserContext.class);
Stream.of(modules).forEach(configurator::install);
}
/**
* Install modules into the private configuration of *every* {@link MatchPlayer}
*/
default void installPlayerModule(Module... modules) {
final ChildConfigurator<MatchPlayer> configurator = new ChildConfigurator<>(forwardedBinder(), MatchPlayer.class);
Stream.of(modules).forEach(configurator::install);
}
}