Codingstyle nullable
This commit is contained in:
+125
-140
@@ -1,143 +1,128 @@
|
||||
namespace Swan.Diagnostics
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Threading;
|
||||
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Swan.Threading;
|
||||
|
||||
namespace Swan.Diagnostics {
|
||||
/// <summary>
|
||||
/// A time measurement artifact.
|
||||
/// </summary>
|
||||
internal sealed class RealTimeClock : IDisposable {
|
||||
private readonly Stopwatch _chrono = new Stopwatch();
|
||||
private ISyncLocker? _locker = SyncLockerFactory.Create(useSlim: true);
|
||||
private Int64 _offsetTicks;
|
||||
private Double _speedRatio = 1.0d;
|
||||
private Boolean _isDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// A time measurement artifact.
|
||||
/// Initializes a new instance of the <see cref="RealTimeClock"/> class.
|
||||
/// The clock starts paused and at the 0 position.
|
||||
/// </summary>
|
||||
internal sealed class RealTimeClock : IDisposable
|
||||
{
|
||||
private readonly Stopwatch _chrono = new Stopwatch();
|
||||
private ISyncLocker? _locker = SyncLockerFactory.Create(useSlim: true);
|
||||
private long _offsetTicks;
|
||||
private double _speedRatio = 1.0d;
|
||||
private bool _isDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RealTimeClock"/> class.
|
||||
/// The clock starts paused and at the 0 position.
|
||||
/// </summary>
|
||||
public RealTimeClock()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the clock position.
|
||||
/// </summary>
|
||||
public TimeSpan Position
|
||||
{
|
||||
get
|
||||
{
|
||||
using (_locker?.AcquireReaderLock())
|
||||
{
|
||||
return TimeSpan.FromTicks(
|
||||
_offsetTicks + Convert.ToInt64(_chrono.Elapsed.Ticks * SpeedRatio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the clock is running.
|
||||
/// </summary>
|
||||
public bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
using (_locker?.AcquireReaderLock())
|
||||
{
|
||||
return _chrono.IsRunning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the speed ratio at which the clock runs.
|
||||
/// </summary>
|
||||
public double SpeedRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
using (_locker?.AcquireReaderLock())
|
||||
{
|
||||
return _speedRatio;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
using (_locker?.AcquireWriterLock())
|
||||
{
|
||||
if (value < 0d) value = 0d;
|
||||
|
||||
// Capture the initial position se we set it even after the Speed Ratio has changed
|
||||
// this ensures a smooth position transition
|
||||
var initialPosition = Position;
|
||||
_speedRatio = value;
|
||||
Update(initialPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a new position value atomically.
|
||||
/// </summary>
|
||||
/// <param name="value">The new value that the position property will hold.</param>
|
||||
public void Update(TimeSpan value)
|
||||
{
|
||||
using (_locker?.AcquireWriterLock())
|
||||
{
|
||||
var resume = _chrono.IsRunning;
|
||||
_chrono.Reset();
|
||||
_offsetTicks = value.Ticks;
|
||||
if (resume) _chrono.Start();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts or resumes the clock.
|
||||
/// </summary>
|
||||
public void Play()
|
||||
{
|
||||
using (_locker?.AcquireWriterLock())
|
||||
{
|
||||
if (_chrono.IsRunning) return;
|
||||
_chrono.Start();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pauses the clock.
|
||||
/// </summary>
|
||||
public void Pause()
|
||||
{
|
||||
using (_locker?.AcquireWriterLock())
|
||||
{
|
||||
_chrono.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the clock position to 0 and stops it.
|
||||
/// The speed ratio is not modified.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
using (_locker?.AcquireWriterLock())
|
||||
{
|
||||
_offsetTicks = 0;
|
||||
_chrono.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (_isDisposed) return;
|
||||
_isDisposed = true;
|
||||
_locker?.Dispose();
|
||||
_locker = null;
|
||||
}
|
||||
}
|
||||
public RealTimeClock() => this.Reset();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the clock position.
|
||||
/// </summary>
|
||||
public TimeSpan Position {
|
||||
get {
|
||||
using(this._locker?.AcquireReaderLock()) {
|
||||
return TimeSpan.FromTicks(this._offsetTicks + Convert.ToInt64(this._chrono.Elapsed.Ticks * this.SpeedRatio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the clock is running.
|
||||
/// </summary>
|
||||
public Boolean IsRunning {
|
||||
get {
|
||||
using(this._locker?.AcquireReaderLock()) {
|
||||
return this._chrono.IsRunning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the speed ratio at which the clock runs.
|
||||
/// </summary>
|
||||
public Double SpeedRatio {
|
||||
get {
|
||||
using(this._locker?.AcquireReaderLock()) {
|
||||
return this._speedRatio;
|
||||
}
|
||||
}
|
||||
set {
|
||||
using(this._locker?.AcquireWriterLock()) {
|
||||
if(value < 0d) {
|
||||
value = 0d;
|
||||
}
|
||||
|
||||
// Capture the initial position se we set it even after the Speed Ratio has changed
|
||||
// this ensures a smooth position transition
|
||||
TimeSpan initialPosition = this.Position;
|
||||
this._speedRatio = value;
|
||||
this.Update(initialPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a new position value atomically.
|
||||
/// </summary>
|
||||
/// <param name="value">The new value that the position property will hold.</param>
|
||||
public void Update(TimeSpan value) {
|
||||
using(this._locker?.AcquireWriterLock()) {
|
||||
Boolean resume = this._chrono.IsRunning;
|
||||
this._chrono.Reset();
|
||||
this._offsetTicks = value.Ticks;
|
||||
if(resume) {
|
||||
this._chrono.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts or resumes the clock.
|
||||
/// </summary>
|
||||
public void Play() {
|
||||
using(this._locker?.AcquireWriterLock()) {
|
||||
if(this._chrono.IsRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._chrono.Start();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pauses the clock.
|
||||
/// </summary>
|
||||
public void Pause() {
|
||||
using(this._locker?.AcquireWriterLock()) {
|
||||
this._chrono.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the clock position to 0 and stops it.
|
||||
/// The speed ratio is not modified.
|
||||
/// </summary>
|
||||
public void Reset() {
|
||||
using(this._locker?.AcquireWriterLock()) {
|
||||
this._offsetTicks = 0;
|
||||
this._chrono.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose() {
|
||||
if(this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isDisposed = true;
|
||||
this._locker?.Dispose();
|
||||
this._locker = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user