using System;
using System.Diagnostics;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Simulacion.Fluids;
using nkast.Aether.Physics2D.Common;
using CtrEditor.ObjetosSim;
namespace CtrEditor
{
///
/// ViewModel para controlar la simulación de fluidos de forma independiente
///
public partial class SimulationFluidsViewModel : ObservableObject
{
private MainViewModel _mainViewModel;
private readonly DispatcherTimer _timerSimulacionFluidos;
private Stopwatch _stopwatch;
private double _lastUpdateTime;
// Propiedades observables
[ObservableProperty]
private bool isFluidSimulationRunning;
[ObservableProperty]
private float fps;
[ObservableProperty]
private int particulasCount;
///
/// Constructor
///
/// Referencia al ViewModel principal
public SimulationFluidsViewModel(MainViewModel mainViewModel)
{
_mainViewModel = mainViewModel;
// Inicializar timer para simulación de fluidos
_timerSimulacionFluidos = new DispatcherTimer();
_timerSimulacionFluidos.Interval = TimeSpan.FromMilliseconds(16); // ~60fps
_timerSimulacionFluidos.Tick += OnTickSimulacionFluidos;
_stopwatch = new Stopwatch();
_stopwatch.Start();
}
///
/// Inicia la simulación de fluidos
///
public void StartFluidSimulation()
{
if (IsFluidSimulationRunning)
return;
IsFluidSimulationRunning = true;
// Notificar a todos los objetos que usan fluidos que inicie su simulación
foreach (var objetoSimulable in _mainViewModel.ObjetosSimulables)
{
if (objetoSimulable is osSistemaFluidos sistemaFluidos)
{
sistemaFluidos.UpdateGeometryStart();
}
}
_lastUpdateTime = _stopwatch.Elapsed.TotalMilliseconds;
_timerSimulacionFluidos.Start();
}
///
/// Detiene la simulación de fluidos
///
public void StopFluidSimulation()
{
if (!IsFluidSimulationRunning)
return;
IsFluidSimulationRunning = false;
_timerSimulacionFluidos.Stop();
// Notificar a todos los objetos que usan fluidos que detenga su simulación
foreach (var objetoSimulable in _mainViewModel.ObjetosSimulables)
{
if (objetoSimulable is osSistemaFluidos sistemaFluidos)
{
sistemaFluidos.SimulationStop();
}
}
}
///
/// Evento que se dispara cada tick de la simulación de fluidos
///
private void OnTickSimulacionFluidos(object sender, EventArgs e)
{
// Calcular delta time
double currentTime = _stopwatch.Elapsed.TotalMilliseconds;
float deltaTime = (float)(currentTime - _lastUpdateTime) / 1000.0f; // convertir a segundos
_lastUpdateTime = currentTime;
int totalParticleCount = 0;
// Actualizar todos los sistemas de fluidos
foreach (var objetoSimulable in _mainViewModel.ObjetosSimulables)
{
if (objetoSimulable is osSistemaFluidos sistemaFluidos && sistemaFluidos.Show_On_This_Page)
{
// Actualizar la simulación con el deltaTime calculado
if (sistemaFluidos._simFluidos != null)
{
sistemaFluidos._simFluidos.Actualizar(deltaTime);
totalParticleCount += sistemaFluidos._simFluidos.ParticlesCount;
}
// Actualizar controles visuales
sistemaFluidos.UpdateControl((int)(deltaTime * 1000));
}
}
// Actualizar estadísticas
Fps = 1.0f / Math.Max(deltaTime, 0.001f);
ParticulasCount = totalParticleCount;
}
}
}