using SFML.Graphics; using SFML.Window; using SFML.System; using System.Diagnostics; using FluidSim.Scenarios; using FluidSim.Audio; namespace FluidSim; public class Program { private const int SampleRate = 44100; private static volatile bool running = true; // Global step counter – incremented every simulation step private static long stepCount = 0; public static void Main() { var mode = new VideoMode(new Vector2u(1280, 720)); var window = new RenderWindow(mode, "Fluid Simulation"); window.SetVerticalSyncEnabled(true); window.Closed += (_, _) => { running = false; window.Close(); }; var soundEngine = new SoundEngine(bufferCapacity: 2048); soundEngine.Volume = 70; soundEngine.Start(); var stopwatch = Stopwatch.StartNew(); // --- Warmup: fill audio buffer with silence --- int warmupSamples = SampleRate / 2; // 0.5 s float[] warmup = new float[warmupSamples]; for (int i = 0; i < warmupSamples; i++) warmup[i] = 0; soundEngine.WriteSamples(warmup, warmupSamples); // Reset timer after warmup – this is the “real‑time zero” stopwatch.Restart(); stepCount = 0; // simulation steps start now // --- Initialise the simulation scenario --- Simulation.Initialize(SampleRate); const int chunkSize = 2048; float[] buffer = new float[chunkSize]; double lastLogTime = 0.0; // for periodic speed printout while (window.IsOpen) { window.DispatchEvents(); // --- Compute how many audio samples are needed since last frame --- double currentTime = stopwatch.Elapsed.TotalSeconds; double elapsed = currentTime; // since stopwatch was reset int samplesNeeded = (int)(elapsed * SampleRate) - (int)(stepCount); // (stepCount is total generated samples, so we just need the remainder) // --- Generate the required number of simulation steps --- while (samplesNeeded > 0 && running) { int toGenerate = Math.Min(samplesNeeded, chunkSize); for (int i = 0; i < toGenerate; i++) { buffer[i] = Simulation.Process(); stepCount++; } soundEngine.WriteSamples(buffer, toGenerate); samplesNeeded -= toGenerate; } // --- Display speed --- double simTime = stepCount / (double)SampleRate; double wallTime = stopwatch.Elapsed.TotalSeconds; double speed = (wallTime > 0) ? simTime / wallTime : 0.0; // Update window title with instant speed window.SetTitle($"FluidSim | Speed: {speed:F3}× | Steps: {stepCount}"); // Console log once per second if (wallTime - lastLogTime >= 1.0) { Console.WriteLine($"Speed: {speed:F3}× ({stepCount} steps, {wallTime:F2}s wall)"); lastLogTime = wallTime; } // --- Rendering (placeholder) --- window.Clear(Color.Black); window.Display(); } // --- Cleanup --- soundEngine.Dispose(); window.Dispose(); } }