package tc.oc.pgm.match;
import java.util.Optional;
import java.util.Random;
import com.google.inject.Key;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
import org.bukkit.event.Listener;
import tc.oc.api.docs.virtual.MatchDoc;
import tc.oc.commons.core.chat.Audience;
import tc.oc.commons.core.exception.ExceptionHandler;
import tc.oc.commons.core.inject.ChildInjectorFactory;
import tc.oc.commons.core.inject.HybridManifest;
import tc.oc.commons.core.inject.Manifest;
import tc.oc.commons.core.logging.Loggers;
import tc.oc.commons.core.random.Entropy;
import tc.oc.commons.core.random.MutableEntropy;
import tc.oc.commons.core.scheduler.SchedulerBackend;
import tc.oc.pgm.api.MatchDocument;
import tc.oc.pgm.countdowns.CountdownContext;
import tc.oc.pgm.countdowns.SingleCountdownContext;
import tc.oc.pgm.features.MatchFeatureContext;
import tc.oc.pgm.match.inject.ForMatch;
import tc.oc.pgm.match.inject.ForRunningMatch;
import tc.oc.pgm.match.inject.MatchBinders;
import tc.oc.pgm.match.inject.MatchScoped;
import tc.oc.pgm.module.MatchModulesManifest;
import tc.oc.pgm.time.TickClock;
import tc.oc.pgm.time.WorldTickClock;
import tc.oc.pgm.utils.WorldTickRandom;
/**
* Configure things related to {@link Match}es
*
* @see MatchModulesManifest
*/
public class MatchManifest extends HybridManifest implements MatchBinders {
@Override
protected void configure() {
// Make @MatchScoped work
install(new MatchInjectionScope().new Manifest());
// @MatchScoped stuff
installIn(MatchScoped.class, new Manifest() {
@Override protected void configure() {
bind(Match.class).to(MatchImpl.class);
bind(MatchModuleContext.class);
bind(MatchFeatureContext.class);
bind(WorldTickClock.class);
bind(WorldTickRandom.class);
bind(MatchDocument.class);
bind(MatchAudiences.class);
bind(MatchScheduler.class);
bind(MatchRealtimeScheduler.class);
bind(MatchExecutor.class);
bind(Key.get(Entropy.class, ForMatch.class))
.to(MutableEntropy.class);
bind(Key.get(Random.class, ForMatch.class))
.to(Random.class);
bind(Key.get(SingleCountdownContext.class, ForMatch.class))
.to(SingleCountdownContext.class);
}
});
// Tourney needs this
expose(Match.class);
// Aliases
bind(MatchPlayerFinder.class).to(Match.class);
bind(Audience.class).annotatedWith(ForMatch.class).to(Match.class);
bind(TickClock.class).to(WorldTickClock.class);
bind(MatchDoc.class).to(MatchDocument.class);
bind(Key.get(CountdownContext.class, ForMatch.class))
.to(Key.get(SingleCountdownContext.class, ForMatch.class));
// Listeners to be registered at match load time
Multibinder.newSetBinder(binder(), MatchListenerMeta.class);
Multibinder.newSetBinder(binder(), Key.get(Listener.class, ForMatch.class));
Multibinder.newSetBinder(binder(), new Key<Optional<? extends Listener>>(ForMatch.class){});
matchListener(Key.get(CountdownContext.class, ForMatch.class));
matchListener(MatchRealtimeScheduler.class);
bind(new TypeLiteral<ChildInjectorFactory<MatchUserContext>>(){});
installPlayerModule(new MatchPlayerFacetManifest());
}
@Provides @MatchScoped @ForRunningMatch
MatchScheduler runningMatchScheduler(Loggers loggers, SchedulerBackend backend, ExceptionHandler exceptionHandler, Match match) {
return new MatchScheduler(MatchScope.RUNNING, loggers, backend, exceptionHandler, match);
}
}