File tree Expand file tree Collapse file tree 7 files changed +94
-0
lines changed
c2me-rewrites-chunk-system/src/main
java/com/ishland/c2me/rewrites/chunksystem Expand file tree Collapse file tree 7 files changed +94
-0
lines changed Original file line number Diff line number Diff line change @@ -20,6 +20,20 @@ public class Config {
2020 """ )
2121 .getBoolean (false , false );
2222
23+ public static final boolean allowPOIUnloading = new ConfigSystem .ConfigAccessor ()
24+ .key ("chunkSystem.allowPOIUnloading" )
25+ .comment ("""
26+ Whether to allow POIs (Point of Interest) to be unloaded
27+ Unloaded POIs are reloaded on-demand or when the corresponding chunks are loaded again,
28+ which should not cause any behavior change
29+ \s
30+ Note:
31+ Vanilla never unloads POIs when chunks unload, causing small memory leaks
32+ These leaks adds up and eventually cause issues after generating millions of chunks
33+ in a single world instance
34+ """ )
35+ .getBoolean (true , false );
36+
2337 public static void init () {
2438 // intentionally empty
2539 }
Original file line number Diff line number Diff line change 1+ package com .ishland .c2me .rewrites .chunksystem .common .ducks ;
2+
3+ import net .minecraft .util .math .ChunkPos ;
4+
5+ public interface IPOIUnloading {
6+
7+ void c2me$unloadPoi (ChunkPos pos );
8+
9+ default boolean c2me$shouldUnloadPoi (ChunkPos pos ) {
10+ return false ;
11+ }
12+
13+ }
Original file line number Diff line number Diff line change 1010import com .ishland .c2me .rewrites .chunksystem .common .ChunkState ;
1111import com .ishland .c2me .rewrites .chunksystem .common .Config ;
1212import com .ishland .c2me .rewrites .chunksystem .common .NewChunkStatus ;
13+ import com .ishland .c2me .rewrites .chunksystem .common .ducks .IPOIUnloading ;
1314import com .ishland .c2me .rewrites .chunksystem .common .fapi .LifecycleEventInvoker ;
1415import com .ishland .flowsched .scheduler .ItemHolder ;
1516import com .ishland .flowsched .scheduler .KeyStatusPair ;
@@ -142,6 +143,8 @@ public CompletionStage<Void> downgradeFromThis(ChunkLoadingContext context) {
142143 listener .setChunkStatus (context .holder ().getKey (), null );
143144 }
144145
146+ ((IPOIUnloading ) ((IThreadedAnvilChunkStorage ) context .tacs ()).getPointOfInterestStorage ()).c2me$unloadPoi (context .holder ().getKey ());
147+
145148 context .holder ().getItem ().set (new ChunkState (null , null , null ));
146149 }, ((IThreadedAnvilChunkStorage ) context .tacs ()).getMainThreadExecutor ());
147150 }
Original file line number Diff line number Diff line change 1818import com .ishland .c2me .rewrites .chunksystem .common .async_chunkio .ChunkIoMainThreadTaskUtils ;
1919import com .ishland .c2me .rewrites .chunksystem .common .async_chunkio .ProtoChunkExtension ;
2020import com .ishland .c2me .rewrites .chunksystem .common .async_chunkio .SerializingRegionBasedStorageExtension ;
21+ import com .ishland .c2me .rewrites .chunksystem .common .ducks .IPOIUnloading ;
2122import com .ishland .c2me .rewrites .chunksystem .common .fapi .LifecycleEventInvoker ;
2223import com .ishland .flowsched .scheduler .ItemHolder ;
2324import com .ishland .flowsched .scheduler .KeyStatusPair ;
@@ -167,6 +168,8 @@ public CompletionStage<Void> downgradeFromThis(ChunkLoadingContext context) {
167168 ((IThreadedAnvilChunkStorage ) context .tacs ()).getWorldGenerationProgressListener ().setChunkStatus (chunk .getPos (), null );
168169 ((IThreadedAnvilChunkStorage ) context .tacs ()).getChunkToNextSaveTimeMs ().remove (chunk .getPos ().toLong ());
169170
171+ ((IPOIUnloading ) ((IThreadedAnvilChunkStorage ) context .tacs ()).getPointOfInterestStorage ()).c2me$unloadPoi (context .holder ().getKey ());
172+
170173 context .holder ().getItem ().set (new ChunkState (null , null , null ));
171174 }, ((IThreadedAnvilChunkStorage ) context .tacs ()).getMainThreadExecutor ());
172175 }
Original file line number Diff line number Diff line change 1+ package com .ishland .c2me .rewrites .chunksystem .mixin ;
2+
3+ import com .ishland .c2me .rewrites .chunksystem .common .ducks .IPOIUnloading ;
4+ import it .unimi .dsi .fastutil .longs .LongSet ;
5+ import net .minecraft .util .math .ChunkPos ;
6+ import net .minecraft .world .poi .PointOfInterestStorage ;
7+ import org .spongepowered .asm .mixin .Final ;
8+ import org .spongepowered .asm .mixin .Mixin ;
9+ import org .spongepowered .asm .mixin .Shadow ;
10+
11+ @ Mixin (PointOfInterestStorage .class )
12+ public abstract class MixinPointOfInterestStorage implements IPOIUnloading {
13+
14+ @ Shadow @ Final private LongSet preloadedChunks ;
15+
16+ @ Override
17+ public boolean c2me$shouldUnloadPoi (ChunkPos pos ) {
18+ return !this .preloadedChunks .contains (pos .toLong ());
19+ }
20+ }
Original file line number Diff line number Diff line change 1+ package com .ishland .c2me .rewrites .chunksystem .mixin ;
2+
3+ import com .ishland .c2me .rewrites .chunksystem .common .Config ;
4+ import com .ishland .c2me .rewrites .chunksystem .common .ducks .IPOIUnloading ;
5+ import it .unimi .dsi .fastutil .longs .Long2ObjectMap ;
6+ import net .minecraft .util .math .ChunkPos ;
7+ import net .minecraft .util .math .ChunkSectionPos ;
8+ import net .minecraft .world .HeightLimitView ;
9+ import net .minecraft .world .storage .SerializingRegionBasedStorage ;
10+ import org .spongepowered .asm .mixin .Final ;
11+ import org .spongepowered .asm .mixin .Mixin ;
12+ import org .spongepowered .asm .mixin .Shadow ;
13+
14+ import java .util .Optional ;
15+
16+ @ Mixin (SerializingRegionBasedStorage .class )
17+ public abstract class MixinSerializingRegionBasedStorage <R > implements IPOIUnloading {
18+
19+ @ Shadow protected abstract void save (ChunkPos pos );
20+
21+ @ Shadow @ Final protected HeightLimitView world ;
22+
23+ @ Shadow @ Final private Long2ObjectMap <Optional <R >> loadedElements ;
24+
25+ @ Override
26+ public void c2me$unloadPoi (ChunkPos pos ) {
27+ if (!Config .allowPOIUnloading ) return ;
28+
29+ if (!this .c2me$shouldUnloadPoi (pos )) {
30+ return ;
31+ }
32+
33+ this .save (pos );
34+ for (int i = this .world .getBottomSectionCoord (); i < this .world .getTopSectionCoord (); i ++) {
35+ this .loadedElements .remove (ChunkSectionPos .asLong (pos .x , i , pos .z ));
36+ }
37+ }
38+
39+ }
Original file line number Diff line number Diff line change 1010 " MixinChunkTicketManagerTicketDistanceLevelPropagator" ,
1111 " MixinMinecraftServer" ,
1212 " MixinNoiseChunkGenerator" ,
13+ " MixinPointOfInterestStorage" ,
14+ " MixinSerializingRegionBasedStorage" ,
1315 " MixinServerChunkManager" ,
1416 " MixinThreadedAnvilChunkStorage" ,
1517 " async_serialization.MixinBlender" ,
You can’t perform that action at this time.
0 commit comments