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 ) if ( PVS.IsValid )
{ {
// don't destroy if another SceneWorld is using it // 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 ); 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<SceneObject> InternalSceneObjects { get; set; } = new();
internal HashSet<SceneMap> InternalSceneMaps { get; set; } = new(); internal HashSet<SceneMap> InternalSceneMaps { get; set; } = new();
internal HashSet<SceneSkybox3D> InternalSkyboxWorlds { get; set; } = new(); internal HashSet<SceneSkybox3D> InternalSkyboxWorlds { get; set; } = new();
internal IPVS ActivePVS { get; private set; }
/// <summary> /// <summary>
/// List of scene objects belonging to this scene world. /// List of scene objects belonging to this scene world.
@@ -100,6 +101,7 @@ public sealed partial class SceneWorld : IHandle
CSceneSystem.DestroyWorld( this ); CSceneSystem.DestroyWorld( this );
native = IntPtr.Zero; native = IntPtr.Zero;
ActivePVS = default;
} }
internal void OnNativeInit( ISceneWorld ptr ) internal void OnNativeInit( ISceneWorld ptr )
@@ -111,6 +113,7 @@ public sealed partial class SceneWorld : IHandle
internal void OnNativeDestroy() internal void OnNativeDestroy()
{ {
native = IntPtr.Zero; native = IntPtr.Zero;
ActivePVS = default;
All.Remove( this ); All.Remove( this );
} }
@@ -168,6 +171,7 @@ public sealed partial class SceneWorld : IHandle
{ {
//Log.Info( $"{this} - SET PVS from {sceneMap}" ); //Log.Info( $"{this} - SET PVS from {sceneMap}" );
native.SetPVS( sceneMap.PVS ); native.SetPVS( sceneMap.PVS );
ActivePVS = sceneMap.PVS;
} }
} }
} }
@@ -182,9 +186,13 @@ public sealed partial class SceneWorld : IHandle
Log.Warning( "Couldn't remove sceneMap" ); 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; _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(); GlobalContext.Current.UISystem.Clear();
if ( activePackage != null && !Application.IsStandalone ) if ( activePackage != null && !Application.IsStandalone )
@@ -123,8 +126,6 @@ internal partial class GameInstance : IGameInstance
GameInstanceDll.Current.Shutdown( this ); GameInstanceDll.Current.Shutdown( this );
Game.Shutdown();
// If we were running a benchmark, leave the game // If we were running a benchmark, leave the game
if ( Application.IsBenchmark ) if ( Application.IsBenchmark )
{ {