Skip to content

Commit 634a140

Browse files
feat: RPC Network Update Order and Network Update Loop Registration (#442)
* MTT-174 Added first pass implementation of RPC invocation update stage assignment. RPCs can now be assigned a specific update stage for the RPC to be invoked. * feat: Starting to get new network update loop registration into place. * feat: MTT-327 The rest of the changes for the RPC Queue Revisited jira task MTT-327. * feat: MTT-367 MTT-327 MTT-367 Finalizing some adjustment to conform to the naming standards. Predominantly updating member property names and formating related changes. * refactor: Develop Merge Adjustments Making adjustments from the merge of develop * refactor: The RPCQueueRevisited kind of threw this branch into chaos. These are some of the fixes for the merge issue. * fix: Batching Lost some of the batching changes, also wanted to keep the original RPC Send methods. This just fixes some of the stutter associated with batching. * feat: network game update loop modular registration MTT-254 Added a more modular way to register with the network loop update system. This includes four possible paths: Add the INetworkUpdateLoopSystem to your class declaration and provide the appropriate methods. =or= Derive your class from: GenericUpdateLoopSystem for a slim non-monobehavior derived class. UpdateLoopBehaviour for a MonoBehaviour derived class. NetworkUpdateLoopBehaviour for a NetworkedBehaviour derived class. NetworkingManager now only is updated during the PREUPDATE and UPDATE stages. RpcQueueContainer now automatically registers for all update stages but also provides the ability for one to handle RPC queue processing externally (i.e.. at different stages). * fix: updated legacy name from rpcQueueMananger to rpcQueueContainer The updated names and formating for Unity standards will be coming in the RPCQueueRevisited PR * fix: removed line between properties * refactor: Updated for BitReader BitWriter bool This just applies the fix for bool reading and writing PR #438 * refactor: Fixes and Standards Removed the code that extracted the host client id from the connected client list as the bug that invoked that change was finally found and not related to this temporary fix. Did some standards clean up. * refactor: develop branch merge Had to refactor some of the code based on current state of develop branch. * fix: Using different writers per SendStream, to fix issue with more than 2 clients * refactor: Better divide by 8 option Making change, as suggested by Jeffrey, to steer clear of any floating point operations when calculating 64 bit block count. * refactor: Review comment related changes. The majority of these changes are syntax/standard oriented, but there are a few good catches like removing C# 8.0 standard "using", try an catches left in, and some const definitions for some of the RPC queue related boundary checking. * refactor: removing USINGUTP Removing the ifdef. * refactor: moved rpc queue files Moving the RPC queue related files to the Messaging directory since they are within the same namespace (and it is the proper location for them). Co-authored-by: Jeffrey Rainy <jeffrey.rainy@unity3d.com>
1 parent 528813a commit 634a140

25 files changed

Lines changed: 900 additions & 422 deletions

com.unity.multiplayer.mlapi/Runtime/Core/MessageBatcher.cs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using MLAPI.Serialization;
33
using MLAPI.Configuration;
44
using MLAPI.Profiling;
5+
using MLAPI.Messaging;
56
using System.Collections.Generic;
67
using System.Linq;
78
using System;
@@ -15,12 +16,17 @@ public class SendStream
1516
{
1617
public string channel;
1718
public PooledBitStream Stream = PooledBitStream.Get();
19+
public PooledBitWriter Writer;
1820
public bool Empty = true;
21+
22+
public SendStream()
23+
{
24+
Writer = PooledBitWriter.Get(Stream);
25+
}
1926
}
2027

2128
// Stores the stream of batched RPC to send to each client, by ClientId
2229
private Dictionary<ulong, SendStream> SendDict = new Dictionary<ulong, SendStream>();
23-
private PooledBitWriter Writer = new PooledBitWriter(PooledBitStream.Get());
2430

2531
// Used to store targets, internally
2632
private ulong[] TargetList = new ulong[0];
@@ -115,37 +121,35 @@ public void QueueItem(in FrameQueueItem item)
115121
{
116122
SendDict[clientId].Empty = false;
117123
SendDict[clientId].channel = item.channel;
118-
Writer.SetStream(SendDict[clientId].Stream);
119124

120-
Writer.WriteBit(false); // Encrypted
121-
Writer.WriteBit(false); // Authenticated
125+
SendDict[clientId].Writer.WriteBit(false); // Encrypted
126+
SendDict[clientId].Writer.WriteBit(false); // Authenticated
122127

123128
switch (item.queueItemType)
124129
{
125130
// 6 bits are used for the message type, which is an MLAPIConstants
126131
case RpcQueueContainer.QueueItemType.ServerRpc:
127-
Writer.WriteBits(MLAPIConstants.MLAPI_SERVER_RPC, 6); // MessageType
132+
SendDict[clientId].Writer.WriteBits(MLAPIConstants.MLAPI_SERVER_RPC, 6); // MessageType
128133
break;
129134
case RpcQueueContainer.QueueItemType.ClientRpc:
130-
Writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType
135+
SendDict[clientId].Writer.WriteBits(MLAPIConstants.MLAPI_CLIENT_RPC, 6); // MessageType
131136
break;
132137
}
133138
}
134139

135140
// write the amounts of bytes that are coming up
136-
PushLength(item.messageData.Count, ref Writer);
141+
PushLength(item.messageData.Count, ref SendDict[clientId].Writer);
137142

138143
// write the message to send
139-
// todo: is there a faster alternative to .ToArray()
140-
Writer.WriteBytes(item.messageData.ToArray(), item.messageData.Count);
144+
SendDict[clientId].Writer.WriteBytes(item.messageData.Array, item.messageData.Count, item.messageData.Offset);
141145

142146
ProfilerStatManager.bytesSent.Record((int)item.messageData.Count);
143147
ProfilerStatManager.rpcsSent.Record();
144148
}
145149
}
146150

147151
public delegate void SendCallbackType(ulong clientId, SendStream messageStream);
148-
public delegate void ReceiveCallbackType(BitStream messageStream, MLAPI.RpcQueueContainer.QueueItemType messageType, ulong clientId, float time);
152+
public delegate void ReceiveCallbackType(BitStream messageStream, RpcQueueContainer.QueueItemType messageType, ulong clientId, float time);
149153

150154
/// <summary>
151155
/// SendItems
@@ -165,17 +169,17 @@ public void SendItems(int threshold, SendCallbackType sendCallback)
165169
if (length >= threshold)
166170
{
167171
sendCallback(entry.Key, entry.Value);
168-
ProfilerStatManager.rpcBatchesSent.Record();
169-
170172
// clear the batch that was sent from the SendDict
171173
entry.Value.Stream.SetLength(0);
172174
entry.Value.Stream.Position = 0;
173175
entry.Value.Empty = true;
176+
ProfilerStatManager.rpcBatchesSent.Record();
174177
}
175178
}
176179
}
177180
}
178181

182+
179183
/// <summary>
180184
/// ReceiveItems
181185
/// Process the messageStream and call the callback with individual RPC messages
@@ -185,16 +189,17 @@ public void SendItems(int threshold, SendCallbackType sendCallback)
185189
/// <param name="messageType"> the message type to pass back to callback</param>
186190
/// <param name="clientId"> the clientId to pass back to callback</param>
187191
/// <param name="receiveTime"> the packet receive time to pass back to callback</param>
188-
public int ReceiveItems(in BitStream messageStream, ReceiveCallbackType receiveCallback, MLAPI.RpcQueueContainer.QueueItemType messageType, ulong clientId, float receiveTime)
192+
public int ReceiveItems(in BitStream messageStream, ReceiveCallbackType receiveCallback, RpcQueueContainer.QueueItemType messageType, ulong clientId, float receiveTime)
189193
{
190-
using PooledBitStream copy = PooledBitStream.Get();
194+
PooledBitStream copy = PooledBitStream.Get();
191195
do
192196
{
193197
// read the length of the next RPC
194198
int rpcSize = PopLength(messageStream);
195199

196200
if (rpcSize < 0)
197201
{
202+
copy.Dispose();
198203
// abort if there's an error reading lengths
199204
return 0;
200205
}
@@ -211,6 +216,7 @@ public int ReceiveItems(in BitStream messageStream, ReceiveCallbackType receiveC
211216
// RPCReceiveQueueItem peeks at content, it doesn't advance
212217
messageStream.Seek(rpcSize, SeekOrigin.Current);
213218
} while (messageStream.Position < messageStream.Length);
219+
copy.Dispose();
214220
return 0;
215221
}
216222
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
using System;
2+
using UnityEngine;
3+
4+
5+
namespace MLAPI
6+
{
7+
/// <summary>
8+
/// NetworkUpdateLoopBehaviour
9+
/// Derive from this class if you need to register a NetworkedBehaviour based class
10+
/// </summary>
11+
public class NetworkUpdateLoopBehaviour:NetworkedBehaviour, INetworkUpdateLoopSystem
12+
{
13+
protected virtual Action InternalRegisterNetworkUpdateStage(NetworkUpdateManager.NetworkUpdateStages stage )
14+
{
15+
return null;
16+
}
17+
18+
public Action RegisterUpdate(NetworkUpdateManager.NetworkUpdateStages stage )
19+
{
20+
return InternalRegisterNetworkUpdateStage(stage);
21+
}
22+
23+
protected void RegisterUpdateLoopSystem()
24+
{
25+
NetworkUpdateManager.NetworkLoopRegistration(this);
26+
}
27+
28+
protected void OnNetworkLoopSystemRemove()
29+
{
30+
if(onNetworkLoopSystemDestroyed != null)
31+
{
32+
onNetworkLoopSystemDestroyed.Invoke(this);
33+
}
34+
}
35+
36+
private Action<INetworkUpdateLoopSystem> onNetworkLoopSystemDestroyed;
37+
38+
public void RegisterUpdateLoopSystemDestroyCallback(Action<INetworkUpdateLoopSystem> networkLoopSystemDestroyedCallback)
39+
{
40+
onNetworkLoopSystemDestroyed = networkLoopSystemDestroyedCallback;
41+
}
42+
}
43+
44+
/// <summary>
45+
/// UpdateLoopBehaviour
46+
/// Derive from this class if you only require MonoBehaviour functionality
47+
/// </summary>
48+
public class UpdateLoopBehaviour:MonoBehaviour, INetworkUpdateLoopSystem
49+
{
50+
protected virtual Action InternalRegisterNetworkUpdateStage(NetworkUpdateManager.NetworkUpdateStages stage )
51+
{
52+
return null;
53+
}
54+
55+
public Action RegisterUpdate(NetworkUpdateManager.NetworkUpdateStages stage )
56+
{
57+
return InternalRegisterNetworkUpdateStage(stage);
58+
}
59+
60+
protected void RegisterUpdateLoopSystem()
61+
{
62+
NetworkUpdateManager.NetworkLoopRegistration(this);
63+
}
64+
65+
protected void OnNetworkLoopSystemRemove()
66+
{
67+
if(onNetworkLoopSystemDestroyed != null)
68+
{
69+
onNetworkLoopSystemDestroyed.Invoke(this);
70+
}
71+
}
72+
73+
private Action<INetworkUpdateLoopSystem> onNetworkLoopSystemDestroyed;
74+
75+
public void RegisterUpdateLoopSystemDestroyCallback(Action<INetworkUpdateLoopSystem> networkLoopSystemDestroyedCallback)
76+
{
77+
onNetworkLoopSystemDestroyed = networkLoopSystemDestroyedCallback;
78+
}
79+
}
80+
81+
/// <summary>
82+
/// GenericUpdateLoopSystem
83+
/// Derive from this class for generic (non-MonoBehaviour) classes
84+
/// </summary>
85+
public class GenericUpdateLoopSystem:INetworkUpdateLoopSystem
86+
{
87+
protected virtual Action InternalRegisterNetworkUpdateStage(NetworkUpdateManager.NetworkUpdateStages stage )
88+
{
89+
return null;
90+
}
91+
92+
public Action RegisterUpdate(NetworkUpdateManager.NetworkUpdateStages stage )
93+
{
94+
return InternalRegisterNetworkUpdateStage(stage);
95+
}
96+
97+
protected void RegisterUpdateLoopSystem()
98+
{
99+
NetworkUpdateManager.NetworkLoopRegistration(this);
100+
}
101+
102+
protected void OnNetworkLoopSystemRemove()
103+
{
104+
if(onNetworkLoopSystemDestroyed != null)
105+
{
106+
onNetworkLoopSystemDestroyed.Invoke(this);
107+
}
108+
}
109+
110+
private Action<INetworkUpdateLoopSystem> onNetworkLoopSystemDestroyed;
111+
112+
public void RegisterUpdateLoopSystemDestroyCallback(Action<INetworkUpdateLoopSystem> networkLoopSystemDestroyedCallback)
113+
{
114+
onNetworkLoopSystemDestroyed = networkLoopSystemDestroyedCallback;
115+
}
116+
}
117+
118+
119+
/// <summary>
120+
/// INetworkUpdateLoopSystem
121+
/// Use this interface if you need a custom class beyond the scope of GenericUpdateLoopSystem, UpdateLoopBehaviour, and NetworkUpdateLoopBehaviour
122+
/// </summary>
123+
public interface INetworkUpdateLoopSystem
124+
{
125+
Action RegisterUpdate(NetworkUpdateManager.NetworkUpdateStages stage );
126+
127+
void RegisterUpdateLoopSystemDestroyCallback(Action<INetworkUpdateLoopSystem> networkLoopSystemDestroyedCallbsack);
128+
}
129+
}

com.unity.multiplayer.mlapi/Runtime/Core/NetworkUpdateLoopSystem.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)