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

View file

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

View file

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

View file

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

View file

@ -22,11 +22,16 @@ public class PonderChapterRegistry {
}
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) {
chapters.put(chapter.getId(), Pair.of(chapter, new ArrayList<>()));
synchronized (chapters) {
chapters.put(chapter.getId(), Pair.of(chapter, new ArrayList<>()));
}
return chapter;
}

View file

@ -445,17 +445,17 @@ public class PonderIndex {
.add(Blocks.HONEY_BLOCK);
PonderRegistry.TAGS.forTag(PonderTag.CONTRAPTION_ACTOR)
.add(AllBlocks.MECHANICAL_HARVESTER)
.add(AllBlocks.MECHANICAL_PLOUGH)
.add(AllBlocks.MECHANICAL_DRILL)
.add(AllBlocks.MECHANICAL_SAW)
.add(AllBlocks.DEPLOYER)
.add(AllBlocks.PORTABLE_STORAGE_INTERFACE)
.add(AllBlocks.PORTABLE_FLUID_INTERFACE)
.add(AllBlocks.MECHANICAL_BEARING)
.add(AllBlocks.ANDESITE_FUNNEL)
.add(AllBlocks.BRASS_FUNNEL)
.add(AllBlocks.SEATS.get(DyeColor.WHITE))
.add(AllBlocks.MECHANICAL_HARVESTER)
.add(AllBlocks.MECHANICAL_PLOUGH)
.add(AllBlocks.MECHANICAL_DRILL)
.add(AllBlocks.MECHANICAL_SAW)
.add(AllBlocks.DEPLOYER)
.add(AllBlocks.PORTABLE_STORAGE_INTERFACE)
.add(AllBlocks.PORTABLE_FLUID_INTERFACE)
.add(AllBlocks.MECHANICAL_BEARING)
.add(AllBlocks.ANDESITE_FUNNEL)
.add(AllBlocks.BRASS_FUNNEL)
.add(AllBlocks.SEATS.get(DyeColor.WHITE))
.add(AllBlocks.REDSTONE_CONTACT)
.add(Blocks.BELL)
.add(Blocks.DISPENSER)

View file

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

View file

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