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); } }