Improved initial sync
This commit is contained in:
+812
-813
File diff suppressed because it is too large
Load Diff
+438
-383
File diff suppressed because it is too large
Load Diff
@@ -53,15 +53,19 @@ namespace Marro.PacManUdon
|
||||
/// <summary>
|
||||
/// The delay in ticks at which the receiving side replays events.
|
||||
/// </summary>
|
||||
[SerializeField] private int delay = 50;
|
||||
[SerializeField] private int delay = 1;
|
||||
/// <summary>
|
||||
/// The maximum amount of times a message is sent.
|
||||
/// </summary>
|
||||
[SerializeField] private int maxEventSendTries = 3;
|
||||
/// <summary>
|
||||
/// How long to wait since last message to send next ping.
|
||||
/// How long to wait since last message to send next message.
|
||||
/// </summary>
|
||||
[SerializeField] private int pingDelay = 15;
|
||||
[SerializeField] private int sendingPingDelay = 15;
|
||||
/// <summary>
|
||||
/// How long to wait since last attempt to request sync.
|
||||
/// </summary>
|
||||
[SerializeField] private int syncingPingDelay = 300;
|
||||
/// <summary>
|
||||
/// The time delta at which updates occur.
|
||||
/// </summary>
|
||||
@@ -200,7 +204,7 @@ namespace Marro.PacManUdon
|
||||
/// </summary>
|
||||
private int eventTransmissionHistoryIndex;
|
||||
/// <summary>
|
||||
/// Time of last event transmission, in ticks.
|
||||
/// Time of last event transmission sent, requested or received, in ticks.
|
||||
/// </summary>
|
||||
private int lastEventTransmissionTime;
|
||||
|
||||
@@ -210,7 +214,6 @@ namespace Marro.PacManUdon
|
||||
/// </summary>
|
||||
private byte lastEventId;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Data which is currently available on the network.
|
||||
/// </summary>
|
||||
@@ -295,7 +298,7 @@ namespace Marro.PacManUdon
|
||||
|
||||
#region General
|
||||
/// <summary>
|
||||
/// Initializes the <see cref="NetworkManager"/>. Call <see cref="Reset"/> afterwards to activate networking.
|
||||
/// Initializes the <see cref="NetworkManager"/>.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
@@ -361,7 +364,6 @@ namespace Marro.PacManUdon
|
||||
|
||||
Synced = IsOwner; // Owner is always synced
|
||||
retriesWithoutSuccess = 0;
|
||||
hasFullSyncReady = false;
|
||||
|
||||
targetTicks = 0;
|
||||
startTime = Time.fixedTime;
|
||||
@@ -371,11 +373,7 @@ namespace Marro.PacManUdon
|
||||
Ready = true;
|
||||
|
||||
// Sync up
|
||||
if (IsOwner)
|
||||
{
|
||||
SendEventSoon(NetworkEventType.FullSyncForced);
|
||||
}
|
||||
else
|
||||
if (!IsOwner)
|
||||
{
|
||||
RequestEvent(NetworkEventType.FullSync);
|
||||
}
|
||||
@@ -409,15 +407,19 @@ namespace Marro.PacManUdon
|
||||
{
|
||||
if (Ready)
|
||||
{
|
||||
if (IsOwner)
|
||||
if (isOwner)
|
||||
{
|
||||
ProcessEventsToSend(); // Prepare events from last cycle
|
||||
ProgressPingTime(); // See if we need to send a ping
|
||||
ProgressSendingPingTime(); // See if we need to send a ping
|
||||
}
|
||||
if (!isOwner)
|
||||
else if (Synced || hasFullSyncReady)
|
||||
{
|
||||
ApplyReceivedEvents(); // See if there's events after last update that need to be replayed
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressSyncingPingTime(); // See if we should request syncing
|
||||
}
|
||||
}
|
||||
|
||||
ProgressSyncedTime();
|
||||
@@ -532,6 +534,11 @@ namespace Marro.PacManUdon
|
||||
|
||||
eventsToSendLate[eventsToSendLateIndex++] = eventType;
|
||||
}
|
||||
|
||||
if (IsFullSync(eventType))
|
||||
{
|
||||
hasFullSyncReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessEventsToSend()
|
||||
@@ -591,11 +598,6 @@ namespace Marro.PacManUdon
|
||||
var eventSizeBytes = BitConverter.GetBytes((ushort)index);
|
||||
Array.Copy(eventSizeBytes, 0, data, HeaderEventSizeIndex, eventSizeBytes.Length);
|
||||
|
||||
if (IsFullSync(eventType))
|
||||
{
|
||||
hasFullSyncReady = true;
|
||||
}
|
||||
|
||||
data = GetArrayPart(data, 0, index);
|
||||
|
||||
QueueEventInBuffer(data);
|
||||
@@ -641,27 +643,35 @@ namespace Marro.PacManUdon
|
||||
|
||||
if (IsFullSync(eventType) && hasFullSyncReady)
|
||||
{
|
||||
//Debug.Log($"Rejected event request because already have full sync ready");
|
||||
return; // Don't send another full sync if we're already preparing to send one
|
||||
}
|
||||
|
||||
if (eventType == NetworkEventType.FullSyncForced)
|
||||
{
|
||||
SendEventSoon(NetworkEventType.FullSync); // Remote is not allowed to request a forced full sync
|
||||
return;
|
||||
eventType = NetworkEventType.FullSync; // Remote is not allowed to request a forced full sync
|
||||
}
|
||||
|
||||
SendEventSoon(eventType);
|
||||
}
|
||||
|
||||
private void ProgressPingTime()
|
||||
private void ProgressSendingPingTime()
|
||||
{
|
||||
if (eventsQueueIndex > 0 && !serializationRequested
|
||||
&& targetTicks - lastEventTransmissionTime >= pingDelay)
|
||||
&& targetTicks - lastEventTransmissionTime >= sendingPingDelay)
|
||||
{
|
||||
RequestSerializationForEvents();
|
||||
}
|
||||
}
|
||||
|
||||
private void ProgressSyncingPingTime()
|
||||
{
|
||||
if (targetTicks - lastEventTransmissionTime >= syncingPingDelay)
|
||||
{
|
||||
RequestEvent(NetworkEventType.FullSync);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPreSerialization()
|
||||
{
|
||||
if (!Ready || !IsOwner || !serializationRequested || eventsQueue == null || eventsQueueIndex == 0)
|
||||
@@ -688,6 +698,9 @@ namespace Marro.PacManUdon
|
||||
// Version of OnPostSerialization which does not require instantiating SerializationResult, so that it can be called for debugging purposes.
|
||||
public void OnPostSerializationInternal(bool success, int byteCount)
|
||||
{
|
||||
// If there was a full sync in the queue, it should now have been transmitted at least once
|
||||
hasFullSyncReady = false;
|
||||
|
||||
if (!Ready || !IsOwner || networkedData.Length == 0)
|
||||
{
|
||||
return;
|
||||
@@ -708,9 +721,6 @@ namespace Marro.PacManUdon
|
||||
|
||||
networkedData = new byte[0];
|
||||
|
||||
// If there was a full sync in the queue, it has now been transmitted at least once
|
||||
hasFullSyncReady = false;
|
||||
|
||||
lastEventTransmissionTime = targetTicks;
|
||||
}
|
||||
#endregion
|
||||
@@ -730,6 +740,7 @@ namespace Marro.PacManUdon
|
||||
}
|
||||
|
||||
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.Owner, "RequestEventReceived", eventType);
|
||||
lastEventTransmissionTime = SyncedTimeTicks;
|
||||
|
||||
if (tester != null)
|
||||
{
|
||||
@@ -798,25 +809,29 @@ namespace Marro.PacManUdon
|
||||
continue;
|
||||
}
|
||||
|
||||
QueueEventInBuffer(@event);
|
||||
if (!QueueEventInBuffer(@event))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventsQueueIndex == 1) // If this is the next upcoming event, update the next event time
|
||||
{
|
||||
UpdateNextEventTime();
|
||||
}
|
||||
|
||||
//Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)} Queued event with id {eventId}");
|
||||
}
|
||||
else if (IsFullSync(eventType)) // If we're not yet synced, we only care about full sync events.
|
||||
{
|
||||
QueueFullSyncForReplay(@event); // Immediately process full sync
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're not yet synced, we only care about full sync events.
|
||||
if (IsFullSync(eventType))
|
||||
{
|
||||
QueueFullSyncForReplay(@event); // Immediately process full sync
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
lastEventId = eventId;
|
||||
}
|
||||
|
||||
if (Synced)
|
||||
{
|
||||
UpdateNextEventTime();
|
||||
lastEventTransmissionTime = SyncedTimeTicks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1211,6 +1226,7 @@ namespace Marro.PacManUdon
|
||||
[SerializeField] private Animator DebugImageToIndicateReady;
|
||||
|
||||
private NetworkManagerTester tester;
|
||||
|
||||
public void SetNetworkManagerTester(NetworkManagerTester tester)
|
||||
{
|
||||
this.tester = tester;
|
||||
|
||||
@@ -12,6 +12,7 @@ public class NetworkManagerSyncTester : UdonSharpBehaviour
|
||||
[SerializeField] GridMover[] gridMovers1;
|
||||
[SerializeField] NetworkManager networkManager2;
|
||||
[SerializeField] GridMover[] gridMovers2;
|
||||
|
||||
[SerializeField] Animator debugImageToIndicateSynced;
|
||||
|
||||
private int[] captureTimes = new int[1000];
|
||||
|
||||
@@ -7,7 +7,7 @@ using UnityEngine;
|
||||
public class NetworkManagerTester : UdonSharpBehaviour
|
||||
{
|
||||
[SerializeField] private NetworkManager[] networkManagers;
|
||||
[SerializeField] private float interval = 0.1f;
|
||||
[SerializeField] private float interval = 0.01f;
|
||||
[SerializeField] private int ownerIndex = 0;
|
||||
|
||||
private float countdown = 0;
|
||||
@@ -62,7 +62,7 @@ public class NetworkManagerTester : UdonSharpBehaviour
|
||||
{
|
||||
networkManager.OnPreSerialization();
|
||||
var data = networkManager.NetworkedData;
|
||||
networkManager.OnPostSerializationInternal(true, data.Length) ;
|
||||
networkManager.OnPostSerializationInternal(true, data.Length);
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class NetworkManagerTester : UdonSharpBehaviour
|
||||
{
|
||||
foreach (var target in networkManagers)
|
||||
{
|
||||
if (!target.IsOwner || !target.SerializationRequested)
|
||||
if (!target.IsOwner)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user