Skip to content

Commit f5a7a83

Browse files
committed
Reworked the internal event loop & Lag compensator
1 parent 80b167e commit f5a7a83

File tree

5 files changed

+89
-35
lines changed

5 files changed

+89
-35
lines changed

MLAPI/Data/FixedQueue.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
3+
namespace MLAPI.Data
4+
{
5+
public class FixedQueue<T>
6+
{
7+
protected readonly T[] queue;
8+
protected int queueCount = 0;
9+
protected int queueStart;
10+
11+
public int Count { get => queueCount; }
12+
13+
public FixedQueue(int maxSize)
14+
{
15+
queue = new T[maxSize];
16+
queueStart = 0;
17+
}
18+
19+
public bool Enqueue(T t)
20+
{
21+
queue[(queueStart + queueCount) % queue.Length] = t;
22+
if (++queueCount > queue.Length)
23+
{
24+
--queueCount;
25+
return true;
26+
}
27+
return false;
28+
}
29+
30+
public T Dequeue()
31+
{
32+
if (--queueCount == -1) throw new IndexOutOfRangeException("Cannot dequeue empty queue!");
33+
T res = queue[queueStart];
34+
queueStart = (queueStart + 1) % queue.Length;
35+
return res;
36+
}
37+
38+
public T ElementAt(int index) => queue[(queueStart + index) % queue.Length];
39+
}
40+
}

MLAPI/Data/NetworkConfig.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public class NetworkConfig
104104
/// <summary>
105105
/// The amount of seconds to keep a lag compensation position history
106106
/// </summary>
107-
public float SecondsHistory = 5;
107+
public int SecondsHistory = 5;
108108
/// <summary>
109109
/// Wheter or not to make the library handle object spawning
110110
/// </summary>

MLAPI/MLAPI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
<Compile Include="Data\Channel.cs" />
7575
<Compile Include="Data\FieldType.cs" />
7676
<Compile Include="Attributes\SyncedVar.cs" />
77+
<Compile Include="Data\FixedQueue.cs" />
7778
<Compile Include="Data\NetworkConfig.cs" />
7879
<Compile Include="Data\NetworkedPrefab.cs" />
7980
<Compile Include="Data\NetworkPool.cs" />

MLAPI/MonoBehaviours/Core/NetworkingManager.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,10 @@ private void OnValidate()
212212
private ConnectionConfig Init(bool server)
213213
{
214214
networkTime = 0f;
215-
lastSendTickTime = 0;
216-
lastEventTickTime = 0;
217-
lastReceiveTickTime = 0;
215+
lastSendTickTime = 0f;
216+
lastEventTickTime = 0f;
217+
lastReceiveTickTime = 0f;
218+
eventOvershootCounter = 0f;
218219
pendingClients = new HashSet<uint>();
219220
connectedClients = new Dictionary<uint, NetworkedClient>();
220221
messageBuffer = new byte[NetworkConfig.MessageBufferSize];
@@ -679,6 +680,7 @@ private void Shutdown()
679680
private float lastReceiveTickTime;
680681
private float lastSendTickTime;
681682
private float lastEventTickTime;
683+
private float eventOvershootCounter;
682684
private float lastTimeSyncTime;
683685
private void Update()
684686
{
@@ -781,12 +783,19 @@ private void Update()
781783
lastReceiveTickTime = NetworkTime;
782784
}
783785

784-
if (isServer && ((NetworkTime - lastEventTickTime >= (1f / NetworkConfig.EventTickrate)) || NetworkConfig.EventTickrate <= 0))
786+
if (isServer && ((NetworkTime - lastEventTickTime >= (1f / NetworkConfig.EventTickrate))))
785787
{
788+
eventOvershootCounter += ((NetworkTime - lastEventTickTime) - (1f / NetworkConfig.EventTickrate));
786789
LagCompensationManager.AddFrames();
787790
NetworkedObject.InvokeSyncvarUpdate();
788791
lastEventTickTime = NetworkTime;
789792
}
793+
else if (isServer && eventOvershootCounter >= ((1f / NetworkConfig.EventTickrate)))
794+
{
795+
//We run this one to compensate for previous update overshoots.
796+
eventOvershootCounter -= (1f / NetworkConfig.EventTickrate);
797+
LagCompensationManager.AddFrames();
798+
}
790799

791800
if (NetworkConfig.EnableTimeResync && NetworkTime - lastTimeSyncTime >= 30)
792801
{
Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using MLAPI.Data;
22
using MLAPI.NetworkingManagerComponents.Core;
3+
using System;
34
using System.Collections.Generic;
45
using UnityEngine;
56

@@ -15,7 +16,7 @@ namespace MLAPI.MonoBehaviours.Core
1516
public class TrackedObject : MonoBehaviour
1617
{
1718
internal Dictionary<float, TrackedPointData> FrameData = new Dictionary<float, TrackedPointData>();
18-
internal LinkedList<float> Framekeys = new LinkedList<float>();
19+
internal FixedQueue<float> Framekeys;
1920
private Vector3 savedPosition;
2021
private Quaternion savedRotation;
2122

@@ -37,38 +38,49 @@ public float AvgTimeBetweenPointsMs
3738
{
3839
get
3940
{
40-
if (Framekeys.First == null || Framekeys.Last == null)
41+
if (Framekeys.Count < 2)
4142
return 0;
42-
float totalSpan = Framekeys.Last.Value - Framekeys.First.Value;
43+
float totalSpan = Framekeys.ElementAt(Framekeys.Count - 1) - Framekeys.ElementAt(0);
4344
return (totalSpan / Framekeys.Count) * 1000f;
4445
}
4546
}
4647

48+
public float TotalTimeHistory
49+
{
50+
get
51+
{
52+
return Framekeys.ElementAt(Framekeys.Count - 1) - Framekeys.ElementAt(0);
53+
}
54+
}
55+
56+
private int maxPoints
57+
{
58+
get
59+
{
60+
return (int)(NetworkingManager.singleton.NetworkConfig.SecondsHistory / (1f / NetworkingManager.singleton.NetworkConfig.EventTickrate));
61+
}
62+
}
63+
4764
internal void ReverseTransform(float secondsAgo)
4865
{
4966
savedPosition = transform.position;
5067
savedRotation = transform.rotation;
68+
5169
float currentTime = NetworkingManager.singleton.NetworkTime;
5270
float targetTime = currentTime - secondsAgo;
53-
float previousTime = 0;
54-
float nextTime = 0;
55-
LinkedListNode<float> node = Framekeys.First;
56-
float previousValue = 0f;
57-
while(node != null)
71+
72+
float previousTime = 0f;
73+
float nextTime = 0f;
74+
for (int i = 0; i < Framekeys.Count; i++)
5875
{
59-
if(previousValue <= targetTime && node.Value >= targetTime)
76+
if (previousTime <= targetTime && Framekeys.ElementAt(i) >= targetTime)
6077
{
61-
previousTime = previousValue;
62-
nextTime = node.Value;
78+
nextTime = Framekeys.ElementAt(i);
6379
break;
6480
}
6581
else
66-
{
67-
previousValue = node.Value;
68-
node = node.Next;
69-
}
82+
previousTime = Framekeys.ElementAt(i);
7083
}
71-
7284
float timeBetweenFrames = nextTime - previousTime;
7385
float timeAwayFromPrevious = currentTime - previousTime;
7486
float lerpProgress = timeAwayFromPrevious / timeBetweenFrames;
@@ -84,35 +96,27 @@ internal void ResetStateTransform()
8496

8597
void Start()
8698
{
87-
Framekeys.AddFirst(0);
99+
Framekeys = new FixedQueue<float>(maxPoints);
100+
Framekeys.Enqueue(0);
88101
LagCompensationManager.simulationObjects.Add(this);
89102
}
90103

91104
void OnDestroy()
92105
{
93-
Framekeys.Clear();
94-
FrameData.Clear();
95106
LagCompensationManager.simulationObjects.Remove(this);
96107
}
97108

98109
internal void AddFrame()
99110
{
100-
float currentTime = NetworkingManager.singleton.NetworkTime;
101-
LinkedListNode<float> node = Framekeys.First;
102-
LinkedListNode<float> nextNode = node.Next;
103-
while (node != null && currentTime - node.Value >= NetworkingManager.singleton.NetworkConfig.SecondsHistory)
104-
{
105-
nextNode = node.Next;
106-
FrameData.Remove(node.Value);
107-
Framekeys.RemoveFirst();
108-
node = nextNode;
109-
}
111+
if (Framekeys.Count == maxPoints)
112+
FrameData.Remove(Framekeys.Dequeue());
113+
110114
FrameData.Add(NetworkingManager.singleton.NetworkTime, new TrackedPointData()
111115
{
112116
position = transform.position,
113117
rotation = transform.rotation
114118
});
115-
Framekeys.AddLast(NetworkingManager.singleton.NetworkTime);
119+
Framekeys.Enqueue(NetworkingManager.singleton.NetworkTime);
116120
}
117121
}
118122
}

0 commit comments

Comments
 (0)