add immersive portals support
This commit is contained in:
committed by
Acuadragon100
parent
40040294e7
commit
e65b1e2dfc
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program 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, version 3.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common;
|
||||
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
|
||||
/**
|
||||
* Runtime detection and compatibility handling for Immersive Portals
|
||||
*/
|
||||
public class ImmersivePortalsCompat
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static volatile Boolean isImmersivePortalsPresent = null;
|
||||
private static volatile Boolean isImmersivePortalsActive = null;
|
||||
|
||||
/**
|
||||
* Check if Immersive Portals is present in the mod environment
|
||||
*/
|
||||
public static boolean isImmersivePortalsPresent()
|
||||
{
|
||||
if (isImmersivePortalsPresent == null)
|
||||
{
|
||||
synchronized (ImmersivePortalsCompat.class)
|
||||
{
|
||||
if (isImmersivePortalsPresent == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try to load an Immersive Portals class
|
||||
Class.forName("qouteall.imm_ptl.core.IPMcHelper");
|
||||
isImmersivePortalsPresent = true;
|
||||
LOGGER.info("Immersive Portals detected - enabling compatibility features");
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
isImmersivePortalsPresent = false;
|
||||
LOGGER.debug("Immersive Portals not detected - using standard level management");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isImmersivePortalsPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Immersive Portals compatibility should be active
|
||||
* This checks both presence and configuration
|
||||
*/
|
||||
public static boolean isImmersivePortalsActive()
|
||||
{
|
||||
if (isImmersivePortalsActive == null)
|
||||
{
|
||||
synchronized (ImmersivePortalsCompat.class)
|
||||
{
|
||||
if (isImmersivePortalsActive == null)
|
||||
{
|
||||
// TODO: Add configuration check here
|
||||
isImmersivePortalsActive = isImmersivePortalsPresent();
|
||||
}
|
||||
}
|
||||
}
|
||||
return isImmersivePortalsActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset detection cache (useful for testing)
|
||||
*/
|
||||
public static void resetDetection()
|
||||
{
|
||||
isImmersivePortalsPresent = null;
|
||||
isImmersivePortalsActive = null;
|
||||
}
|
||||
}
|
||||
+53
-3
@@ -6,6 +6,7 @@ import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.block.ClientBlockStateColorCache;
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.level.*;
|
||||
@@ -79,9 +80,9 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
|
||||
private boolean cloudColorFailLogged = false;
|
||||
|
||||
private BlockStateWrapper dirtBlockWrapper;
|
||||
private IDhLevel dhLevel;
|
||||
|
||||
private volatile BlockStateWrapper dirtBlockWrapper;
|
||||
private volatile IDhLevel dhLevel;
|
||||
private volatile long lastRenderTime = System.currentTimeMillis();
|
||||
|
||||
|
||||
//=============//
|
||||
@@ -100,6 +101,55 @@ public class ClientLevelWrapper implements IClientLevelWrapper
|
||||
//==================//
|
||||
//region
|
||||
|
||||
public synchronized void markRendered() {
|
||||
this.lastRenderTime = System.currentTimeMillis();
|
||||
}
|
||||
public long getLastRenderTime() { return this.lastRenderTime; }
|
||||
public boolean isDhLevelLoaded() {
|
||||
return this.dhLevel != null;
|
||||
}
|
||||
|
||||
public static void tickCleanup()
|
||||
{
|
||||
if (MINECRAFT.level == null) { return; }
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long timeout = 30 * 1000;
|
||||
|
||||
java.util.List<ClientLevelWrapper> toUnload = new java.util.ArrayList<>();
|
||||
|
||||
synchronized(LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL)
|
||||
{
|
||||
for (java.lang.ref.WeakReference<ClientLevelWrapper> ref : LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.values())
|
||||
{
|
||||
ClientLevelWrapper wrapper = ref.get();
|
||||
if (wrapper != null && wrapper.isDhLevelLoaded() && wrapper.level != MINECRAFT.level)
|
||||
{
|
||||
if (currentTime - wrapper.getLastRenderTime() > timeout)
|
||||
{
|
||||
toUnload.add(wrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ClientLevelWrapper wrapper : toUnload)
|
||||
{
|
||||
// Re-verify all conditions inside a synchronized block on the wrapper
|
||||
// to ensure atomicity with respect to markRendered()
|
||||
synchronized(wrapper)
|
||||
{
|
||||
if (wrapper.isDhLevelLoaded() && wrapper.level != MINECRAFT.level && currentTime - wrapper.getLastRenderTime() > timeout)
|
||||
{
|
||||
LOGGER.debug("Unloading level " + wrapper.getDhIdentifier() + " due to inactivity");
|
||||
ClientApi.INSTANCE.clientLevelUnloadEvent(wrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* can be used when speed is important and the same level is likely to be passed in,
|
||||
* IE rendering.
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
|
||||
private static final Map<ServerLevel, WeakReference<ServerLevelWrapper>> LEVEL_WRAPPER_REF_BY_SERVER_LEVEL = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
|
||||
private final ServerLevel level;
|
||||
private IDhLevel dhLevel;
|
||||
private volatile IDhLevel dhLevel;
|
||||
|
||||
/**
|
||||
* this name is cached to prevent issues during shutdown where
|
||||
|
||||
Reference in New Issue
Block a user