Closing the blinds

- Prevent LightUpdater from interacting with invalid levels.
 - Bump version - 0.6.3
This commit is contained in:
Jozufozu 2022-06-22 13:29:28 -07:00
parent af11d1e78b
commit e26195169f
5 changed files with 96 additions and 5 deletions

View File

@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G
org.gradle.daemon = false
# mod version info
mod_version = 0.6.2
mod_version = 0.6.3
mc_update_version = 1.18
minecraft_version = 1.18.2
forge_version = 40.0.15

View File

@ -0,0 +1,50 @@
package com.jozufozu.flywheel.light;
import java.util.stream.Stream;
import com.jozufozu.flywheel.util.box.ImmutableBox;
import net.minecraft.world.level.LightLayer;
public class DummyLightUpdater extends LightUpdater {
public static final DummyLightUpdater INSTANCE = new DummyLightUpdater();
private DummyLightUpdater() {
super(null);
}
@Override
public void tick() {
// noop
}
@Override
public void addListener(LightListener listener) {
// noop
}
@Override
public void removeListener(LightListener listener) {
// noop
}
@Override
public void onLightUpdate(LightLayer type, long sectionPos) {
// noop
}
@Override
public void onLightPacket(int chunkX, int chunkZ) {
// noop
}
@Override
public Stream<ImmutableBox> getAllBoxes() {
return Stream.empty();
}
@Override
public boolean isEmpty() {
return true;
}
}

View File

@ -0,0 +1,32 @@
package com.jozufozu.flywheel.light;
import net.minecraft.client.Minecraft;
import net.minecraft.world.level.LevelAccessor;
/**
* Marker interface for custom/fake levels to indicate that LightUpdater should bother interacting with it.<p>
*
* Implement this if your custom level has light updates at all. If so, be sure to call
* {@link com.jozufozu.flywheel.util.WorldAttached#invalidateWorld} when your level in unloaded.
*/
public interface LightUpdated extends LevelAccessor {
/**
* @return {@code true} if this level is passing light updates into LightUpdater.
*/
default boolean receivesLightUpdates() {
return true;
}
static boolean receivesLightUpdates(LevelAccessor level) {
// The client level is guaranteed to receive updates.
if (Minecraft.getInstance().level == level) {
return true;
}
// Custom/fake levels need to indicate that LightUpdater has meaning.
if (level instanceof LightUpdated c) {
return c.receivesLightUpdates();
}
return false;
}
}

View File

@ -20,14 +20,23 @@ import net.minecraft.world.level.LightLayer;
/**
* Keeps track of what chunks/sections each listener is in, so we can update exactly what needs to be updated.
*
* @apiNote Custom/fake levels (that are {@code != Minecraft.getInstance.level}) need to implement
* {@link LightUpdated} for LightUpdater to work with them.
*/
public class LightUpdater {
private static final WorldAttached<LightUpdater> light = new WorldAttached<>(LightUpdater::new);
private static final WorldAttached<LightUpdater> LEVELS = new WorldAttached<>(LightUpdater::new);
private final ParallelTaskEngine taskEngine;
public static LightUpdater get(LevelAccessor world) {
return light.get(world);
public static LightUpdater get(LevelAccessor level) {
if (LightUpdated.receivesLightUpdates(level)) {
// The level is valid, add it to the map.
return LEVELS.get(level);
} else {
// Fake light updater for a fake level.
return DummyLightUpdater.INSTANCE;
}
}
private final LightProvider provider;

View File

@ -28,7 +28,7 @@ public class WorldAttached<T> {
}
public static void invalidateWorld(LevelAccessor world) {
Iterator<WeakReference<Map<LevelAccessor, ?>>> i = allMaps.iterator();
var i = allMaps.iterator();
while (i.hasNext()) {
Map<LevelAccessor, ?> map = i.next()
.get();