Initial Code commit

This commit is contained in:
xx-TheDoctor-xx
2020-05-11 15:14:08 +01:00
parent 1cf954fa5f
commit fd7f383438
5 changed files with 174 additions and 0 deletions

View File

@ -1,2 +1,5 @@
# Tick Manager
Constant application tick rate library
Usage

8
TickManager.csproj Normal file
View File

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>Library</OutputType>
</PropertyGroup>
</Project>

42
src/TickClock.cs Normal file
View File

@ -0,0 +1,42 @@
using Microsoft.Win32;
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
namespace TickManager
{
/// <summary>
/// Clock that calculates tick time
/// </summary>
public class TickClock
{
/// <summary>
/// The ammount of ticks a millisecond has
/// </summary>
internal const double TicksPerMillisecond = 10000;
/// <summary>
/// Internal application start timestamp
/// </summary>
internal double startTimeStamp;
/// <summary>
/// Resets the TickClock
/// </summary>
public void Reset()
{
startTimeStamp = TickHelper.GetCurrentTimestamp();
}
/// <summary>
/// Register an application tick
/// </summary>
/// <returns>The amount of time the application took to register a tick</returns>
public double Tick()
{
long currentTimestamp = TickHelper.GetCurrentTimestamp();
return (currentTimestamp - startTimeStamp) / TicksPerMillisecond;
}
}
}

51
src/TickHelper.cs Normal file
View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
namespace TickManager
{
internal static class NativeMethods
{
[DllImport("kernel32.dll")]
[ResourceExposure(ResourceScope.None)]
public static extern bool QueryPerformanceCounter(out long value);
}
/// <summary>
/// Helper functions
/// </summary>
public static class TickHelper
{
/// <summary>
/// Convert ticks per second to milliseconds per tick
/// </summary>
/// <param name="tps">Ticks per second</param>
/// <returns>Milliseconds per tick</returns>
public static double TpsToMspt(double tps)
{
return 1D / tps * 1000;
}
/// <summary>
/// Converts milliseconds per tick to ticks per second
/// </summary>
/// <param name="mspt">Milliseconds per tick</param>
/// <returns>Ticks per second</returns>
public static double MsptToTps(double mspt)
{
return 1D / mspt * 1000;
}
internal static long GetCurrentTimestamp()
{
long timestamp;
// took it from Stopwatch
// maybe find a better way to get the current timestamp
NativeMethods.QueryPerformanceCounter(out timestamp);
return timestamp;
}
}
}

70
src/TickManager.cs Normal file
View File

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace TickManager
{
/// <summary>
/// Handles ticking for an application
/// </summary>
public class TickManager
{
/// <summary>
/// The frequency the application should be running at
/// </summary>
internal double internalFrequency;
/// <summary>
/// Variable to store the milliseconds each tick should take
/// </summary>
internal double msptInternal;
/// <summary>
/// Tick clock object
/// </summary>
internal TickClock tc = new TickClock();
/// <summary>
/// The frequency your application will tick
/// </summary>
public int Frequency
{
get => (int)internalFrequency;
set
{
// Tries to get an exact aproximation to the integer because Math...
internalFrequency = value + 0.001;
msptInternal = TickHelper.TpsToMspt(internalFrequency);
}
}
/// <summary>
/// Milliseconds per tick that took to run last tick
/// </summary>
public double MSPT { get; private set; }
/// <summary>
/// The ticks per second the server is running at relative to last tick
/// </summary>
public double TPS
{
get => TickHelper.MsptToTps(MSPT);
}
/// <summary>
/// Checks if the application can process the same tick relative to the frequency set
/// </summary>
/// <returns>Whether the application should process the next tick or not</returns>
public bool CanTick()
{
double internalMspt = tc.Tick();
bool canTick = internalMspt > msptInternal;
if (canTick)
{
MSPT = internalMspt;
tc.Reset();
}
return canTick;
}
}
}