Shutdown scene early (#3576)

* Destroy ActiveScene early during game shutdown
* Don't call into native when deleting scenemaps
This commit is contained in:
Lorenz Junglas
2025-12-11 09:10:03 +01:00
committed by GitHub
parent 1b80ecd2e9
commit 94bb6f886b
3 changed files with 14 additions and 5 deletions

View File

@@ -210,7 +210,7 @@ public sealed partial class SceneMap : IValid
if ( PVS.IsValid )
{
// don't destroy if another SceneWorld is using it
if ( !SceneWorld.All.Where( x => x.IsValid() && x.native.GetPVS() == PVS ).Any() )
if ( !SceneWorld.All.Any( x => x.ActivePVS == PVS ) )
{
g_pEnginePVSManager.DestroyPvs( PVS );
}

View File

@@ -16,6 +16,7 @@ public sealed partial class SceneWorld : IHandle
internal HashSet<SceneObject> InternalSceneObjects { get; set; } = new();
internal HashSet<SceneMap> InternalSceneMaps { get; set; } = new();
internal HashSet<SceneSkybox3D> InternalSkyboxWorlds { get; set; } = new();
internal IPVS ActivePVS { get; private set; }
/// <summary>
/// List of scene objects belonging to this scene world.
@@ -100,6 +101,7 @@ public sealed partial class SceneWorld : IHandle
CSceneSystem.DestroyWorld( this );
native = IntPtr.Zero;
ActivePVS = default;
}
internal void OnNativeInit( ISceneWorld ptr )
@@ -111,6 +113,7 @@ public sealed partial class SceneWorld : IHandle
internal void OnNativeDestroy()
{
native = IntPtr.Zero;
ActivePVS = default;
All.Remove( this );
}
@@ -168,6 +171,7 @@ public sealed partial class SceneWorld : IHandle
{
//Log.Info( $"{this} - SET PVS from {sceneMap}" );
native.SetPVS( sceneMap.PVS );
ActivePVS = sceneMap.PVS;
}
}
}
@@ -182,9 +186,13 @@ public sealed partial class SceneWorld : IHandle
Log.Warning( "Couldn't remove sceneMap" );
}
if ( native.GetPVS() == sceneMap.PVS )
if ( ActivePVS == sceneMap.PVS )
{
native.SetPVS( default );
if ( !native.IsNull )
{
native.SetPVS( default );
}
ActivePVS = default;
}
}
}

View File

@@ -106,6 +106,9 @@ internal partial class GameInstance : IGameInstance
_packageAssembly = null;
// Tear down the active scene while content is still mounted so native handles remain valid during cleanup
Game.Shutdown();
GlobalContext.Current.UISystem.Clear();
if ( activePackage != null && !Application.IsStandalone )
@@ -123,8 +126,6 @@ internal partial class GameInstance : IGameInstance
GameInstanceDll.Current.Shutdown( this );
Game.Shutdown();
// If we were running a benchmark, leave the game
if ( Application.IsBenchmark )
{