From 77a0af6c03adf2e55806c6d6ca9c2ebe85d68291 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 10 Apr 2022 09:40:55 +0800 Subject: [PATCH] Synchronise EventBuses properly, hopefully fixing "Where is architectury" race (#235) * Synchronise it properly? * Use synchronised maps rather than local synchronisation Signed-off-by: Max Co-authored-by: shedaniel --- .../event/forge/EventHandlerImpl.java | 14 +++++++++---- .../platform/forge/EventBuses.java | 20 +++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImpl.java b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImpl.java index c9e811d3..86137582 100644 --- a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImpl.java +++ b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImpl.java @@ -19,8 +19,8 @@ package dev.architectury.event.forge; -import dev.architectury.platform.forge.EventBuses; import dev.architectury.forge.ArchitecturyForge; +import dev.architectury.platform.forge.EventBuses; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.MinecraftForge; @@ -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); + }); } } diff --git a/forge/src/main/java/dev/architectury/platform/forge/EventBuses.java b/forge/src/main/java/dev/architectury/platform/forge/EventBuses.java index 75ec6a4a..f6f8c406 100644 --- a/forge/src/main/java/dev/architectury/platform/forge/EventBuses.java +++ b/forge/src/main/java/dev/architectury/platform/forge/EventBuses.java @@ -19,25 +19,31 @@ package dev.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 EVENT_BUS_MAP = new HashMap<>(); - private static final Map>> ON_REGISTERED = new HashMap<>(); + private static final Map EVENT_BUS_MAP = Collections.synchronizedMap(new HashMap<>()); + private static final Multimap> 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 runnable : ON_REGISTERED.getOrDefault(modId, Collections.emptyList())) { - runnable.accept(bus); + for (Consumer 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); } }