Synchronization

- Make PonderRegistry use a ThreadLocal current namespace
- Add synchronized blocks to some methods that modify maps or lists
- Move some non-thread safe method calls to the event.enqueueWork
lambdas
This commit is contained in:
PepperBell 2021-07-31 17:28:41 -07:00
parent 296b302160
commit 99be93e8a6
8 changed files with 68 additions and 41 deletions

View file

@ -109,6 +109,7 @@ public class Create {
modEventBus.addListener(AllConfigs::onReload); modEventBus.addListener(AllConfigs::onReload);
modEventBus.addListener(EventPriority.LOWEST, this::gatherData); modEventBus.addListener(EventPriority.LOWEST, this::gatherData);
forgeEventBus.addListener(EventPriority.HIGH, Create::onBiomeLoad); forgeEventBus.addListener(EventPriority.HIGH, Create::onBiomeLoad);
forgeEventBus.register(CHUNK_UTIL);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> CreateClient.addClientListeners(forgeEventBus, modEventBus)); () -> () -> CreateClient.addClientListeners(forgeEventBus, modEventBus));
@ -116,16 +117,14 @@ public class Create {
public static void init(final FMLCommonSetupEvent event) { public static void init(final FMLCommonSetupEvent event) {
CapabilityMinecartController.register(); CapabilityMinecartController.register();
SchematicInstances.register();
CHUNK_UTIL.init();
MinecraftForge.EVENT_BUS.register(CHUNK_UTIL);
AllPackets.registerPackets(); AllPackets.registerPackets();
AllTriggers.register(); SchematicInstances.register();
PotatoCannonProjectileTypes.register(); PotatoCannonProjectileTypes.register();
CHUNK_UTIL.init();
event.enqueueWork(() -> { event.enqueueWork(() -> {
AllTriggers.register();
SchematicProcessor.register(); SchematicProcessor.register();
AllWorldFeatures.registerFeatures(); AllWorldFeatures.registerFeatures();
}); });

View file

@ -107,12 +107,12 @@ public class CreateClient {
UIRenderHelper.init(); UIRenderHelper.init();
event.enqueueWork(() -> {
IResourceManager resourceManager = Minecraft.getInstance() IResourceManager resourceManager = Minecraft.getInstance()
.getResourceManager(); .getResourceManager();
if (resourceManager instanceof IReloadableResourceManager) if (resourceManager instanceof IReloadableResourceManager)
((IReloadableResourceManager) resourceManager).registerReloadListener(new ResourceReloadHandler()); ((IReloadableResourceManager) resourceManager).registerReloadListener(new ResourceReloadHandler());
event.enqueueWork(() -> {
registerLayerRenderers(Minecraft.getInstance() registerLayerRenderers(Minecraft.getInstance()
.getEntityRenderDispatcher()); .getEntityRenderDispatcher());
}); });

View file

@ -253,12 +253,16 @@ public class PotatoCannonProjectileTypes {
; ;
public static void registerType(ResourceLocation resLoc, PotatoCannonProjectileTypes type) { public static void registerType(ResourceLocation resLoc, PotatoCannonProjectileTypes type) {
synchronized (ALL) {
ALL.put(resLoc, type); ALL.put(resLoc, type);
} }
}
public static void assignType(IRegistryDelegate<Item> item, PotatoCannonProjectileTypes type) { public static void assignType(IRegistryDelegate<Item> item, PotatoCannonProjectileTypes type) {
synchronized (ITEM_MAP) {
ITEM_MAP.put(item, type); ITEM_MAP.put(item, type);
} }
}
public static Optional<PotatoCannonProjectileTypes> getProjectileTypeOf(ItemStack item) { public static Optional<PotatoCannonProjectileTypes> getProjectileTypeOf(ItemStack item) {
if (item.isEmpty()) if (item.isEmpty())

View file

@ -41,23 +41,32 @@ public class PonderRegistry {
// Map from item ids to all storyboards // Map from item ids to all storyboards
public static final Map<ResourceLocation, List<PonderStoryBoardEntry>> ALL = new HashMap<>(); public static final Map<ResourceLocation, List<PonderStoryBoardEntry>> ALL = new HashMap<>();
private static String currentNamespace; private static final ThreadLocal<String> CURRENT_NAMESPACE = new ThreadLocal<>();
private static String getCurrentNamespace() {
return CURRENT_NAMESPACE.get();
}
private static void setCurrentNamespace(String namespace) {
CURRENT_NAMESPACE.set(namespace);
}
public static void startRegistration(String namespace) { public static void startRegistration(String namespace) {
if (currentNamespace != null) { if (getCurrentNamespace() != null) {
throw new IllegalStateException("Cannot start registration when already started!"); throw new IllegalStateException("Cannot start registration when already started!");
} }
currentNamespace = namespace; setCurrentNamespace(namespace);
} }
public static void endRegistration() { public static void endRegistration() {
if (currentNamespace == null) { if (getCurrentNamespace() == null) {
throw new IllegalStateException("Cannot end registration when not started!"); throw new IllegalStateException("Cannot end registration when not started!");
} }
currentNamespace = null; setCurrentNamespace(null);
} }
private static String getNamespaceOrThrow() { private static String getNamespaceOrThrow() {
String currentNamespace = getCurrentNamespace();
if (currentNamespace == null) { if (currentNamespace == null) {
throw new IllegalStateException("Cannot register storyboard without starting registration!"); throw new IllegalStateException("Cannot register storyboard without starting registration!");
} }
@ -71,8 +80,10 @@ public class PonderRegistry {
PonderSceneBuilder builder = new PonderSceneBuilder(entry); PonderSceneBuilder builder = new PonderSceneBuilder(entry);
if (tags.length > 0) if (tags.length > 0)
builder.highlightTags(tags); builder.highlightTags(tags);
synchronized (ALL) {
ALL.computeIfAbsent(id, _$ -> new ArrayList<>()) ALL.computeIfAbsent(id, _$ -> new ArrayList<>())
.add(entry); .add(entry);
}
return builder; return builder;
} }

View file

@ -22,11 +22,16 @@ public class PonderChapterRegistry {
} }
public void addStoriesToChapter(@Nonnull PonderChapter chapter, PonderStoryBoardEntry... entries) { public void addStoriesToChapter(@Nonnull PonderChapter chapter, PonderStoryBoardEntry... entries) {
chapters.get(chapter.getId()).getSecond().addAll(Arrays.asList(entries)); List<PonderStoryBoardEntry> entryList = chapters.get(chapter.getId()).getSecond();
synchronized (entryList) {
entryList.addAll(Arrays.asList(entries));
}
} }
PonderChapter addChapter(@Nonnull PonderChapter chapter) { PonderChapter addChapter(@Nonnull PonderChapter chapter) {
synchronized (chapters) {
chapters.put(chapter.getId(), Pair.of(chapter, new ArrayList<>())); chapters.put(chapter.getId(), Pair.of(chapter, new ArrayList<>()));
}
return chapter; return chapter;
} }

View file

@ -49,12 +49,16 @@ public class PonderTagRegistry {
} }
public void add(PonderTag tag, ResourceLocation item) { public void add(PonderTag tag, ResourceLocation item) {
synchronized (tags) {
tags.put(item, tag); tags.put(item, tag);
} }
}
public void add(PonderTag tag, PonderChapter chapter) { public void add(PonderTag tag, PonderChapter chapter) {
synchronized (chapterTags) {
chapterTags.put(chapter, tag); chapterTags.put(chapter, tag);
} }
}
public ItemBuilder forItems(ResourceLocation... items) { public ItemBuilder forItems(ResourceLocation... items) {
return new ItemBuilder(items); return new ItemBuilder(items);

View file

@ -28,7 +28,7 @@ import net.minecraft.util.math.BlockPos;
public class SuperByteBufferCache { public class SuperByteBufferCache {
Map<Compartment<?>, Cache<Object, SuperByteBuffer>> cache; private Map<Compartment<?>, Cache<Object, SuperByteBuffer>> cache;
public SuperByteBufferCache() { public SuperByteBufferCache() {
cache = new HashMap<>(); cache = new HashMap<>();
@ -87,15 +87,19 @@ public class SuperByteBufferCache {
} }
public void registerCompartment(Compartment<?> instance) { public void registerCompartment(Compartment<?> instance) {
synchronized (cache) {
cache.put(instance, CacheBuilder.newBuilder() cache.put(instance, CacheBuilder.newBuilder()
.build()); .build());
} }
}
public void registerCompartment(Compartment<?> instance, long ticksUntilExpired) { public void registerCompartment(Compartment<?> instance, long ticksUntilExpired) {
synchronized (cache) {
cache.put(instance, CacheBuilder.newBuilder() cache.put(instance, CacheBuilder.newBuilder()
.expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS) .expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS)
.build()); .build());
} }
}
private SuperByteBuffer standardBlockRender(BlockState renderedState) { private SuperByteBuffer standardBlockRender(BlockState renderedState) {
BlockRendererDispatcher dispatcher = Minecraft.getInstance() BlockRendererDispatcher dispatcher = Minecraft.getInstance()