package tc.oc.commons.core.inject;
import java.util.concurrent.ThreadFactory;
import javax.inject.Singleton;
import com.google.inject.Provides;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import tc.oc.commons.core.exception.ExceptionHandler;
import tc.oc.commons.core.exception.LoggingExceptionHandler;
import tc.oc.commons.core.exception.NamedThreadFactory;
import tc.oc.commons.core.util.NumberFactory;
import tc.oc.commons.core.util.SystemFutureCallback;
import tc.oc.evil.DecoratorFactory;
import tc.oc.parse.ParsersManifest;
/**
* Configures low-level utility classes, nothing related to Minecraft
*/
public class UtilCoreManifest extends Manifest {
@Override
protected void configure() {
// @InjectorScoped annotation
install(new InjectorScopeModule());
// Provide a global, catch-all exception handler
bind(LoggingExceptionHandler.class).in(Singleton.class);
bind(ExceptionHandler.class).to(LoggingExceptionHandler.class);
bind(new TypeLiteral<ExceptionHandler<Throwable>>(){}).to(LoggingExceptionHandler.class);
bind(Thread.UncaughtExceptionHandler.class).to(LoggingExceptionHandler.class);
// Evil decorator thing
// Create it manually so we can use it before the injector is ready
bind(DecoratorFactory.class).toInstance(DecoratorFactory.get());
install(new NumberFactory.Manifest());
install(new ParsersManifest());
requestStaticInjection(SystemFutureCallback.class);
if(currentStage() == Stage.DEVELOPMENT) {
// This is useful, but it makes the LeakDetector unhappy
//install(new RepeatInjectionDetector());
}
}
@Provides @Singleton
ThreadFactory threadFactory(Thread.UncaughtExceptionHandler exceptionHandler) {
return runnable -> {
final Thread thread = new Thread(runnable);
thread.setUncaughtExceptionHandler(exceptionHandler);
return thread;
};
}
@Provides @Singleton
NamedThreadFactory namedThreadFactory(ThreadFactory factory) {
return (name, code) -> {
final Thread thread = factory.newThread(code);
thread.setName(name);
return thread;
};
}
}