use modular initing system rather than calling Init() method.
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
// -----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StgSharp.Timing
|
||||
@@ -53,24 +54,31 @@ namespace StgSharp.Timing
|
||||
|
||||
public virtual bool IsComplete
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _timeProvider.CurrentSecond > _ending;
|
||||
}
|
||||
|
||||
public Func<float, float> TimeRelatedCalculation
|
||||
{
|
||||
get { return _timeRelatedCalculation; }
|
||||
set { _timeRelatedCalculation = value; }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _timeRelatedCalculation;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
set => _timeRelatedCalculation = value;
|
||||
}
|
||||
|
||||
public static TimeFunction One
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => new TimeFunctionOne();
|
||||
}
|
||||
|
||||
public TimeSpanProvider TimeSpanProvider
|
||||
{
|
||||
get { return _timeProvider; }
|
||||
set { _timeProvider = value; }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _timeProvider;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
set => _timeProvider = value;
|
||||
}
|
||||
|
||||
public virtual float Calculate()
|
||||
@@ -96,7 +104,7 @@ namespace StgSharp.Timing
|
||||
return new TimeFunction(_timeProvider, func, range);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
public virtual void Reset()
|
||||
{
|
||||
float range = _ending - _beginning;
|
||||
_beginning = _timeProvider.CurrentSecond;
|
||||
@@ -117,10 +125,7 @@ namespace StgSharp.Timing
|
||||
|
||||
internal TimeFunctionOne() : base() { }
|
||||
|
||||
public override bool IsComplete
|
||||
{
|
||||
get => true;
|
||||
}
|
||||
public override bool IsComplete => true;
|
||||
|
||||
public override float Calculate()
|
||||
{
|
||||
@@ -138,9 +143,9 @@ namespace StgSharp.Timing
|
||||
}
|
||||
|
||||
#pragma warning disable CA1822
|
||||
public new void Reset()
|
||||
public override void Reset()
|
||||
{
|
||||
}
|
||||
#pragma warning restore CA1822
|
||||
{ }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
using StgSharp.Collections;
|
||||
using StgSharp.Timing;
|
||||
|
||||
using System;
|
||||
@@ -48,7 +49,7 @@ namespace StgSharp
|
||||
public sealed class StgSharpTime : TimeSourceProviderBase
|
||||
{
|
||||
|
||||
private static List<TimeSpanProvider> subscriberList = [];
|
||||
private static readonly LinearBag<TimeSpanProvider> _subscribers = new();
|
||||
private static long accuracy;
|
||||
private static readonly Stopwatch mainProvider = new();
|
||||
private static Thread timeProvideThread;
|
||||
@@ -65,21 +66,21 @@ namespace StgSharp
|
||||
mainProvider.Start();
|
||||
|
||||
// speed test
|
||||
long totalMS, internalFrequncy = Stopwatch.Frequency;
|
||||
long totalMS, internalFrequency = Stopwatch.Frequency;
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
totalMS = mainProvider.ElapsedTicks / (internalFrequncy / (1000L * 1000L));
|
||||
totalMS = mainProvider.ElapsedTicks / (internalFrequency / (1000L * 1000L));
|
||||
for (int t = 0; t < 10; t++)
|
||||
{
|
||||
if (totalMS < 1000) {
|
||||
subscriberList.Add(
|
||||
_subscribers.Add(
|
||||
new TimeSpanProvider(100L, TimeSpanProvider.DefaultProvider));
|
||||
}
|
||||
}
|
||||
}
|
||||
mainProvider.Stop();
|
||||
subscriberList.Clear();
|
||||
totalMS = mainProvider.ElapsedTicks / (internalFrequncy / (1000L * 1000L)) / 100L;
|
||||
_subscribers.Clear();
|
||||
totalMS = mainProvider.ElapsedTicks / (internalFrequency / (1000L * 1000L)) / 100L;
|
||||
accuracy = totalMS * 2 / 3;
|
||||
mainProvider.Reset();
|
||||
timeProvideThread = new Thread(new ThreadStart(ProvideTime));
|
||||
@@ -102,44 +103,36 @@ namespace StgSharp
|
||||
|
||||
protected sealed override void AddSubscriberUnsynced(TimeSpanProvider subscriber)
|
||||
{
|
||||
subscriberList.Add(subscriber);
|
||||
_subscribers.Add(subscriber);
|
||||
}
|
||||
|
||||
protected sealed override void RemoveSubscriberUnsynced(TimeSpanProvider subscriber)
|
||||
{
|
||||
_ = subscriberList.Remove(subscriber);
|
||||
_subscribers.Remove(subscriber);
|
||||
}
|
||||
|
||||
private void ProvideTime()
|
||||
{
|
||||
long totalMS, internalFrequncy = Stopwatch.Frequency;
|
||||
long totalMS, internalFrequency = Stopwatch.Frequency;
|
||||
lock (mainProvider) {
|
||||
mainProvider.Restart();
|
||||
}
|
||||
while (mainProvider.IsRunning)
|
||||
{
|
||||
totalMS = mainProvider.ElapsedTicks / (internalFrequncy / (1000L * 1000L));
|
||||
if (subscriberList.Count == 0)
|
||||
totalMS = mainProvider.ElapsedTicks / (internalFrequency / (1000L * 1000L));
|
||||
if (_subscribers.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
lock (SubscribeLock)
|
||||
{
|
||||
List<TimeSpanProvider> toRemoveList = [];
|
||||
foreach (TimeSpanProvider subscriber in subscriberList)
|
||||
for (int i = 0; i < _subscribers.Count; i++)
|
||||
{
|
||||
if (!subscriber.CheckTime(totalMS))
|
||||
if (!_subscribers[i].CheckTime(totalMS))
|
||||
{
|
||||
toRemoveList.Add(subscriber);
|
||||
_subscribers.RemoveAt(i);
|
||||
DefaultLog.InternalWriteLog(
|
||||
$"Time subscriber {subscriber} is to be removed.", LogType.Info);
|
||||
}
|
||||
;
|
||||
}
|
||||
if (toRemoveList.Count != 0)
|
||||
{
|
||||
foreach (TimeSpanProvider subscriber in toRemoveList) {
|
||||
_ = subscriberList.Remove(subscriber);
|
||||
$"Time subscriber {_subscribers[i]} is to be removed.", LogType.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,20 +36,18 @@ namespace StgSharp.Timing
|
||||
public abstract class TimeSourceProviderBase
|
||||
{
|
||||
|
||||
private readonly object _subscriberLock = new();
|
||||
|
||||
protected object SubscribeLock => _subscriberLock;
|
||||
protected object SubscribeLock { get; } = new();
|
||||
|
||||
public void AddSubscriber(TimeSpanProvider subscriber)
|
||||
{
|
||||
lock (_subscriberLock) {
|
||||
lock (SubscribeLock) {
|
||||
AddSubscriberUnsynced(subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveSubscriber(TimeSpanProvider subscriber)
|
||||
{
|
||||
lock (_subscriberLock) {
|
||||
lock (SubscribeLock) {
|
||||
RemoveSubscriberUnsynced(subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
@@ -43,11 +44,10 @@ namespace StgSharp.Timing
|
||||
|
||||
private bool _subscribed;
|
||||
|
||||
private ConcurrentQueue<TimeSpanAwaitingToken> _tokenToAdd = new ConcurrentQueue<TimeSpanAwaitingToken>(
|
||||
);
|
||||
private ConcurrentQueue<TimeSpanAwaitingToken> _tokenToQuit;
|
||||
private Counter<int> timeSpanCount = new Counter<int>(-1, 1, 1);
|
||||
private HashSet<TimeSpanAwaitingToken> _awaitingTokens;
|
||||
private readonly ConcurrentQueue<TimeSpanAwaitingToken> _tokenToAdd = new();
|
||||
private readonly ConcurrentQueue<TimeSpanAwaitingToken> _tokenToQuit;
|
||||
private Counter<int> timeSpanCount = new(-1, 1, 1);
|
||||
private readonly HashSet<TimeSpanAwaitingToken> _awaitingTokens;
|
||||
private long _maxSpanCount;
|
||||
private long _spanBegin;
|
||||
private readonly long _spanLength;
|
||||
@@ -71,7 +71,7 @@ namespace StgSharp.Timing
|
||||
_maxSpanCount = int.MaxValue;
|
||||
provider.AddSubscriber(this);
|
||||
_subscribed = true;
|
||||
_awaitingTokens = new HashSet<TimeSpanAwaitingToken>();
|
||||
_awaitingTokens = [];
|
||||
_tokenToQuit = new ConcurrentQueue<TimeSpanAwaitingToken>();
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace StgSharp.Timing
|
||||
_maxSpanCount = long.MaxValue;
|
||||
provider.AddSubscriber(this);
|
||||
_subscribed = true;
|
||||
_awaitingTokens = new HashSet<TimeSpanAwaitingToken>();
|
||||
_awaitingTokens = [];
|
||||
_tokenToQuit = new ConcurrentQueue<TimeSpanAwaitingToken>();
|
||||
}
|
||||
|
||||
@@ -128,21 +128,25 @@ namespace StgSharp.Timing
|
||||
|
||||
public double SpanLength
|
||||
{
|
||||
get => (_spanLength * 1.0) / (1000L * 1000L);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _spanLength * 1.0 / (1000L * 1000L);
|
||||
}
|
||||
|
||||
public float CurrentSecond
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => timeSpanCount.Value * SpanLengthLowPrecession;
|
||||
}
|
||||
|
||||
public float SpanLengthLowPrecession
|
||||
{
|
||||
get => (_spanLength * 1.0f) / (1000 * 1000);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _spanLength * 1.0f / (1000 * 1000);
|
||||
}
|
||||
|
||||
public int CurrentSpan
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => timeSpanCount.Value;
|
||||
}
|
||||
|
||||
@@ -153,7 +157,7 @@ namespace StgSharp.Timing
|
||||
|
||||
public TimeSpanAwaitingToken ParticipantSpanAwaiting(int count)
|
||||
{
|
||||
TimeSpanAwaitingToken token = new TimeSpanAwaitingToken(this, count);
|
||||
TimeSpanAwaitingToken token = new(this, count);
|
||||
_tokenToAdd.Enqueue(token);
|
||||
return token;
|
||||
}
|
||||
@@ -165,7 +169,7 @@ namespace StgSharp.Timing
|
||||
|
||||
public void StopSpanProviding()
|
||||
{
|
||||
Interlocked.Exchange(ref _maxSpanCount, 0);
|
||||
_ = Interlocked.Exchange(ref _maxSpanCount, 0);
|
||||
}
|
||||
|
||||
public void SubscribeToTimeSource(TimeSourceProviderBase serviceHandler)
|
||||
@@ -207,7 +211,7 @@ namespace StgSharp.Timing
|
||||
{
|
||||
if (item.AwaitingSemaphoreSlim.CurrentCount == 0)
|
||||
{
|
||||
item.AwaitingSemaphoreSlim.Release();
|
||||
_ = item.AwaitingSemaphoreSlim.Release();
|
||||
item.Refresh();
|
||||
} else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user