1919
2020package net .patchworkmc .impl ;
2121
22+ import java .util .Collection ;
2223import java .util .HashMap ;
2324import java .util .List ;
2425import java .util .Map ;
26+ import java .util .function .Consumer ;
2527import java .util .function .Function ;
2628import java .util .function .Supplier ;
29+ import java .util .stream .Collectors ;
2730
2831import org .apache .logging .log4j .LogManager ;
2932import org .apache .logging .log4j .Logger ;
30- import net .minecraftforge .api .distmarker .Dist ;
3133import net .minecraftforge .common .MinecraftForge ;
3234import net .minecraftforge .event .RegistryEvent ;
3335import net .minecraftforge .eventbus .api .Event ;
34- import net .minecraftforge .fml .DistExecutor ;
3536import net .minecraftforge .fml .ModContainer ;
3637import net .minecraftforge .fml .ModList ;
3738import net .minecraftforge .fml .ModLoadingContext ;
38- import net .minecraftforge .fml .event .lifecycle .FMLClientSetupEvent ;
3939import net .minecraftforge .fml .event .lifecycle .FMLCommonSetupEvent ;
4040import net .minecraftforge .fml .event .lifecycle .FMLDedicatedServerSetupEvent ;
4141import net .minecraftforge .fml .event .lifecycle .FMLLoadCompleteEvent ;
4545import net .minecraftforge .fml .javafmlmod .FMLModContainer ;
4646import net .minecraftforge .registries .ForgeRegistries ;
4747
48- import net .minecraft .client .MinecraftClient ;
4948import net .minecraft .server .dedicated .DedicatedServer ;
5049
51- import net .fabricmc .api .ModInitializer ;
5250import net .fabricmc .loader .api .FabricLoader ;
5351
5452import net .patchworkmc .api .ForgeInitializer ;
55- import net .patchworkmc .impl .event .lifecycle .LifecycleEvents ;
56- import net .patchworkmc .impl .event .render .RenderEvents ;
57- import net .patchworkmc .impl .modelloader .ModelEventDispatcher ;
5853import net .patchworkmc .impl .registries .RegistryEventDispatcher ;
5954
60- public class Patchwork implements ModInitializer {
55+ public class Patchwork {
6156 private static final Logger LOGGER = LogManager .getLogger (Patchwork .class );
6257
63- private static void dispatch (Map < ForgeInitializer , FMLModContainer > mods , Event event ) {
58+ private static void dispatch (Collection < FMLModContainer > mods , Event event ) {
6459 dispatch (mods , container -> event );
6560 }
6661
67- private static void dispatch (Map <ForgeInitializer , FMLModContainer > mods , Function <ModContainer , Event > provider ) {
68- for (FMLModContainer container : mods .values ()) {
62+ /**
63+ * Fire the specific event for all ModContainers on the {@link Mod.EventBusSubscriber.Bus.MOD} Event bus.
64+ */
65+ private static void dispatch (Collection <FMLModContainer > mods , Function <ModContainer , Event > provider ) {
66+ for (FMLModContainer container : mods ) {
6967 ModLoadingContext .get ().setActiveContainer (container , new FMLJavaModLoadingContext (container ));
7068
7169 Event event = provider .apply (container );
7270 LOGGER .debug ("Firing event for modid {} : {}" , container .getModId (), event .toString ());
73- container .getEventBus (). post (event );
71+ container .patchwork$acceptEvent (event );
7472 LOGGER .debug ("Fired event for modid {} : {}" , container .getModId (), event .toString ());
7573
7674 ModLoadingContext .get ().setActiveContainer (null , "minecraft" );
7775 }
7876 }
7977
80- @ Override
81- public void onInitialize () {
78+ public static void gatherAndInitializeMods () {
8279 ForgeRegistries .init ();
8380
8481 Map <ForgeInitializer , FMLModContainer > mods = new HashMap <>();
@@ -102,6 +99,7 @@ public void onInitialize() {
10299 ModLoadingContext .get ().setActiveContainer (container , new FMLJavaModLoadingContext (container ));
103100
104101 try {
102+ // TODO: Supposed to call "container.setMod()" here, but this requires a WIP Patchwork-Patcher feature.
105103 initializer .onForgeInitialize ();
106104 } catch (Throwable t ) {
107105 if (error == null ) {
@@ -150,27 +148,65 @@ public void onInitialize() {
150148 ModList .get ().setLoadedMods (mods .values ());
151149 // Send initialization events
152150
153- dispatch (mods , new RegistryEvent .NewRegistry ());
154- RegistryEventDispatcher .dispatchRegistryEvents (event -> dispatch (mods , event ));
155- dispatch (mods , FMLCommonSetupEvent ::new );
156-
157- DistExecutor .runWhenOn (Dist .CLIENT , () -> () -> {
158- ModelEventDispatcher .fireModelRegistryEvent ();
159- dispatch (mods , container -> new FMLClientSetupEvent (MinecraftClient ::getInstance , container ));
160- RenderEvents .registerEventDispatcher (event -> dispatch (mods , event ));
161- });
151+ dispatch (mods .values (), new RegistryEvent .NewRegistry ());
152+ RegistryEventDispatcher .dispatchRegistryEvents (event -> dispatch (mods .values (), event ));
153+ }
162154
163- DistExecutor .runWhenOn (Dist .DEDICATED_SERVER , () -> () -> {
164- Object gameInstance = FabricLoader .getInstance ().getGameInstance ();
165- Supplier <DedicatedServer > supplier = () -> (DedicatedServer ) gameInstance ;
155+ /**
156+ * This is called on the ResourceLoader's thread when a resource loading happens, i.e. during client start-up or F3+T is pressed.
157+ * Forge fires the FMLCommonSetupEvent and LifeCycleEvents(FMLClientSetupEvent and FMLDedicatedServerSetupEvent) on its own thread in parallel. Sequence cannot be guaranteed.
158+ * IMPORTANT: In Patchwork, we fire all events on the main thread (Client Thread or Server Thread).
159+ * @param lifeCycleEvent
160+ * @param preSidedRunnable Fired before the LifeCycleEvent, on the main thread. Sequence cannot be guaranteed.
161+ * @param postSidedRunnable Fired after the LifeCycleEvent, on the main thread. Sequence cannot be guaranteed.
162+ */
163+ public static void loadMods (Function <ModContainer , Event > lifeCycleEvent , Consumer <Consumer <Supplier <Event >>> preSidedRunnable , Consumer <Consumer <Supplier <Event >>> postSidedRunnable ) {
164+ List <FMLModContainer > mods = ModList .get ().applyForEachModContainer (m -> (FMLModContainer ) m ).collect (Collectors .toList ());
165+
166+ // Loading mod config
167+ // TODO: Load client and common configs here
168+
169+ // Mod setup: SETUP
170+ dispatch (mods , FMLCommonSetupEvent ::new );
171+ // Mod setup: SIDED SETUP
172+ preSidedRunnable .accept (c -> dispatch (mods , c .get ()));
173+ dispatch (mods , lifeCycleEvent );
174+ postSidedRunnable .accept (c -> dispatch (mods , c .get ()));
175+ // Mod setup complete
176+ }
166177
167- dispatch (mods , container -> new FMLDedicatedServerSetupEvent (supplier , container ));
168- });
178+ /**
179+ * In Patchwork, we fire all of following events on the main thread (Client Thread or Server Thread).
180+ */
181+ public static void finishMods () {
182+ List <FMLModContainer > mods = ModList .get ().applyForEachModContainer (m -> (FMLModContainer ) m ).collect (Collectors .toList ());
169183
184+ // Mod setup: ENQUEUE IMC
170185 dispatch (mods , InterModEnqueueEvent ::new );
186+ // Mod setup: PROCESS IMC
171187 dispatch (mods , InterModProcessEvent ::new );
172- LifecycleEvents .setLoadCompleteCallback (() -> dispatch (mods , FMLLoadCompleteEvent ::new ));
188+ // Mod setup: Final completion
189+ dispatch (mods , FMLLoadCompleteEvent ::new );
190+ // Freezing data, TODO: do we need freezing?
191+ // GameData.freezeData();
192+ // NetworkRegistry.lock();
193+ }
194+
195+ public static void beginServerModLoading () {
196+ Object gameInstance = FabricLoader .getInstance ().getGameInstance ();
197+ Supplier <DedicatedServer > supplier = () -> (DedicatedServer ) gameInstance ;
198+
199+ LOGGER .debug ("Patchwork Dedicated Server Mod Loader: Start mod loading." );
200+ Patchwork .gatherAndInitializeMods ();
201+ Patchwork .loadMods (container -> new FMLDedicatedServerSetupEvent (supplier , container ), dummy -> { }, dummy -> { });
202+ }
203+
204+ public static void endOfServerModLoading () {
205+ LOGGER .debug ("Patchwork Dedicated Server Mod Loader: Finish mod loading." );
206+ Patchwork .finishMods ();
173207
208+ LOGGER .debug ("Patchwork Dedicated Server Mod Loader: Complete mod loading" );
209+ // Assume there's no error.
174210 MinecraftForge .EVENT_BUS .start ();
175211 }
176212}
0 commit comments