Game engine now uses timespan structures to be more precise.

This commit is contained in:
Harrison Deng 2020-05-27 11:07:18 -05:00
parent a3401e1c22
commit 9ecfd079b2

View File

@ -15,10 +15,11 @@ namespace SlatedGameToolkit.Framework {
WriteTo.File("SlatedGameToolKit.Framework.Log", rollingInterval: RollingInterval.Day, fileSizeLimitBytes: 1048576, rollOnFileSizeLimit: true). WriteTo.File("SlatedGameToolKit.Framework.Log", rollingInterval: RollingInterval.Day, fileSizeLimitBytes: 1048576, rollOnFileSizeLimit: true).
CreateLogger(); CreateLogger();
private static readonly object ignitionLock = new object(); private static readonly object ignitionLock = new object();
private static readonly object deltaUpdateLock = new object();
private static Thread thread; private static Thread thread;
private static volatile bool exit = false, stopped = true; private static volatile bool exit = false, stopped = true;
private static volatile bool deltaChanged = true; private static volatile bool deltaChanged;
private static long updateDeltaTime = 25, frameDeltaTime = 16; private static TimeSpan updateDeltaTime = TimeSpan.FromSeconds(1/200), frameDeltaTime = TimeSpan.FromSeconds(1/60);
/// <summary> /// <summary>
/// The amount of updates per second. /// The amount of updates per second.
@ -28,10 +29,16 @@ namespace SlatedGameToolkit.Framework {
/// <value>The updates per second.</value> /// <value>The updates per second.</value>
public static double UpdatesPerSecond { public static double UpdatesPerSecond {
get { get {
return 1 / TimeSpan.FromMilliseconds(updateDeltaTime).TotalSeconds; return 1 / updateDeltaTime.TotalSeconds;
} }
set { set {
Interlocked.Exchange(ref updateDeltaTime, Math.Max(5, (long) TimeSpan.FromSeconds(1 / value).TotalMilliseconds)); lock (deltaUpdateLock) {
if (1 / value < 0.005) {
updateDeltaTime = TimeSpan.FromSeconds(1/200);
} else {
updateDeltaTime = TimeSpan.FromSeconds(1/value);
}
}
deltaChanged = true; deltaChanged = true;
} }
} }
@ -45,12 +52,16 @@ namespace SlatedGameToolkit.Framework {
/// <value>The target frames per second.</value> /// <value>The target frames per second.</value>
public static double targetFPS { public static double targetFPS {
get { get {
if (frameDeltaTime == 0) return 0; return 1 / frameDeltaTime.TotalSeconds;
return 1 / TimeSpan.FromMilliseconds(frameDeltaTime).TotalSeconds;
} }
set { set {
if (value == 0) Interlocked.Exchange(ref frameDeltaTime, 0); lock (deltaUpdateLock) {
Interlocked.Exchange(ref frameDeltaTime, (long) TimeSpan.FromSeconds(1 / value).TotalMilliseconds); if (value == 0) {
frameDeltaTime = TimeSpan.FromSeconds(0);
} else {
frameDeltaTime = TimeSpan.FromSeconds(1/value);
}
}
deltaChanged = true; deltaChanged = true;
} }
} }
@ -65,34 +76,37 @@ namespace SlatedGameToolkit.Framework {
if (!(o is Manager)) throw new InternalFrameworkException(String.Format("Expected manager object for asynchronous loop. Got {0}", o)); if (!(o is Manager)) throw new InternalFrameworkException(String.Format("Expected manager object for asynchronous loop. Got {0}", o));
Manager manager = (Manager) o; Manager manager = (Manager) o;
manager.initialize(); manager.initialize();
long currentTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); DateTime currentTime = DateTime.Now;
long timePassedFromLastUpdate = 0; TimeSpan timePassedFromLastUpdate;
long timePassedFromLastRender = 0; TimeSpan timePassedFromLastRender;
long updateDeltaTime = 0; TimeSpan updateDeltaTime;
long frameDeltaTime = 0; TimeSpan frameDeltaTime;
deltaChanged = true;
stopped = false; stopped = false;
logger.Information("Game engine initiated."); logger.Information("Game engine initiated.");
while (!exit) { while (!exit) {
if (deltaChanged) { if (deltaChanged) {
updateDeltaTime = Interlocked.Read(ref GameEngine.updateDeltaTime); lock (deltaUpdateLock) {
frameDeltaTime = Interlocked.Read(ref GameEngine.frameDeltaTime); updateDeltaTime = GameEngine.updateDeltaTime;
frameDeltaTime = GameEngine.frameDeltaTime;
}
deltaChanged = false; deltaChanged = false;
} }
long frameStart = DateTimeOffset.Now.ToUnixTimeMilliseconds(); DateTime frameStart = DateTime.Now;
long difference = frameStart - currentTime; TimeSpan difference = frameStart - currentTime;
currentTime = frameStart; currentTime = frameStart;
timePassedFromLastUpdate += difference; timePassedFromLastUpdate += difference;
while (timePassedFromLastUpdate > updateDeltaTime) { while (timePassedFromLastUpdate > updateDeltaTime) {
manager.update(updateDeltaTime); manager.update(updateDeltaTime.TotalMilliseconds);
timePassedFromLastUpdate -= updateDeltaTime; timePassedFromLastUpdate -= updateDeltaTime;
} }
timePassedFromLastRender += difference; timePassedFromLastRender += difference;
if (timePassedFromLastRender > frameDeltaTime) { if (timePassedFromLastRender > frameDeltaTime) {
manager.render(timePassedFromLastUpdate / updateDeltaTime); manager.render(timePassedFromLastUpdate.TotalMilliseconds / updateDeltaTime.TotalMilliseconds);
timePassedFromLastRender = 0; timePassedFromLastRender = TimeSpan.Zero;
} }
} }
manager.removeAllStates(); manager.removeAllStates();