-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Avoid creating and dispatching to empty game event dispatchers
- Loading branch information
Showing
7 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
...java/me/jellysquid/mods/lithium/common/world/chunk/ChunkWithEmptyGameEventDispatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package me.jellysquid.mods.lithium.common.world.chunk; | ||
|
||
import net.minecraft.world.event.listener.GameEventDispatcher; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
public interface ChunkWithEmptyGameEventDispatcher { | ||
|
||
@Nullable GameEventDispatcher lithium$getExistingGameEventDispatcher(int ySectionCoord); | ||
} |
43 changes: 43 additions & 0 deletions
43
...mods/lithium/mixin/world/game_events/dispatch_to_empty/GameEventDispatchManagerMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package me.jellysquid.mods.lithium.mixin.world.game_events.dispatch_to_empty; | ||
|
||
import me.jellysquid.mods.lithium.common.world.chunk.ChunkWithEmptyGameEventDispatcher; | ||
import net.minecraft.registry.entry.RegistryEntry; | ||
import net.minecraft.util.math.Vec3d; | ||
import net.minecraft.world.chunk.Chunk; | ||
import net.minecraft.world.event.GameEvent; | ||
import net.minecraft.world.event.listener.GameEventDispatchManager; | ||
import net.minecraft.world.event.listener.GameEventDispatcher; | ||
import org.jetbrains.annotations.Nullable; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Redirect; | ||
|
||
@Mixin(GameEventDispatchManager.class) | ||
public class GameEventDispatchManagerMixin { | ||
|
||
@Redirect( | ||
method = "dispatch", | ||
at = @At( | ||
value = "INVOKE", | ||
target = "Lnet/minecraft/world/chunk/Chunk;getGameEventDispatcher(I)Lnet/minecraft/world/event/listener/GameEventDispatcher;" | ||
) | ||
) | ||
private GameEventDispatcher existingGameEventDispatcherOrNull(Chunk chunk, int ySectionCoord) { | ||
if (chunk instanceof ChunkWithEmptyGameEventDispatcher) | ||
return ((ChunkWithEmptyGameEventDispatcher) chunk).lithium$getExistingGameEventDispatcher(ySectionCoord); | ||
return chunk.getGameEventDispatcher(ySectionCoord); | ||
} | ||
@Redirect( | ||
method = "dispatch", | ||
at = @At( | ||
value = "INVOKE", | ||
target = "Lnet/minecraft/world/event/listener/GameEventDispatcher;dispatch(Lnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/util/math/Vec3d;Lnet/minecraft/world/event/GameEvent$Emitter;Lnet/minecraft/world/event/listener/GameEventDispatcher$DispatchCallback;)Z" | ||
) | ||
) | ||
private boolean handleNullDispatcher(@Nullable GameEventDispatcher dispatcher, RegistryEntry<GameEvent> gameEventRegistryEntry, Vec3d vec3d, GameEvent.Emitter emitter, GameEventDispatcher.DispatchCallback dispatchCallback) { | ||
if (dispatcher == null) { | ||
return false; | ||
} | ||
return dispatcher.dispatch(gameEventRegistryEntry, vec3d, emitter, dispatchCallback); | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
...me/jellysquid/mods/lithium/mixin/world/game_events/dispatch_to_empty/WorldChunkMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package me.jellysquid.mods.lithium.mixin.world.game_events.dispatch_to_empty; | ||
|
||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; | ||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; | ||
import me.jellysquid.mods.lithium.common.world.chunk.ChunkWithEmptyGameEventDispatcher; | ||
import net.minecraft.util.math.ChunkPos; | ||
import net.minecraft.world.World; | ||
import net.minecraft.world.chunk.ChunkSection; | ||
import net.minecraft.world.chunk.UpgradeData; | ||
import net.minecraft.world.chunk.WorldChunk; | ||
import net.minecraft.world.event.listener.GameEventDispatcher; | ||
import net.minecraft.world.gen.chunk.BlendingData; | ||
import net.minecraft.world.tick.ChunkTickScheduler; | ||
import org.jetbrains.annotations.Nullable; | ||
import org.spongepowered.asm.mixin.Final; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Mutable; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.Redirect; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; | ||
|
||
@Mixin(WorldChunk.class) | ||
public class WorldChunkMixin implements ChunkWithEmptyGameEventDispatcher { | ||
|
||
private static final Int2ObjectOpenHashMap<?> EMPTY_MAP = new Int2ObjectOpenHashMap<>(0); | ||
|
||
@Shadow | ||
@Final | ||
@Mutable | ||
private Int2ObjectMap<GameEventDispatcher> gameEventDispatchers; | ||
|
||
@Redirect( | ||
method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/world/chunk/UpgradeData;Lnet/minecraft/world/tick/ChunkTickScheduler;Lnet/minecraft/world/tick/ChunkTickScheduler;J[Lnet/minecraft/world/chunk/ChunkSection;Lnet/minecraft/world/chunk/WorldChunk$EntityLoader;Lnet/minecraft/world/gen/chunk/BlendingData;)V", | ||
at = @At(value = "NEW", target = "it/unimi/dsi/fastutil/ints/Int2ObjectOpenHashMap"), | ||
require = 1, allow = 1 | ||
) | ||
private Int2ObjectOpenHashMap<?> initGameEventDispatchers() { | ||
return EMPTY_MAP; | ||
} | ||
@Inject( | ||
method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/world/chunk/UpgradeData;Lnet/minecraft/world/tick/ChunkTickScheduler;Lnet/minecraft/world/tick/ChunkTickScheduler;J[Lnet/minecraft/world/chunk/ChunkSection;Lnet/minecraft/world/chunk/WorldChunk$EntityLoader;Lnet/minecraft/world/gen/chunk/BlendingData;)V", | ||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/Heightmap$Type;values()[Lnet/minecraft/world/Heightmap$Type;"), | ||
require = 1, allow = 1 | ||
) | ||
private void replaceWithNullMap(World world, ChunkPos pos, UpgradeData upgradeData, ChunkTickScheduler<?> blockTickScheduler, ChunkTickScheduler<?> fluidTickScheduler, long inhabitedTime, ChunkSection[] sectionArrayInitializer, WorldChunk.EntityLoader entityLoader, BlendingData blendingData, CallbackInfo ci) { | ||
if (this.gameEventDispatchers == EMPTY_MAP) { | ||
this.gameEventDispatchers = null; | ||
} | ||
} | ||
|
||
@Override | ||
public @Nullable GameEventDispatcher lithium$getExistingGameEventDispatcher(int ySectionCoord) { | ||
if (this.gameEventDispatchers != null) { | ||
return this.gameEventDispatchers.get(ySectionCoord); | ||
} | ||
return null; | ||
} | ||
|
||
@Inject( | ||
method = "getGameEventDispatcher(I)Lnet/minecraft/world/event/listener/GameEventDispatcher;", | ||
at = @At(value = "FIELD", shift = At.Shift.BEFORE, target = "Lnet/minecraft/world/chunk/WorldChunk;gameEventDispatchers:Lit/unimi/dsi/fastutil/ints/Int2ObjectMap;") | ||
) | ||
private void initializeCollection(int ySectionCoord, CallbackInfoReturnable<GameEventDispatcher> cir) { | ||
if (this.gameEventDispatchers == null) { | ||
this.gameEventDispatchers = new Int2ObjectOpenHashMap<>(4); | ||
} | ||
} | ||
|
||
@Inject( | ||
method = "removeGameEventDispatcher(I)V", | ||
at = @At("RETURN") | ||
) | ||
private void removeGameEventDispatcher(int ySectionCoord, CallbackInfo ci) { | ||
if (this.gameEventDispatchers != null && this.gameEventDispatchers.isEmpty()) { | ||
this.gameEventDispatchers = null; | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
...va/me/jellysquid/mods/lithium/mixin/world/game_events/dispatch_to_empty/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
@MixinConfigOption( | ||
description = "Create game event dispatchers for chunk sections only when needed, i.e. when a" + | ||
" listener is added to a section. This reduces memory usage for chunks that do not have any listeners." + | ||
" This speeds up attempting to dispatch events when there are no nearby listeners, which could be sculk" + | ||
" sensors, allays, wardens or sculk shriekers." | ||
) | ||
package me.jellysquid.mods.lithium.mixin.world.game_events.dispatch_to_empty; | ||
|
||
import net.caffeinemc.gradle.MixinConfigOption; |
4 changes: 4 additions & 0 deletions
4
src/main/java/me/jellysquid/mods/lithium/mixin/world/game_events/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
@MixinConfigOption(description = "Various improvements to game events (vibrations).") | ||
package me.jellysquid.mods.lithium.mixin.world.game_events; | ||
|
||
import net.caffeinemc.gradle.MixinConfigOption; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters