package mhfc.net.common.core.registry;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;
import mhfc.net.common.util.services.IPhaseKey;
import mhfc.net.common.util.services.IServiceAccess;
import mhfc.net.common.util.services.IServiceHandle;
import mhfc.net.common.util.services.IServiceKey;
import mhfc.net.common.util.services.IServicePhaseHandle;
import mhfc.net.common.util.services.Services;
public class RegistryWrapper<T> {
private T registry;
private final Supplier<T> newRegistry;
private final Consumer<T> finalizeHook;
public RegistryWrapper(Supplier<T> newRegistry, Consumer<T> finalizeHook) {
this.newRegistry = Objects.requireNonNull(newRegistry);
this.finalizeHook = Objects.requireNonNull(finalizeHook);
}
public void register() {
assert this.registry == null;
this.registry = newRegistry.get();
}
public void unregister() {
assert this.registry != null;
finalizeHook.accept(registry);
this.registry = null;
}
public T getRegistry() {
if (registry == null) {
throw new IllegalStateException("Registry not active");
}
return registry;
}
public static <T, A, Z> IServiceKey<T> registerService(
String name,
Supplier<T> newRegistry,
Consumer<T> softFinalizeHook,
IPhaseKey<A, Z> phase) {
IServiceAccess<RegistryWrapper<T>> serviceAccess = Services.instance.registerService(
name,
IServiceHandle.noInit(),
() -> new RegistryWrapper<>(newRegistry, softFinalizeHook));
serviceAccess.addTo(phase, new IServicePhaseHandle<RegistryWrapper<T>, A, Z>() {
@Override
public void onPhaseStart(RegistryWrapper<T> service, A startupContext) {
service.register();
}
@Override
public void onPhaseEnd(RegistryWrapper<T> service, Z shutdownContext) {
service.unregister();
}
});
return serviceAccess.withIndirection(RegistryWrapper::getRegistry);
}
public static <T, A, Z> IServiceKey<T> registerService(
String name,
Supplier<T> newRegistry,
IPhaseKey<A, Z> phase) {
return registerService(name, newRegistry, t -> {}, phase);
}
}