Skip to content

Commit

Permalink
feat!: changing SyncMode to just have SendToAll and SendToObservers
Browse files Browse the repository at this point in the history
removing benchmark code for simple enum, and just keeping best to modes

BREAKING CHANGE: SyncMode now only has two modes. SendToDirtyObservers_PackOnce mode renamed to SendToObservers and index changed from 4 to 2, Validate should auto convert from 4 to 2
  • Loading branch information
James-Frowen committed Apr 1, 2024
1 parent 5d6ef05 commit b9eedeb
Showing 1 changed file with 7 additions and 190 deletions.
197 changes: 7 additions & 190 deletions Assets/NetworkPositionSync/Runtime/SyncPositionSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,45 +33,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

namespace JamesFrowen.PositionSync
{
public static class Benchmark
{
private static long[] frames;
private static int index;
private static bool isRecording;
private static long start;

public static event Action<long[]> RecordingFinished;

public static bool IsRecording => isRecording;

public static void StartRecording(int frameCount)
{
frames = new long[frameCount];
isRecording = true;
index = 0;
}

public static void StartFrame()
{
if (!isRecording) return;

start = Stopwatch.GetTimestamp();
}
public static void EndFrame()
{
if (!isRecording) return;

var end = Stopwatch.GetTimestamp();
frames[index] = end - start;
index++;
if (index >= frames.Length)
{
RecordingFinished?.Invoke(frames);
isRecording = false;
}
}
}

public class SyncPositionBehaviourCollection
{
private static readonly ILogger logger = LogFactory.GetLogger<SyncPositionBehaviourCollection>();
Expand Down Expand Up @@ -125,10 +86,7 @@ private NetworkBehaviour.Id GetId(SyncPositionBehaviour thing)
public enum SyncMode
{
SendToAll = 1,
SendToObservers_PlayerDirty = 2,
SendToObservers_PlayerDirty_PackOnce = 5,
SendToObservers_DirtyObservers = 3,
SendToDirtyObservers_PackOnce = 4,
SendToObservers = 2,
}

[AddComponentMenu("Network/SyncPosition/SyncPositionSystem")]
Expand Down Expand Up @@ -201,6 +159,9 @@ private void OnValidate()
packer = new SyncPacker(PackSettings ?? new SyncSettings());
if (_timeSync != null)
_timeSync.ClientDelay = TickDelayCount / SyncRate;

if ((int)syncMode == 4) // auto convert old number to new enum
syncMode = SyncMode.SendToObservers;
}
private void OnDestroy()
{
Expand Down Expand Up @@ -274,27 +235,16 @@ private void ServerUpdate(double time)
{
if (!ServerActive) return;

Benchmark.StartFrame();
// syncs every frame, each Behaviour will track its own timer
switch (syncMode)
{
case SyncMode.SendToAll:
SendUpdateToAll(time);
break;
case SyncMode.SendToObservers_PlayerDirty:
SendUpdateToObservers_PlayerDirty(time);
break;
case SyncMode.SendToObservers_PlayerDirty_PackOnce:
SendUpdateToObservers_PlayerDirty_PackOnce(time);
break;
case SyncMode.SendToObservers_DirtyObservers:
SendUpdateToObservers_DirtyObservers(time);
break;
case SyncMode.SendToDirtyObservers_PackOnce:
SendUpdateToObservers_DirtyObservers_PackOnce(time);
case SyncMode.SendToObservers:
SendUpdateToObservers(time);
break;
}
Benchmark.EndFrame();

// host mode
// todo do we need this?
Expand Down Expand Up @@ -339,145 +289,12 @@ internal void SendUpdateToAll(double time)
}
}

/// <summary>
/// Loops through all players, followed by all dirty objects and checks if the player object can see each one
/// </summary>
/// <param name="time"></param>
internal void SendUpdateToObservers_PlayerDirty(double time)
{
// dont send message if no behaviours
if (Behaviours.Dictionary.Count == 0)
return;

UpdateDirtySet();

using (var writer = NetworkWriterPool.GetWriter())
{
foreach (var player in Server.Players)
{
writer.Reset();

packer.PackTime(writer, time);
foreach (var behaviour in dirtySet)
{
if (!behaviour.Identity.observers.Contains(player))
continue;

packer.PackNext(writer, behaviour);
}

var msg = new NetworkPositionMessage
{
payload = writer.ToArraySegment()
};
player.Send(msg, MessageChannel);
}
}

ClearDirtySet();
}

/// <summary>
/// Loops through all players, followed by all dirty objects and checks if the player object can see each one
/// ...except this one packs data once.
/// </summary>
/// <param name="time"></param>
internal void SendUpdateToObservers_PlayerDirty_PackOnce(double time)
{
// dont send message if no behaviours
if (Behaviours.Dictionary.Count == 0)
return;

UpdateDirtySet();
NetworkWriterPool.Configure(100, 200);

using (var writer = NetworkWriterPool.GetWriter())
{
foreach (var player in Server.Players)
{
writer.Reset();

packer.PackTime(writer, time);
foreach (var behaviour in dirtySet)
{
if (!behaviour.Identity.observers.Contains(player))
continue;

var packed = GetWriterFromPool_Behaviours(behaviour);
writer.CopyFromWriter(packed);
}

var msg = new NetworkPositionMessage
{
payload = writer.ToArraySegment()
};
player.Send(msg, MessageChannel);
}
}

foreach (var writer in writerPool_Behaviours.Values)
writer.Release();

writerPool_Behaviours.Clear();

ClearDirtySet();
}

private Dictionary<SyncPositionBehaviour, PooledNetworkWriter> writerPool_Behaviours = new Dictionary<SyncPositionBehaviour, PooledNetworkWriter>();

private PooledNetworkWriter GetWriterFromPool_Behaviours(SyncPositionBehaviour behaviour)
{
if (!writerPool_Behaviours.TryGetValue(behaviour, out var writer))
{
writer = NetworkWriterPool.GetWriter();
writerPool_Behaviours[behaviour] = writer;
packer.PackNext(writer, behaviour);
}

return writer;
}

/// <summary>
/// Loops through all dirty objects, and then their observers and then writes that behaviouir to a cahced writer
/// </summary>
/// <param name="time"></param>
internal void SendUpdateToObservers_DirtyObservers(double time)
{
// dont send message if no behaviours
if (Behaviours.Dictionary.Count == 0)
return;

UpdateDirtySet();

foreach (var behaviour in dirtySet)
{
foreach (var observer in behaviour.Identity.observers)
{
var writer = GetWriterFromPool(time, observer);

packer.PackNext(writer, behaviour);
}
}

foreach (var player in Server.Players)
{
var writer = GetWriterFromPool(time, player);

var msg = new NetworkPositionMessage { payload = writer.ToArraySegment() };
player.Send(msg, MessageChannel);
writer.Release();
}
writerPool.Clear();

ClearDirtySet();
}

/// <summary>
/// Loops through all dirty objects, and then their observers and then writes that behaviouir to a cahced writer
/// <para>But Packs once and copies bytes</para>
/// </summary>
/// <param name="time"></param>
internal void SendUpdateToObservers_DirtyObservers_PackOnce(double time)
internal void SendUpdateToObservers(double time)
{
// dont send message if no behaviours
if (Behaviours.Dictionary.Count == 0)
Expand Down

0 comments on commit b9eedeb

Please sign in to comment.