mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-12 08:18:29 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
175 lines
4.6 KiB
C#
175 lines
4.6 KiB
C#
using System;
|
|
|
|
[TestClass]
|
|
public class FixedUpdateTests
|
|
{
|
|
[TestMethod]
|
|
[DataRow( 1, 5, 11 )] // Very low frequency
|
|
[DataRow( 5, 5, 59 )] // Standard case
|
|
[DataRow( 30, 5, 359 )] // Higher frequency
|
|
[DataRow( 60, 5, 719 )] // Same as frame rate
|
|
[DataRow( 120, 5, 1439 )] // Higher than frame rate
|
|
[DataRow( 1, 1, 11 )] // maxSteps = 1, low frequency
|
|
[DataRow( 10, 1, 119 )] // maxSteps = 1, medium frequency
|
|
[DataRow( 60, 2, 719 )] // maxSteps = 2, high frequency (maxSteps doesn't limit here)
|
|
public void TestFixedUpdateFrequency( int frequency, int maxSteps, int expectedCalls )
|
|
{
|
|
var fu = new FixedUpdate();
|
|
fu.Frequency = frequency;
|
|
var fixedDelta = fu.Delta;
|
|
int callTimes = 0;
|
|
Action action = () =>
|
|
{
|
|
callTimes++;
|
|
Assert.AreEqual( Time.Delta, fixedDelta, "Fixed delta doesn't match!" );
|
|
|
|
// Get the remainder as a number around 0
|
|
float remainder = (Time.Now % fixedDelta);
|
|
if ( remainder > fixedDelta / 2 ) remainder = fixedDelta - remainder;
|
|
Assert.AreEqual( 0, remainder, 0.00001f, "Time.Now doesn't align with step!" );
|
|
};
|
|
|
|
float time = 0;
|
|
float fps = 60;
|
|
float frameDelta = 1.0f / fps;
|
|
int loops = 0;
|
|
|
|
// Simulate 12 seconds (shorter time for faster test execution)
|
|
while ( time < 12.0f )
|
|
{
|
|
loops++;
|
|
fu.Run( action, time, maxSteps );
|
|
time += frameDelta;
|
|
}
|
|
|
|
Console.WriteLine( $"{loops} loops at {fps:N0} FPS with maxSteps={maxSteps} gave {callTimes} fixed updates at {frequency} Hz" );
|
|
|
|
// Allow small tolerance for floating point differences at very low frequencies
|
|
if ( frequency <= 1 )
|
|
{
|
|
Assert.IsTrue( Math.Abs( expectedCalls - callTimes ) <= 1,
|
|
$"Expected approximately {expectedCalls} calls, got {callTimes}" );
|
|
}
|
|
else
|
|
{
|
|
Assert.AreEqual( expectedCalls, callTimes );
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TestDeltaCalculation()
|
|
{
|
|
var fu = new FixedUpdate();
|
|
|
|
// Test various frequencies
|
|
fu.Frequency = 10;
|
|
Assert.AreEqual( 0.1f, fu.Delta, 0.00001f );
|
|
|
|
fu.Frequency = 60;
|
|
Assert.AreEqual( 1.0f / 60, fu.Delta, 0.00001f );
|
|
|
|
fu.Frequency = 1;
|
|
Assert.AreEqual( 1.0f, fu.Delta, 0.00001f );
|
|
|
|
// Test non-integer frequency
|
|
fu.Frequency = 16.7f; // Approx 60fps / 1000 * 16.7ms
|
|
Assert.AreEqual( 1.0f / 16.7f, fu.Delta, 0.00001f );
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TestMaxSteps()
|
|
{
|
|
var fu = new FixedUpdate();
|
|
fu.Frequency = 10; // 10Hz = 0.1s per update
|
|
int callCount = 0;
|
|
Action action = () => callCount++;
|
|
|
|
// Start at time 0
|
|
fu.Run( action, 0, 5 );
|
|
Assert.AreEqual( 0, callCount, "No updates should occur at start" );
|
|
|
|
// Jump ahead by 1 second (10 steps)
|
|
fu.Run( action, 1.0f, 5 );
|
|
Assert.AreEqual( 5, callCount, "Should be limited by maxSteps" );
|
|
|
|
// Small increment should continue from where we left off
|
|
fu.Run( action, 1.1f, 5 );
|
|
Assert.AreEqual( 6, callCount, "Should get 1 more update" );
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TestTimeNotAdvancing()
|
|
{
|
|
var fu = new FixedUpdate();
|
|
fu.Frequency = 10;
|
|
int callCount = 0;
|
|
Action action = () => callCount++;
|
|
|
|
// First call
|
|
fu.Run( action, 1.0f, 5 );
|
|
int firstCallCount = callCount;
|
|
|
|
// Call again with same time
|
|
fu.Run( action, 1.0f, 5 );
|
|
Assert.AreEqual( firstCallCount, callCount, "No updates should occur when time doesn't advance" );
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TestNegativeTime()
|
|
{
|
|
var fu = new FixedUpdate();
|
|
fu.Frequency = 10;
|
|
int callCount = 0;
|
|
Action action = () => callCount++;
|
|
|
|
// First call with negative time
|
|
fu.Run( action, -1.0f, 5 );
|
|
|
|
// Then positive time
|
|
fu.Run( action, 0.5f, 5 );
|
|
|
|
// We expect calls because we're moving forward in time
|
|
Assert.IsTrue( callCount > 0, "Should get updates when moving from negative to positive time" );
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TestNonIntegerFrequency()
|
|
{
|
|
var fu = new FixedUpdate();
|
|
fu.Frequency = 2.5f; // 2.5Hz = 0.4s per update
|
|
int callCount = 0;
|
|
Action action = () => callCount++;
|
|
|
|
float time = 0;
|
|
float fps = 60;
|
|
float frameDelta = 1.0f / fps;
|
|
|
|
// Simulate 1 second
|
|
while ( time < 1.0f )
|
|
{
|
|
fu.Run( action, time, 5 );
|
|
time += frameDelta;
|
|
}
|
|
|
|
// At 2.5Hz, we expect 2 or 3 calls in 1 second
|
|
// (Depends on floating point precision and exact timing)
|
|
Assert.IsTrue( callCount >= 2 && callCount <= 3,
|
|
$"Expected 2-3 updates with 2.5Hz in 1 second, got {callCount}" );
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TestLargeTimeJump()
|
|
{
|
|
var fu = new FixedUpdate();
|
|
fu.Frequency = 10; // 10Hz
|
|
int callCount = 0;
|
|
Action action = () => callCount++;
|
|
|
|
// Jump ahead by a large amount (20 seconds = 200 updates at 10Hz)
|
|
fu.Run( action, 20.0f, 10 );
|
|
|
|
// Should be limited by maxSteps
|
|
Assert.AreEqual( 10, callCount );
|
|
}
|
|
}
|