Move Registry Events to the mod event bus.
Add infrastructure to allow parallel or synchronous dispatch of mod events, and pass-through of events to the dispatch system. Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
parent
ff2e35c243
commit
f4d2d1a24b
9 changed files with 162 additions and 88 deletions
|
@ -260,7 +260,7 @@ project(':forge') {
|
|||
installer 'org.ow2.asm:asm-tree:6.2'
|
||||
installer 'cpw.mods:modlauncher:0.6.0'
|
||||
installer 'net.minecraftforge:accesstransformers:0.14.+:shadowed'
|
||||
installer 'net.minecraftforge:eventbus:0.3.+:service'
|
||||
installer 'net.minecraftforge:eventbus:0.6.+:service'
|
||||
installer 'net.minecraftforge:forgespi:0.2.+'
|
||||
installer 'net.minecraftforge:coremods:0.2.+'
|
||||
installer 'com.electronwill.night-config:core:3.4.2'
|
||||
|
|
|
@ -39,7 +39,8 @@ import static net.minecraftforge.fml.Logging.LOADING;
|
|||
|
||||
/**
|
||||
* Automatic eventbus subscriber - reads {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber}
|
||||
* annotations and passes the class instances to the {@link net.minecraftforge.common.MinecraftForge.EVENT_BUS}
|
||||
* annotations and passes the class instances to the {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus}
|
||||
* defined by the annotation. Defaults to {@link MinecraftForge#EVENT_BUS}
|
||||
*/
|
||||
public class AutomaticEventSubscriber
|
||||
{
|
||||
|
@ -60,10 +61,11 @@ public class AutomaticEventSubscriber
|
|||
final EnumSet<Dist> sides = sidesValue.stream().map(eh -> Dist.valueOf(eh.getValue())).
|
||||
collect(Collectors.toCollection(() -> EnumSet.noneOf(Dist.class)));
|
||||
final String modId = (String)ad.getAnnotationData().getOrDefault("modId", mod.getModId());
|
||||
final Mod.EventBusSubscriber.Bus busTarget = (Mod.EventBusSubscriber.Bus)ad.getAnnotationData().getOrDefault("bus", Mod.EventBusSubscriber.Bus.FORGE);
|
||||
if (Objects.equals(mod.getModId(), modId) && sides.contains(FMLEnvironment.dist)) {
|
||||
try
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.register(Class.forName(ad.getClassType().getClassName(), true, loader));
|
||||
busTarget.bus().get().register(Class.forName(ad.getClassType().getClassName(), true, loader));
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
|
|
|
@ -19,40 +19,72 @@
|
|||
|
||||
package net.minecraftforge.fml;
|
||||
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.event.lifecycle.ModLifecycleEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
|
||||
import net.minecraftforge.forgespi.language.ILifecycleEvent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public enum LifecycleEventProvider
|
||||
{
|
||||
CONSTRUCT(()->new LifecycleEvent(ModLoadingStage.CONSTRUCT)),
|
||||
CREATE_REGISTRIES(()->new LifecycleEvent(ModLoadingStage.CREATE_REGISTRIES), ModList.inlineDispatcher),
|
||||
LOAD_REGISTRIES(()->new LifecycleEvent(ModLoadingStage.LOAD_REGISTRIES, LifecycleEvent.Progression.STAY), ModList.inlineDispatcher),
|
||||
SETUP(()->new LifecycleEvent(ModLoadingStage.COMMON_SETUP)),
|
||||
SIDED_SETUP(()->new LifecycleEvent(ModLoadingStage.SIDED_SETUP)),
|
||||
ENQUEUE_IMC(()->new LifecycleEvent(ModLoadingStage.ENQUEUE_IMC)),
|
||||
PROCESS_IMC(()->new LifecycleEvent(ModLoadingStage.PROCESS_IMC)),
|
||||
COMPLETE(()->new LifecycleEvent(ModLoadingStage.COMPLETE));
|
||||
|
||||
public void dispatch(Consumer<List<ModLoadingException>> errorHandler) {
|
||||
ModList.get().dispatchLifeCycleEvent(this.event.get(), errorHandler);
|
||||
}
|
||||
private final Supplier<? extends LifecycleEvent> event;
|
||||
private final BiConsumer<LifecycleEvent, Consumer<List<ModLoadingException>>> eventDispatcher;
|
||||
private Supplier<Event> customEventSupplier;
|
||||
private LifecycleEvent.Progression progression = LifecycleEvent.Progression.NEXT;
|
||||
|
||||
LifecycleEventProvider(Supplier<? extends LifecycleEvent> e)
|
||||
{
|
||||
event = e;
|
||||
this(e, ModList.parallelDispatcher);
|
||||
}
|
||||
|
||||
LifecycleEventProvider(Supplier<? extends LifecycleEvent> e, BiConsumer<LifecycleEvent, Consumer<List<ModLoadingException>>> eventDispatcher)
|
||||
{
|
||||
this.event = e;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
}
|
||||
|
||||
public void setCustomEventSupplier(Supplier<Event> eventSupplier) {
|
||||
this.customEventSupplier = eventSupplier;
|
||||
}
|
||||
|
||||
public void changeProgression(LifecycleEvent.Progression progression) {
|
||||
this.progression = progression;
|
||||
}
|
||||
|
||||
public void dispatch(Consumer<List<ModLoadingException>> errorHandler) {
|
||||
final LifecycleEvent lifecycleEvent = this.event.get();
|
||||
lifecycleEvent.setCustomEventSupplier(this.customEventSupplier);
|
||||
lifecycleEvent.changeProgression(this.progression);
|
||||
this.eventDispatcher.accept(lifecycleEvent, errorHandler);
|
||||
}
|
||||
|
||||
|
||||
public static class LifecycleEvent implements ILifecycleEvent<LifecycleEvent> {
|
||||
private final ModLoadingStage stage;
|
||||
|
||||
public LifecycleEvent(ModLoadingStage stage)
|
||||
private Supplier<Event> customEventSupplier;
|
||||
private Progression progression;
|
||||
LifecycleEvent(final ModLoadingStage stage)
|
||||
{
|
||||
this(stage, Progression.NEXT);
|
||||
}
|
||||
|
||||
LifecycleEvent(final ModLoadingStage stage, final Progression progression) {
|
||||
this.stage = stage;
|
||||
this.progression = progression;
|
||||
}
|
||||
|
||||
public ModLoadingStage fromStage()
|
||||
|
@ -62,12 +94,42 @@ public enum LifecycleEventProvider
|
|||
|
||||
public ModLoadingStage toStage()
|
||||
{
|
||||
return ModLoadingStage.values()[this.stage.ordinal()+1];
|
||||
return progression.apply(this.stage);
|
||||
}
|
||||
|
||||
public ModLifecycleEvent buildModEvent(FMLModContainer fmlModContainer)
|
||||
public void setCustomEventSupplier(Supplier<Event> customEventSupplier) {
|
||||
this.customEventSupplier = customEventSupplier;
|
||||
}
|
||||
|
||||
public void changeProgression(Progression p) {
|
||||
this.progression = p;
|
||||
}
|
||||
|
||||
public Event getOrBuildEvent(FMLModContainer fmlModContainer)
|
||||
{
|
||||
if (customEventSupplier!=null) return customEventSupplier.get();
|
||||
|
||||
return stage.getModEvent(fmlModContainer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LifecycleEvent:"+stage;
|
||||
}
|
||||
|
||||
public enum Progression {
|
||||
NEXT((current)-> ModLoadingStage.values()[current.ordinal()+1]),
|
||||
STAY(Function.identity());
|
||||
|
||||
private final Function<ModLoadingStage, ModLoadingStage> edge;
|
||||
|
||||
Progression(Function<ModLoadingStage, ModLoadingStage> edge) {
|
||||
this.edge = edge;
|
||||
}
|
||||
|
||||
public ModLoadingStage apply(ModLoadingStage in) {
|
||||
return this.edge.apply(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Optional;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -74,6 +75,10 @@ public class ModList
|
|||
return INSTANCE;
|
||||
}
|
||||
|
||||
static BiConsumer<LifecycleEventProvider.LifecycleEvent, Consumer<List<ModLoadingException>>> inlineDispatcher = (event, errors) -> ModList.get().dispatchSynchronousEvent(event, errors);
|
||||
|
||||
static BiConsumer<LifecycleEventProvider.LifecycleEvent, Consumer<List<ModLoadingException>>> parallelDispatcher = (event, errors) -> ModList.get().dispatchParallelEvent(event, errors);
|
||||
|
||||
public static ModList get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
@ -83,13 +88,19 @@ public class ModList
|
|||
return modFiles;
|
||||
}
|
||||
|
||||
|
||||
public ModFileInfo getModFileById(String modid)
|
||||
{
|
||||
return this.fileById.get(modid);
|
||||
}
|
||||
|
||||
public void dispatchLifeCycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent, final Consumer<List<ModLoadingException>> errorHandler) {
|
||||
private void dispatchSynchronousEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent, final Consumer<List<ModLoadingException>> errorHandler) {
|
||||
LOGGER.info(LOADING, "Dispatching synchronous event {}", lifecycleEvent);
|
||||
FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.consumeLifecycleEvent(()->lifecycleEvent));
|
||||
this.mods.forEach(m->m.transitionState(lifecycleEvent, errorHandler));
|
||||
FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.consumeLifecycleEvent(()->lifecycleEvent));
|
||||
}
|
||||
private void dispatchParallelEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent, final Consumer<List<ModLoadingException>> errorHandler) {
|
||||
LOGGER.info(LOADING, "Dispatching parallel event {}", lifecycleEvent);
|
||||
FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.consumeLifecycleEvent(()->lifecycleEvent));
|
||||
DeferredWorkQueue.clear();
|
||||
try
|
||||
|
@ -104,7 +115,7 @@ public class ModList
|
|||
FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.consumeLifecycleEvent(()->lifecycleEvent));
|
||||
}
|
||||
|
||||
public void setLoadedMods(final List<ModContainer> modContainers)
|
||||
void setLoadedMods(final List<ModContainer> modContainers)
|
||||
{
|
||||
this.mods = modContainers;
|
||||
this.indexedMods = modContainers.stream().collect(Collectors.toMap(ModContainer::getModId, Function.identity()));
|
||||
|
|
|
@ -123,10 +123,10 @@ public class ModLoader
|
|||
}
|
||||
modList.setLoadedMods(modContainerStream.collect(Collectors.toList()));
|
||||
dispatchAndHandleError(LifecycleEventProvider.CONSTRUCT);
|
||||
GameData.fireCreateRegistryEvents();
|
||||
GameData.fireCreateRegistryEvents(LifecycleEventProvider.CREATE_REGISTRIES, this::dispatchAndHandleError);
|
||||
ObjectHolderRegistry.findObjectHolders();
|
||||
CapabilityManager.INSTANCE.injectCapabilities(modList.getAllScanData());
|
||||
GameData.fireRegistryEvents();
|
||||
GameData.fireRegistryEvents(rl->true, LifecycleEventProvider.LOAD_REGISTRIES, this::dispatchAndHandleError);
|
||||
dispatchAndHandleError(LifecycleEventProvider.SETUP);
|
||||
DistExecutor.runWhenOn(Dist.CLIENT, ModLoader::fireClientEvents);
|
||||
dispatchAndHandleError(LifecycleEventProvider.SIDED_SETUP);
|
||||
|
|
|
@ -29,13 +29,14 @@ public enum ModLoadingStage
|
|||
ERROR(null),
|
||||
VALIDATE(null),
|
||||
CONSTRUCT(null),
|
||||
CREATE_REGISTRIES(null),
|
||||
LOAD_REGISTRIES(null),
|
||||
COMMON_SETUP(()-> FMLCommonSetupEvent::new),
|
||||
SIDED_SETUP(SidedProvider.SIDED_SETUP_EVENT::get),
|
||||
ENQUEUE_IMC(()-> InterModEnqueueEvent::new),
|
||||
PROCESS_IMC(()-> InterModProcessEvent::new),
|
||||
COMPLETE(()-> FMLLoadCompleteEvent::new),
|
||||
DONE(null);
|
||||
|
||||
private final Supplier<Function<ModContainer, ModLifecycleEvent>> modLifecycleEventFunction;
|
||||
|
||||
ModLoadingStage(Supplier<Function<ModContainer, ModLifecycleEvent>> modLifecycleEventFunction)
|
||||
|
|
|
@ -23,26 +23,19 @@ import java.lang.annotation.ElementType;
|
|||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLFingerprintViolationEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.event.lifecycle.ModLifecycleEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLModLoadingContext;
|
||||
|
||||
/**
|
||||
* This defines a Mod to FML.
|
||||
* Any class found with this annotation applied will be loaded as a Mod. The instance that is loaded will
|
||||
* represent the mod to other Mods in the system. It will be sent various subclasses of {@link ModLifecycleEvent}
|
||||
* at pre-defined times during the loading of the game, based on where you have applied the {@link EventHandler}
|
||||
* annotation.
|
||||
* at pre-defined times during the loading of the game.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
|
@ -56,63 +49,60 @@ public @interface Mod
|
|||
* By default, you will have a resource domain that matches the modid. All these uses require that constraints are imposed on the format of the modid.
|
||||
*/
|
||||
String value();
|
||||
/**
|
||||
* Marks the associated method as handling an FML lifecycle event.
|
||||
* The method must have a single parameter, one of the following types. This annotation
|
||||
* replaces the multiple different annotations that previously were used.
|
||||
*
|
||||
* Current event classes. This first section is standard lifecycle events. They are dispatched
|
||||
* at various phases as the game starts. Each event should have information useful to that
|
||||
* phase of the lifecycle. They are fired in this order.
|
||||
*
|
||||
* These suggestions are mostly just suggestions on what to do in each event.
|
||||
* <ul>
|
||||
* <li> {@link FMLCommonSetupEvent} : Run before anything else. Read your config, create blocks,
|
||||
* items, etc, and register them with the {@link GameRegistry}.</li>
|
||||
* <li> {@link InterModEnqueueEvent} : Do your mod setup. Build whatever data structures you care about. Register recipes,
|
||||
* send {@link FMLInterModComms} messages to other mods.</li>
|
||||
* <li> {@link InterModProcessEvent} : Handle interaction with other mods, complete your setup based on this.</li>
|
||||
* </ul>
|
||||
* <p>These are the server lifecycle events. They are fired whenever a server is running, or about to run. Each time a server
|
||||
* starts they will be fired in this sequence.
|
||||
* <ul>
|
||||
* <li> {@link FMLServerAboutToStartEvent} : Use if you need to handle something before the server has even been created.</li>
|
||||
* <li> {@link FMLServerStartingEvent} : Do stuff you need to do to set up the server. register commands, tweak the server.</li>
|
||||
* <li> {@link FMLServerStartedEvent} : Do what you need to with the running server.</li>
|
||||
* <li> {@link FMLServerStoppingEvent} : Do what you need to before the server has started it's shutdown sequence.</li>
|
||||
* <li> {@link FMLServerStoppedEvent} : Do whatever cleanup you need once the server has shutdown. Generally only useful
|
||||
* on the integrated server.</li>
|
||||
* </ul>
|
||||
* The second set of events are more specialized, for receiving notification of specific
|
||||
* information.
|
||||
* <ul>
|
||||
* <li> {@link FMLFingerprintViolationEvent} : Sent just before {@link FMLCommonSetupEvent}
|
||||
* if something is wrong with your mod signature</li>
|
||||
* <li> {@link IMCEvent} : Sent just after {@link InterModEnqueueEvent} if you have IMC messages waiting
|
||||
* from other mods</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@interface EventHandler{}
|
||||
|
||||
/**
|
||||
* A class which will be subscribed to {@link net.minecraftforge.common.MinecraftForge.EVENT_BUS} at mod construction time.
|
||||
* Annotate a class which will be subscribed to an Event Bus at mod construction time.
|
||||
* Defaults to subscribing the current modid to the {@link MinecraftForge#EVENT_BUS}
|
||||
* on both sides.
|
||||
*
|
||||
* @see Bus
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@interface EventBusSubscriber {
|
||||
/**
|
||||
* Specify targets to load this event subscriber on. Can be used to avoid loading Client specific events
|
||||
* on a dedicated server, for example.
|
||||
*
|
||||
* @return an array of Dist to load this event subscriber on
|
||||
*/
|
||||
Dist[] value() default { Dist.CLIENT, Dist.DEDICATED_SERVER };
|
||||
|
||||
/**
|
||||
* Optional value, only nessasary if tis annotation is not on the same class that has a @Mod annotation.
|
||||
* Optional value, only necessary if this annotation is not on the same class that has a @Mod annotation.
|
||||
* Needed to prevent early classloading of classes not owned by your mod.
|
||||
* @return
|
||||
* @return a modid
|
||||
*/
|
||||
String modid() default "";
|
||||
|
||||
/**
|
||||
* Specify an alternative bus to listen to
|
||||
*
|
||||
* @return the bus you wish to listen to
|
||||
*/
|
||||
Bus bus() default Bus.FORGE;
|
||||
|
||||
enum Bus {
|
||||
/**
|
||||
* The main Forge Event Bus.
|
||||
* @see MinecraftForge#EVENT_BUS
|
||||
*/
|
||||
FORGE(()-> MinecraftForge.EVENT_BUS),
|
||||
/**
|
||||
* The mod specific Event bus.
|
||||
* @see FMLModLoadingContext#getModEventBus()
|
||||
*/
|
||||
MOD(()-> FMLModLoadingContext.get().getModEventBus());
|
||||
|
||||
private final Supplier<IEventBus> busSupplier;
|
||||
|
||||
Bus(final Supplier<IEventBus> eventBusSupplier) {
|
||||
this.busSupplier = eventBusSupplier;
|
||||
}
|
||||
|
||||
public Supplier<IEventBus> bus() {
|
||||
return busSupplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import net.minecraftforge.fml.ModContainer;
|
|||
import net.minecraftforge.fml.ModLoadingException;
|
||||
import net.minecraftforge.fml.ModLoadingStage;
|
||||
import net.minecraftforge.fml.ModThreadContext;
|
||||
import net.minecraftforge.fml.event.lifecycle.ModLifecycleEvent;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import net.minecraftforge.forgespi.language.ModFileScanData;
|
||||
|
||||
|
@ -54,6 +53,8 @@ public class FMLModContainer extends ModContainer
|
|||
LOGGER.debug("Creating FMLModContainer instance for {} with classLoader {} & {}", className, modClassLoader, getClass().getClassLoader());
|
||||
this.scanResults = modFileScanResults;
|
||||
triggerMap.put(ModLoadingStage.CONSTRUCT, dummy().andThen(this::beforeEvent).andThen(this::constructMod).andThen(this::afterEvent));
|
||||
triggerMap.put(ModLoadingStage.CREATE_REGISTRIES, dummy().andThen(this::beforeEvent).andThen(this::fireEvent).andThen(this::afterEvent));
|
||||
triggerMap.put(ModLoadingStage.LOAD_REGISTRIES, dummy().andThen(this::beforeEvent).andThen(this::fireEvent).andThen(this::afterEvent));
|
||||
triggerMap.put(ModLoadingStage.COMMON_SETUP, dummy().andThen(this::beforeEvent).andThen(this::preinitMod).andThen(this::fireEvent).andThen(this::afterEvent));
|
||||
triggerMap.put(ModLoadingStage.SIDED_SETUP, dummy().andThen(this::beforeEvent).andThen(this::fireEvent).andThen(this::afterEvent));
|
||||
triggerMap.put(ModLoadingStage.ENQUEUE_IMC, dummy().andThen(this::beforeEvent).andThen(this::initMod).andThen(this::fireEvent).andThen(this::afterEvent));
|
||||
|
@ -96,8 +97,8 @@ public class FMLModContainer extends ModContainer
|
|||
}
|
||||
|
||||
private void fireEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) {
|
||||
final ModLifecycleEvent event = lifecycleEvent.buildModEvent(this);
|
||||
LOGGER.debug(LOADING, "Firing event for modid {} : {}", this.getModId(), event.getClass().getName());
|
||||
final Event event = lifecycleEvent.getOrBuildEvent(this);
|
||||
LOGGER.info(LOADING, "Firing event for modid {} : {}", this.getModId(), event.getClass().getName());
|
||||
try
|
||||
{
|
||||
eventBus.post(event);
|
||||
|
|
|
@ -41,6 +41,7 @@ import net.minecraft.world.biome.Biome;
|
|||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.RegistryEvent.MissingMappings;
|
||||
import net.minecraftforge.fml.LifecycleEventProvider;
|
||||
import net.minecraftforge.fml.ModThreadContext;
|
||||
import net.minecraftforge.fml.StartupQuery;
|
||||
import net.minecraftforge.fml.common.EnhancedRuntimeException;
|
||||
|
@ -61,6 +62,7 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -779,14 +781,17 @@ public class GameData
|
|||
MinecraftForge.EVENT_BUS.post(new RegistryEvent.NewRegistry());
|
||||
}
|
||||
|
||||
public static void fireRegistryEvents()
|
||||
{
|
||||
fireRegistryEvents(rl -> true);
|
||||
public static void fireCreateRegistryEvents(final LifecycleEventProvider lifecycleEventProvider, final Consumer<LifecycleEventProvider> eventDispatcher) {
|
||||
final RegistryEvent.NewRegistry newRegistryEvent = new RegistryEvent.NewRegistry();
|
||||
lifecycleEventProvider.setCustomEventSupplier(()->newRegistryEvent);
|
||||
eventDispatcher.accept(lifecycleEventProvider);
|
||||
}
|
||||
public static void fireRegistryEvents(Predicate<ResourceLocation> filter)
|
||||
|
||||
|
||||
public static void fireRegistryEvents(Predicate<ResourceLocation> filter, final LifecycleEventProvider lifecycleEventProvider, final Consumer<LifecycleEventProvider> eventDispatcher)
|
||||
{
|
||||
List<ResourceLocation> keys = Lists.newArrayList(RegistryManager.ACTIVE.registries.keySet());
|
||||
Collections.sort(keys, (o1, o2) -> o1.toString().compareToIgnoreCase(o2.toString()));
|
||||
keys.sort((o1, o2) -> String.valueOf(o1).compareToIgnoreCase(String.valueOf(o2)));
|
||||
|
||||
//Move Blocks to first, and Items to second.
|
||||
keys.remove(BLOCKS);
|
||||
|
@ -794,16 +799,18 @@ public class GameData
|
|||
|
||||
keys.add(0, BLOCKS);
|
||||
keys.add(1, ITEMS);
|
||||
|
||||
for (ResourceLocation rl : keys)
|
||||
{
|
||||
for (int i = 0, keysSize = keys.size(); i < keysSize; i++) {
|
||||
final ResourceLocation rl = keys.get(i);
|
||||
if (!filter.test(rl)) continue;
|
||||
ForgeRegistry<?> reg = RegistryManager.ACTIVE.getRegistry(rl);
|
||||
reg.unfreeze();
|
||||
MinecraftForge.EVENT_BUS.post(reg.getRegisterEvent(rl));
|
||||
final RegistryEvent.Register<?> registerEvent = reg.getRegisterEvent(rl);
|
||||
lifecycleEventProvider.setCustomEventSupplier(() -> registerEvent);
|
||||
if (i== keysSize-1) lifecycleEventProvider.changeProgression(LifecycleEventProvider.LifecycleEvent.Progression.NEXT);
|
||||
eventDispatcher.accept(lifecycleEventProvider);
|
||||
reg.freeze();
|
||||
LOGGER.info("{} Applying holder lookups", rl.toString());
|
||||
ObjectHolderRegistry.applyObjectHolders(key -> rl.equals(key));
|
||||
ObjectHolderRegistry.applyObjectHolders(rl::equals);
|
||||
LOGGER.info("{} Holder lookups applied", rl.toString());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue