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