using System; using System.Collections.Generic; using System.Diagnostics; using nkast.Aether.Physics2D.Common; using CtrEditor.Simulacion.Fluids; using CtrEditor.ObjetosSim; namespace CtrEditor.Simulacion { /// /// Gestor para la simulación de fluidos independiente de la simulación física principal /// public class FluidSimulationManager { private SimulacionFluidos _simulacion; private readonly List _deferredActions = new List(); private readonly List _sistemasRegistrados = new List(); private float _defaultWidth = 10.0f; private float _defaultHeight = 10.0f; private bool _isRunning = false; private Stopwatch _stopwatch; private double _lastUpdateTime; public bool IsRunning => _isRunning; /// /// Constructor /// public FluidSimulationManager() { _stopwatch = new Stopwatch(); } /// /// Inicializa la simulación de fluidos /// public void Initialize() { if (_simulacion == null) { _simulacion = new SimulacionFluidos( _defaultWidth, _defaultHeight, 10000, // max partículas new Vector2(0, 9.8f) // gravedad por defecto ); } } /// /// Inicia la simulación de fluidos /// public void Start() { if (!_isRunning) { _isRunning = true; _stopwatch.Start(); _lastUpdateTime = _stopwatch.Elapsed.TotalMilliseconds; // Notificar a los sistemas de fluidos foreach (var sistema in _sistemasRegistrados) { sistema.OnFluidSimulationStart(); } } } /// /// Detiene la simulación de fluidos /// public void Stop() { if (_isRunning) { _isRunning = false; _stopwatch.Stop(); _stopwatch.Reset(); // Notificar a los sistemas de fluidos foreach (var sistema in _sistemasRegistrados) { sistema.OnFluidSimulationStop(); } } } /// /// Actualiza un paso de la simulación de fluidos /// public void Step() { if (!_isRunning) return; // Calcular delta time double currentTime = _stopwatch.Elapsed.TotalMilliseconds; float deltaTime = (float)(currentTime - _lastUpdateTime) / 1000.0f; _lastUpdateTime = currentTime; // Asegurar que deltaTime no es demasiado grande (evita inestabilidades) if (deltaTime > 0.05f) deltaTime = 0.05f; // Procesar acciones diferidas foreach (var action in _deferredActions) { action(); } _deferredActions.Clear(); // Actualizar la simulación _simulacion?.Actualizar(deltaTime); // Notificar a los sistemas de fluidos foreach (var sistema in _sistemasRegistrados) { sistema.UpdateFluidSimulation(deltaTime); } } /// /// Registra un sistema de fluidos para ser actualizado /// public void RegisterFluidSystem(osSistemaFluidos sistema) { if (!_sistemasRegistrados.Contains(sistema)) { _sistemasRegistrados.Add(sistema); // Si el sistema ya está corriendo, notificar al nuevo sistema if (_isRunning) { sistema.OnFluidSimulationStart(); } } } /// /// Elimina un sistema de fluidos del registro /// public void UnregisterFluidSystem(osSistemaFluidos sistema) { _sistemasRegistrados.Remove(sistema); } /// /// Añade una acción para ser ejecutada en el próximo paso de simulación /// public void AddDeferredAction(Action action) { _deferredActions.Add(action); } /// /// Obtiene la instancia de simulación de fluidos /// public SimulacionFluidos GetSimulacion() { if (_simulacion == null) { Initialize(); } return _simulacion; } /// /// Limpia los recursos de la simulación /// public void Clear() { Stop(); _simulacion = null; _sistemasRegistrados.Clear(); _deferredActions.Clear(); } } }