Skip to content

Commit

Permalink
miscellaneous performance fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
FalsePattern committed Jan 6, 2024
1 parent 9c4f35f commit 62d1695
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/falsepattern/lumina/api/LumiAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private LumiAPI() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

public static @NotNull Iterable<LumiWorld> lumiWorldsFromBaseWorld(@NotNull World worldBase) {
public static @NotNull LumiWorld[] lumiWorldsFromBaseWorld(@NotNull World worldBase) {
return WORLD_WRAPPER.lumiWorldsFromBaseWorld(worldBase);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@

@SuppressWarnings("unused")
public interface LumiWorldWrapper {
@NotNull @Unmodifiable Iterable<LumiWorld> lumiWorldsFromBaseWorld(@Nullable World worldBase);
@NotNull @Unmodifiable LumiWorld[] lumiWorldsFromBaseWorld(@Nullable World worldBase);
}
9 changes: 9 additions & 0 deletions src/main/java/com/falsepattern/lumina/internal/LUMINA.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@

package com.falsepattern.lumina.internal;

import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;

import com.falsepattern.chunk.api.DataRegistry;
import com.falsepattern.falsetweaks.api.ThreadedChunkUpdates;
import lombok.NoArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -46,8 +48,15 @@ public static Logger createLogger(String name) {
return LogManager.getLogger(MOD_NAME + "|" + name);
}

private static boolean falseTweaks;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent evt) {
falseTweaks = Loader.isModLoaded("falsetweaks");
}


public static boolean lumi$isThreadedUpdates() {
return falseTweaks && ThreadedChunkUpdates.isEnabled();
}

@Mod.EventHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@

import com.falsepattern.lumina.api.LumiChunkAPI;
import com.falsepattern.lumina.api.lighting.LightType;
import com.falsepattern.lumina.api.world.LumiWorld;
import com.falsepattern.lumina.api.world.LumiWorldRoot;
import cpw.mods.fml.relauncher.SideOnly;
import lombok.experimental.UtilityClass;
import lombok.val;
import lombok.var;
import org.jetbrains.annotations.NotNull;

import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
Expand Down Expand Up @@ -56,7 +59,9 @@ public static int getCurrentLightValue(Chunk chunkBase,
val posZ = (chunkBase.zPosition << 4) + subChunkPosZ;

var maxLightValue = 0;
for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
val lightValue = lightingEngine.getCurrentLightValue(lightType, posX, posY, posZ);
maxLightValue = Math.max(maxLightValue, lightValue);
Expand All @@ -75,7 +80,9 @@ public static int getCurrentLightValueUncached(Chunk chunkBase,
val posZ = (chunkBase.zPosition << 4) + subChunkPosZ;

var maxLightValue = 0;
for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
val lightValue = lightingEngine.getCurrentLightValueUncached(lightType, posX, posY, posZ);
maxLightValue = Math.max(maxLightValue, lightValue);
Expand All @@ -94,7 +101,9 @@ public static int getMaxBrightness(Chunk chunkBase,
val posZ = (chunkBase.zPosition << 4) + subChunkPosZ;

var maxLightValue = 0;
for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightValue = world.lumi$getBrightness(lightType, posX, posY, posZ);
maxLightValue = Math.max(maxLightValue, lightValue);
}
Expand All @@ -105,7 +114,9 @@ public static boolean isChunkFullyLit(Chunk chunkBase) {
val worldBase = chunkBase.worldObj;

var chunkHasLighting = true;
for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
val chunk = world.lumi$wrap(chunkBase);
chunkHasLighting &= lightingEngine.isChunkFullyLit(chunk);
Expand All @@ -117,7 +128,9 @@ public static void handleChunkInit(Chunk chunkBase) {
val worldBase = chunkBase.worldObj;

resetPrecipitationHeightMap(chunkBase);
for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val chunk = world.lumi$wrap(chunkBase);
LumiChunkAPI.scheduleChunkLightingEngineInit(chunk);
}
Expand All @@ -128,7 +141,9 @@ public static void handleClientChunkInit(Chunk chunkBase) {
val worldBase = chunkBase.worldObj;

resetPrecipitationHeightMap(chunkBase);
for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
val chunk = world.lumi$wrap(chunkBase);
lightingEngine.handleClientChunkInit(chunk);
Expand All @@ -138,7 +153,9 @@ public static void handleClientChunkInit(Chunk chunkBase) {
public static void handleSubChunkInit(Chunk chunkBase, ExtendedBlockStorage subChunkBase) {
val worldBase = chunkBase.worldObj;

for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
val chunk = world.lumi$wrap(chunkBase);
val subChunk = world.lumi$wrap(subChunkBase);
Expand All @@ -149,7 +166,9 @@ public static void handleSubChunkInit(Chunk chunkBase, ExtendedBlockStorage subC
public static void handleSubChunkInit(Chunk chunkBase, int chunkPosY) {
val worldBase = chunkBase.worldObj;

for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
val chunk = world.lumi$wrap(chunkBase);
val subChunk = chunk.lumi$getSubChunk(chunkPosY);
Expand All @@ -160,7 +179,9 @@ public static void handleSubChunkInit(Chunk chunkBase, int chunkPosY) {
public static void handleChunkLoad(Chunk chunkBase) {
val worldBase = chunkBase.worldObj;

for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
val chunk = world.lumi$wrap(chunkBase);
lightingEngine.handleChunkLoad(chunk);
Expand All @@ -172,7 +193,9 @@ public static void doRandomChunkLightingUpdates(Chunk chunkBase) {
// return;
//
// val worldBase = chunkBase.worldObj;
// for (val world : lumiWorldsFromBaseWorld(worldBase)) {
// @NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
// for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
// var world = lumiWorldsFromBaseWorld[i];
// val chunk = world.lumi$wrap(chunkBase);
// val lightingEngine = world.lumi$lightingEngine();
// lightingEngine.doRandomChunkLightingUpdates(chunk);
Expand All @@ -182,7 +205,9 @@ public static void doRandomChunkLightingUpdates(Chunk chunkBase) {
public static void resetQueuedRandomLightUpdates(Chunk chunkBase) {
val worldBase = chunkBase.worldObj;

for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val chunk = world.lumi$wrap(chunkBase);
chunk.lumi$resetQueuedRandomLightUpdates();
}
Expand All @@ -196,7 +221,9 @@ public static void updateLightingForBlock(Chunk chunkBase,
val posX = (chunkBase.xPosition << 4) + subChunkPosX;
val posZ = (chunkBase.zPosition << 4) + subChunkPosZ;

for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
lightingEngine.updateLightingForBlock(posX, posY, posZ);
}
Expand All @@ -208,7 +235,9 @@ public static void scheduleLightingUpdate(World worldBase,
int posY,
int posZ) {
val lightType = LightType.of(baseLightType);
for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
lightingEngine.scheduleLightingUpdate(lightType, posX, posY, posZ);
}
Expand All @@ -220,7 +249,9 @@ public static void processLightUpdates(Chunk chunkBase) {
}

public static void processLightUpdates(World worldBase) {
for (val world : lumiWorldsFromBaseWorld(worldBase)) {
@NotNull LumiWorld[] lumiWorldsFromBaseWorld = lumiWorldsFromBaseWorld(worldBase);
for (int i = 0; i < lumiWorldsFromBaseWorld.length; i++) {
var world = lumiWorldsFromBaseWorld[i];
val lightingEngine = world.lumi$lightingEngine();
lightingEngine.processLightingUpdatesForAllTypes();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of LUMINA.
*
* LUMINA is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LUMINA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LUMINA. If not, see <https://www.gnu.org/licenses/>.
*/

package com.falsepattern.lumina.internal.mixin.interfaces;

import com.falsepattern.lumina.api.world.LumiWorld;

import java.util.Iterator;

public interface LumiWorldRootCache {
LumiWorld[] lumi$getLumiWorlds();
void lumi$setLumiWorlds(LumiWorld[] lumiWorlds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
import com.falsepattern.falsetweaks.api.ThreadedChunkUpdates;
import com.falsepattern.lumina.api.cache.LumiBlockCacheRoot;
import com.falsepattern.lumina.api.chunk.LumiChunkRoot;
import com.falsepattern.lumina.api.world.LumiWorld;
import com.falsepattern.lumina.api.world.LumiWorldRoot;
import com.falsepattern.lumina.internal.LUMINA;
import com.falsepattern.lumina.internal.cache.MultiHeadBlockCacheRoot;
import com.falsepattern.lumina.internal.cache.ReadThroughBlockCacheRoot;
import com.falsepattern.lumina.internal.config.LumiConfig;
import com.falsepattern.lumina.internal.mixin.interfaces.LumiWorldRootCache;
import com.falsepattern.lumina.internal.world.DefaultWorldProvider;
import lombok.val;
import net.minecraft.block.Block;
Expand All @@ -50,12 +53,13 @@

@Unique
@Mixin(value = World.class, priority = LUMI_ROOT_IMPL_MIXIN_PRIORITY)
public abstract class LumiWorldRootImplMixin implements IBlockAccess, LumiWorldRoot {
public abstract class LumiWorldRootImplMixin implements IBlockAccess, LumiWorldRoot, LumiWorldRootCache {
// region Shadow
@Final
@Shadow
public WorldProvider provider;


@Shadow
protected IChunkProvider chunkProvider;
@Shadow
Expand Down Expand Up @@ -88,6 +92,18 @@ public abstract class LumiWorldRootImplMixin implements IBlockAccess, LumiWorldR

private LumiBlockCacheRoot lumi$blockCacheRoot = null;

private LumiWorld[] lumi$lumiWorlds;

@Override
public LumiWorld[] lumi$getLumiWorlds() {
return lumi$lumiWorlds;
}

@Override
public void lumi$setLumiWorlds(LumiWorld[] lumiWorlds) {
lumi$lumiWorlds = lumiWorlds;
}

@Inject(method = LUMI_WORLD_INIT_HOOK_METHOD,
at = @At("RETURN"),
remap = false,
Expand All @@ -99,7 +115,7 @@ private void lumiWorldRootInit(CallbackInfo ci) {
}
int cacheCount = LumiConfig.CACHE_COUNT;

if (cacheCount <= 0 || (Loader.isModLoaded("falsetweaks") && ThreadedChunkUpdates.isEnabled() && lumi$isClientSide())) {
if (cacheCount <= 0 || (LUMINA.lumi$isThreadedUpdates() && lumi$isClientSide())) {
this.lumi$blockCacheRoot = new ReadThroughBlockCacheRoot(this);
} else {
this.lumi$blockCacheRoot = new MultiHeadBlockCacheRoot(this, cacheCount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@
import com.falsepattern.lumina.internal.LumiDefaultValues;
import com.falsepattern.lumina.internal.collection.WeakIdentityHashMap;
import com.falsepattern.lumina.internal.event.EventPoster;
import com.falsepattern.lumina.internal.mixin.interfaces.LumiWorldRootCache;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.val;
import net.minecraft.world.World;

import lombok.var;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -47,7 +50,6 @@ public final class WorldProviderManager implements LumiWorldProviderRegistry, Lu
private static final WorldProviderManager INSTANCE = new WorldProviderManager();

private final List<LumiWorldProvider> worldProviders = new ArrayList<>();
private final Map<World, Iterable<LumiWorld>> providedWorlds = new WeakIdentityHashMap<>();

private boolean isRegistered = false;
private boolean isHijacked = false;
Expand Down Expand Up @@ -138,16 +140,22 @@ public void registerWorldProvider(@NotNull LumiWorldProvider worldProvider) {
worldProviders.add(worldProvider);
}

private static final LumiWorld[] NULL_ARR = new LumiWorld[0];

@Override
public @NotNull @Unmodifiable Iterable<LumiWorld> lumiWorldsFromBaseWorld(@Nullable World worldBase) {
public @NotNull @Unmodifiable LumiWorld[] lumiWorldsFromBaseWorld(@Nullable World worldBase) {
if (!isRegistered) {
LOG.error(new IllegalStateException("No world providers exist during registration, " +
"an empty iterable will be returned."));
return Collections.emptyList();
return NULL_ARR;
}
if (worldBase == null)
return Collections.emptyList();
return providedWorlds.computeIfAbsent(worldBase, this::collectProvidedWorlds);
return NULL_ARR;
var worlds = ((LumiWorldRootCache)worldBase).lumi$getLumiWorlds();
if (worlds == null) {
((LumiWorldRootCache)worldBase).lumi$setLumiWorlds(worlds = collectProvidedWorlds(worldBase));
}
return worlds;
}

public @Nullable LumiWorldProvider getWorldProviderByInternalID(int internalWorldProviderID) {
Expand All @@ -160,11 +168,15 @@ public int worldProviderCount() {
return worldProviders.size();
}

private Iterable<LumiWorld> collectProvidedWorlds(World worldBase) {
val worldList = worldProviders.stream()
.map(worldProvider -> worldProvider.provideWorld(worldBase))
.filter(Objects::nonNull)
.collect(Collectors.toCollection(ArrayList::new));
return Collections.unmodifiableList(worldList);
private LumiWorld[] collectProvidedWorlds(World worldBase) {
val worldList = new ArrayList<LumiWorld>();
for (int i = 0, worldProvidersSize = worldProviders.size(); i < worldProvidersSize; i++) {
LumiWorldProvider worldProvider = worldProviders.get(i);
LumiWorld lumiWorld = worldProvider.provideWorld(worldBase);
if (lumiWorld != null) {
worldList.add(lumiWorld);
}
}
return worldList.toArray(new LumiWorld[0]);
}
}

0 comments on commit 62d1695

Please sign in to comment.