using AcDream.App.Rendering;
using AcDream.App.Rendering.Vfx;
using AcDream.App.Rendering.Wb;
using AcDream.App.Streaming;
using AcDream.App.World;
using AcDream.Core.Vfx;
namespace AcDream.App.Diagnostics;
///
/// Samples the canonical owners used by the connected lifecycle gate. This is
/// deliberately a read-only view: it owns no counters and keeps no mirrored
/// resource state between checkpoints.
///
internal sealed class WorldLifecycleResourceSnapshotSource
{
private readonly GpuWorldState _world;
private readonly LiveEntityAnimationRuntimeView
_animations;
private readonly RenderFrameDiagnosticsController _renderDiagnostics;
private readonly LiveEntityRuntime _liveEntities;
private readonly StreamingController _streaming;
private readonly ParticleSystem _particles;
private readonly ParticleHookSink _particleSink;
private readonly EntityEffectController _effects;
private readonly LiveEntityLightController _lights;
private readonly PhysicsScriptRunner _scripts;
private readonly WbMeshAdapter _meshes;
private readonly TextureCache _textures;
private readonly WbDrawDispatcher _dispatcher;
private readonly FrameProfiler _frameProfiler;
public WorldLifecycleResourceSnapshotSource(
GpuWorldState world,
LiveEntityAnimationRuntimeView animations,
RenderFrameDiagnosticsController renderDiagnostics,
LiveEntityRuntime liveEntities,
StreamingController streaming,
ParticleSystem particles,
ParticleHookSink particleSink,
EntityEffectController effects,
LiveEntityLightController lights,
PhysicsScriptRunner scripts,
WbMeshAdapter meshes,
TextureCache textures,
WbDrawDispatcher dispatcher,
FrameProfiler frameProfiler)
{
_world = world ?? throw new ArgumentNullException(nameof(world));
_animations = animations
?? throw new ArgumentNullException(nameof(animations));
_renderDiagnostics = renderDiagnostics
?? throw new ArgumentNullException(nameof(renderDiagnostics));
_liveEntities = liveEntities
?? throw new ArgumentNullException(nameof(liveEntities));
_streaming = streaming
?? throw new ArgumentNullException(nameof(streaming));
_particles = particles
?? throw new ArgumentNullException(nameof(particles));
_particleSink = particleSink
?? throw new ArgumentNullException(nameof(particleSink));
_effects = effects ?? throw new ArgumentNullException(nameof(effects));
_lights = lights ?? throw new ArgumentNullException(nameof(lights));
_scripts = scripts ?? throw new ArgumentNullException(nameof(scripts));
_meshes = meshes ?? throw new ArgumentNullException(nameof(meshes));
_textures = textures ?? throw new ArgumentNullException(nameof(textures));
_dispatcher = dispatcher
?? throw new ArgumentNullException(nameof(dispatcher));
_frameProfiler = frameProfiler
?? throw new ArgumentNullException(nameof(frameProfiler));
}
public WorldLifecycleResourceSnapshot Capture()
{
ObjectMeshManager meshManager = _meshes.MeshManager
?? throw new InvalidOperationException(
"Lifecycle snapshots require the composed modern mesh manager.");
var mesh = meshManager.Diagnostics;
RenderFrameDiagnosticsSnapshot render = _renderDiagnostics.Snapshot;
GCMemoryInfo memory = GC.GetGCMemoryInfo();
return new WorldLifecycleResourceSnapshot(
LoadedLandblocks: _world.LoadedLandblockIds.Count,
WorldEntities: _world.Entities.Count,
AnimatedEntities: _animations.Count,
VisibleLandblocks: render.VisibleLandblocks,
TotalLandblocks: render.TotalLandblocks,
LiveEntities: _liveEntities.Count,
MaterializedLiveEntities: _liveEntities.MaterializedCount,
PendingLiveTeardowns: _liveEntities.PendingTeardownCount,
PendingLandblockRetirements: _streaming.PendingRetirementCount,
ParticleEmitters: _particles.ActiveEmitterCount,
Particles: _particles.ActiveParticleCount,
ParticleBindings: _particleSink.ActiveBindingCount,
ParticleOwners: _particleSink.TrackedOwnerCount,
EffectOwners: _effects.ReadyOwnerCount,
LightOwners: _lights.TrackedOwnerCount,
ScriptOwners: _scripts.ActiveOwnerCount,
ActiveScripts: _scripts.ActiveScriptCount,
MeshRenderData: mesh.RenderData,
MeshAtlasArrays: mesh.AtlasArrays,
MeshEstimatedBytes: mesh.EstimatedBytes,
StagedMeshUploads: _meshes.StagedUploadBacklog,
StagedMeshBytes: _meshes.StagedUploadBytes,
TrackedGpuBytes: GpuMemoryTracker.AllocatedBytes,
TrackedGpuBuffers: GpuMemoryTracker.BufferCount,
TrackedGpuTextures: GpuMemoryTracker.TextureCount,
OwnedCompositeTextures: _textures.OwnedBindlessTextureCount,
CompositeTextureOwners: _textures.TextureOwnerCount,
ActiveParticleTextures: _textures.ActiveParticleTextureCount,
ParticleTextureOwners: _textures.ParticleTextureOwnerCount,
CompositeWarmupPending:
_dispatcher.LastCompositeWarmupPendingCount,
ManagedBytes: GC.GetTotalMemory(forceFullCollection: false),
ManagedCommittedBytes: memory.TotalCommittedBytes,
Fps: render.Fps,
FrameMilliseconds: render.FrameMilliseconds,
LastFrameProfile: _frameProfiler.LastReport);
}
}