Browse Source

Synchronise EventBuses properly, hopefully fixing "Where is architectury" race (#235)

* Synchronise it properly?

* Use synchronised maps rather than local synchronisation

Signed-off-by: Max <maxh2709@gmail.com>
Co-authored-by: shedaniel <daniel@shedaniel.me>
shedaniel 3 years ago
parent
commit
b2b14d73c4

+ 9 - 3
forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImpl.java

@@ -29,17 +29,23 @@ public class EventHandlerImpl {
     @OnlyIn(Dist.CLIENT)
     public static void registerClient() {
         MinecraftForge.EVENT_BUS.register(EventHandlerImplClient.class);
-        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(EventHandlerImplClient.ModBasedEventHandler.class);
+        EventBuses.onRegistered(ArchitecturyForge.MOD_ID, bus -> {
+            bus.register(EventHandlerImplClient.ModBasedEventHandler.class);
+        });
     }
     
     public static void registerCommon() {
         MinecraftForge.EVENT_BUS.register(EventHandlerImplCommon.class);
-        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(EventHandlerImplCommon.ModBasedEventHandler.class);
+        EventBuses.onRegistered(ArchitecturyForge.MOD_ID, bus -> {
+            bus.register(EventHandlerImplCommon.ModBasedEventHandler.class);
+        });
     }
     
     @OnlyIn(Dist.DEDICATED_SERVER)
     public static void registerServer() {
         MinecraftForge.EVENT_BUS.register(EventHandlerImplServer.class);
-        EventBuses.getModEventBus(ArchitecturyForge.MOD_ID).orElseThrow(() -> new IllegalStateException("Where is architectury?")).register(EventHandlerImplServer.ModBasedEventHandler.class);
+        EventBuses.onRegistered(ArchitecturyForge.MOD_ID, bus -> {
+            bus.register(EventHandlerImplServer.ModBasedEventHandler.class);
+        });
     }
 }

+ 12 - 8
forge/src/main/java/me/shedaniel/architectury/platform/forge/EventBuses.java

@@ -19,25 +19,31 @@
 
 package me.shedaniel.architectury.platform.forge;
 
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
 import net.minecraftforge.eventbus.api.IEventBus;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
 import java.util.function.Consumer;
 
 public final class EventBuses {
     private EventBuses() {
     }
     
-    private static final Map<String, IEventBus> EVENT_BUS_MAP = new HashMap<>();
-    private static final Map<String, List<Consumer<IEventBus>>> ON_REGISTERED = new HashMap<>();
+    private static final Map<String, IEventBus> EVENT_BUS_MAP = Collections.synchronizedMap(new HashMap<>());
+    private static final Multimap<String, Consumer<IEventBus>> ON_REGISTERED = Multimaps.synchronizedMultimap(LinkedListMultimap.create());
     
     public static void registerModEventBus(String modId, IEventBus bus) {
         if (EVENT_BUS_MAP.putIfAbsent(modId, bus) != null) {
             throw new IllegalStateException("Can't register event bus for mod '" + modId + "' because it was previously registered!");
         }
         
-        for (Consumer<IEventBus> runnable : ON_REGISTERED.getOrDefault(modId, Collections.emptyList())) {
-            runnable.accept(bus);
+        for (Consumer<IEventBus> consumer : ON_REGISTERED.get(modId)) {
+            consumer.accept(bus);
         }
     }
     
@@ -45,9 +51,7 @@ public final class EventBuses {
         if (EVENT_BUS_MAP.containsKey(modId)) {
             busConsumer.accept(EVENT_BUS_MAP.get(modId));
         } else {
-            synchronized (ON_REGISTERED) {
-                ON_REGISTERED.computeIfAbsent(modId, s -> new ArrayList<>()).add(busConsumer);
-            }
+            ON_REGISTERED.put(modId, busConsumer);
         }
     }