diff --git a/Assets/Mirage/Runtime/INetworkPlayer.cs b/Assets/Mirage/Runtime/INetworkPlayer.cs index d57c77f3404..7c73fd93da4 100644 --- a/Assets/Mirage/Runtime/INetworkPlayer.cs +++ b/Assets/Mirage/Runtime/INetworkPlayer.cs @@ -40,6 +40,7 @@ public interface IVisibilityTracker { void AddToVisList(NetworkIdentity identity); void RemoveFromVisList(NetworkIdentity identity); + bool IsVisible(NetworkIdentity identity); void RemoveAllVisibleObjects(); } diff --git a/Assets/Mirage/Runtime/INetworkServer.cs b/Assets/Mirage/Runtime/INetworkServer.cs index 2c94c815064..b86e24733af 100644 --- a/Assets/Mirage/Runtime/INetworkServer.cs +++ b/Assets/Mirage/Runtime/INetworkServer.cs @@ -61,7 +61,7 @@ public interface INetworkServer NetworkWorld World { get; } - SyncVarSender SyncVarSender { get; } + SyncVarSenderBase SyncVarSender { get; } IReadOnlyCollection Players { get; } diff --git a/Assets/Mirage/Runtime/NetworkBehaviour.cs b/Assets/Mirage/Runtime/NetworkBehaviour.cs index 6609a61fcb2..d7e26f0b249 100644 --- a/Assets/Mirage/Runtime/NetworkBehaviour.cs +++ b/Assets/Mirage/Runtime/NetworkBehaviour.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Cysharp.Threading.Tasks; using Mirage.Collections; using Mirage.Logging; @@ -384,7 +385,7 @@ public void SetDirtyBit(ulong dirtyBit) /// This clears all the dirty bits that were set on this script by SetDirtyBits(); /// This is automatically invoked when an update is sent for this object, but can be called manually as well. /// - public void ClearAllDirtyBits() + public void MarkAsSynced() { lastSyncTime = Time.time; SyncVarDirtyBits = 0L; @@ -414,19 +415,25 @@ bool AnySyncObjectDirty() return false; } - public bool IsDirty() + /// if it is time to sync and Any Var is dirty + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool NeedsSync() { - if (Time.time - lastSyncTime >= syncInterval) - { - return SyncVarDirtyBits != 0L || AnySyncObjectDirty(); - } - return false; + return TimeToSync() && AnyVarDirty(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool TimeToSync() + { + return Time.time - lastSyncTime >= syncInterval; } - // true if this component has data that has not been - // synchronized. Note that it may not synchronize - // right away because of syncInterval - public bool StillDirty() + /// + /// If any syncvar or syncObject is dirty + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool AnyVarDirty() { return SyncVarDirtyBits != 0L || AnySyncObjectDirty(); } diff --git a/Assets/Mirage/Runtime/NetworkIdentity.cs b/Assets/Mirage/Runtime/NetworkIdentity.cs index ec86a470714..9a48346ce74 100644 --- a/Assets/Mirage/Runtime/NetworkIdentity.cs +++ b/Assets/Mirage/Runtime/NetworkIdentity.cs @@ -219,9 +219,6 @@ public NetworkBehaviour[] NetworkBehaviours NetworkBehaviour[] components = GetComponentsInChildren(true); - if (components.Length > byte.MaxValue) - throw new InvalidOperationException("Only 255 NetworkBehaviour per gameobject allowed"); - networkBehavioursCache = components; return networkBehavioursCache; } @@ -782,13 +779,16 @@ internal void StopClient() /// /// /// - void OnSerialize(NetworkBehaviour comp, NetworkWriter writer, bool initialState) + void SerializeBehaviour(NetworkBehaviour comp, NetworkWriter writer, bool initialState) { comp.OnSerialize(writer, initialState); if (logger.LogEnabled()) logger.Log("OnSerializeSafely written for object=" + comp.name + " component=" + comp.GetType() + " sceneId=" + sceneId); // serialize a barrier to be checked by the deserializer writer.WriteByte(Barrier); + + // we can't mark as synced inside OnSerialize because it is virutal and user could override it + comp.MarkAsSynced(); } /// @@ -799,47 +799,47 @@ void OnSerialize(NetworkBehaviour comp, NetworkWriter writer, bool initialState) /// /// /// - internal (int ownerWritten, int observersWritten) OnSerializeAll(bool initialState, NetworkWriter ownerWriter, NetworkWriter observersWriter) + internal (int ownerWritten, int observersWritten) SerializeAllBehaviours(bool initialState, NetworkWriter ownerWriter, NetworkWriter observersWriter) { int ownerWritten = 0; int observersWritten = 0; - // check if components are in byte.MaxRange just to be 100% sure - // that we avoid overflows NetworkBehaviour[] components = NetworkBehaviours; // serialize all components - for (int i = 0; i < components.Length; ++i) + for (int i = 0; i < components.Length; i++) { // is this component dirty? // -> always serialize if initialState so all components are included in spawn packet // -> note: IsDirty() is false if the component isn't dirty or sendInterval isn't elapsed yet NetworkBehaviour comp = components[i]; - if (initialState || comp.IsDirty()) + + // remember start position in case we need to copy it into observers writer too + int startBitPosition = ownerWriter.BitPosition; + + // only calculate isDirty if not intital + bool isDirtyOrInitial = initialState || comp.NeedsSync(); + + // only write isDirty when not initial state + // if initial is false, then isDirtyOrInitial will be isDirty + if (!initialState) { - if (logger.LogEnabled()) logger.Log("OnSerializeAllSafely: " + name + " -> " + comp.GetType() + " initial=" + initialState); + ownerWriter.WriteBoolean(isDirtyOrInitial); + } - // remember start position in case we need to copy it into - // observers writer too - int startBitPosition = ownerWriter.BitPosition; + // then write values if dirty + if (isDirtyOrInitial) + { + if (logger.LogEnabled()) logger.Log($"OnSerializeAllSafely: {name} -> {comp.GetType()} initial={initialState}"); + + // todo dont serialize Owner State if SyncMode==Owner and no owner - // write index as byte [0..255] - ownerWriter.WriteByte((byte)i); + // serialize into ownerWriter first (owner always gets everything!) + SerializeBehaviour(comp, ownerWriter, initialState); - // serialize into ownerWriter first - // (owner always gets everything!) - OnSerialize(comp, ownerWriter, initialState); ownerWritten++; - // copy into observersWriter too if SyncMode.Observers - // -> we copy instead of calling OnSerialize again because - // we don't know what magic the user does in OnSerialize. - // -> it's not guaranteed that calling it twice gets the - // same result - // -> it's not guaranteed that calling it twice doesn't mess - // with the user's OnSerialize timing code etc. - // => so we just copy the result without touching - // OnSerialize again + // just copy from 1 buffer to another, faster than serializing again if (comp.syncMode == SyncMode.Observers) { int bitLength = ownerWriter.BitPosition - startBitPosition; @@ -852,13 +852,15 @@ void OnSerialize(NetworkBehaviour comp, NetworkWriter writer, bool initialState) return (ownerWritten, observersWritten); } - // Determines if there are changes in any component that have not - // been synchronized yet. Probably due to not meeting the syncInterval - internal bool StillDirty() + /// + /// Checks if any behaviour is dirty + /// + /// + internal bool AnyBehaviourDirty() { foreach (NetworkBehaviour behaviour in NetworkBehaviours) { - if (behaviour.StillDirty()) + if (behaviour.AnyVarDirty()) return true; } return false; @@ -885,20 +887,16 @@ internal void OnDeserializeAll(NetworkReader reader, bool initialState) reader.ObjectLocator = Client != null ? Client.World : null; // deserialize all components that were received NetworkBehaviour[] components = NetworkBehaviours; - // check if we can read atleast 1 byte - while (reader.CanReadBytes(1)) + + // serialize all components + for (int i = 0; i < components.Length; i++) { - // todo replace index with bool for if next component in order has changed or not - // the index below was an alternative to a mask, but now we have bitpacking we can just use a bool for each NB index - // read & check index [0..255] - byte index = reader.ReadByte(); - if (index < components.Length) + // initail or ReadIsDirty + if (initialState || reader.ReadBoolean()) { - // deserialize this component - OnDeserialize(components[index], reader, initialState); + OnDeserialize(components[i], reader, initialState); } } - } /// @@ -1209,7 +1207,7 @@ private void ResetEvents() _onStopServer.Reset(); } - internal void UpdateVars() + internal void UpdateVars_Legacy() { if (observers.Count > 0) { @@ -1229,7 +1227,7 @@ void SendUpdateVarsMessage() using (PooledNetworkWriter ownerWriter = NetworkWriterPool.GetWriter(), observersWriter = NetworkWriterPool.GetWriter()) { // serialize all the dirty components and send - (int ownerWritten, int observersWritten) = OnSerializeAll(false, ownerWriter, observersWriter); + (int ownerWritten, int observersWritten) = SerializeAllBehaviours(false, ownerWriter, observersWriter); if (ownerWritten > 0 || observersWritten > 0) { var varsMessage = new UpdateVarsMessage @@ -1256,15 +1254,6 @@ void SendUpdateVarsMessage() varsMessage.payload = observersWriter.ToArraySegment(); SendToRemoteObservers(varsMessage, false); } - - // clear dirty bits only for the components that we serialized - // DO NOT clean ALL component's dirty bits, because - // components can have different syncIntervals and we don't - // want to reset dirty bits for the ones that were not - // synced yet. - // (we serialized only the IsDirty() components, or all of - // them if initialState. clearing the dirty ones is enough.) - ClearDirtyComponentsDirtyBits(); } } } @@ -1308,7 +1297,7 @@ internal void ClearAllComponentsDirtyBits() { foreach (NetworkBehaviour comp in NetworkBehaviours) { - comp.ClearAllDirtyBits(); + comp.MarkAsSynced(); } } @@ -1316,13 +1305,14 @@ internal void ClearAllComponentsDirtyBits() /// Clear only dirty component's dirty bits. ignores components which /// may be dirty but not ready to be synced yet (because of syncInterval) /// + [System.Obsolete("We do this inside Seralize", true)] internal void ClearDirtyComponentsDirtyBits() { foreach (NetworkBehaviour comp in NetworkBehaviours) { - if (comp.IsDirty()) + if (comp.NeedsSync()) { - comp.ClearAllDirtyBits(); + comp.MarkAsSynced(); } } } @@ -1334,5 +1324,62 @@ void ResetSyncObjects() comp.ResetSyncObjects(); } } + + struct UpdateCache + { + public bool hasCache; + public PooledNetworkWriter ownerWriter; + public PooledNetworkWriter observersWriter; + } + UpdateCache updateCache; + + internal NetworkWriter GetCachedUpdate(INetworkPlayer player) + { + if (!updateCache.hasCache) + { + CreateUpdateCache(); + } + + if (Owner == player) + return updateCache.ownerWriter; + else + return updateCache.observersWriter; + + } + + private void CreateUpdateCache() + { + updateCache.hasCache = true; + + updateCache.observersWriter = NetworkWriterPool.GetWriter(); + updateCache.ownerWriter = NetworkWriterPool.GetWriter(); + + // serialize all the dirty components and send + (int ownerWritten, int observersWritten) = SerializeAllBehaviours(false, updateCache.ownerWriter, updateCache.observersWriter); + + if (ownerWritten == 0) + { + updateCache.ownerWriter.Release(); + updateCache.ownerWriter = null; + } + + if (observersWritten == 0) + { + updateCache.observersWriter.Release(); + updateCache.observersWriter = null; + } + } + + internal void ClearCachedUpdate() + { + updateCache.observersWriter?.Release(); + updateCache.ownerWriter?.Release(); + + updateCache.observersWriter = null; + updateCache.ownerWriter = null; + updateCache.hasCache = false; + + ClearAllComponentsDirtyBits(); + } } } diff --git a/Assets/Mirage/Runtime/NetworkPlayer.cs b/Assets/Mirage/Runtime/NetworkPlayer.cs index d5a0b7beb63..f8df80f8a43 100644 --- a/Assets/Mirage/Runtime/NetworkPlayer.cs +++ b/Assets/Mirage/Runtime/NetworkPlayer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Mirage.Logging; using Mirage.Serialization; using Mirage.SocketLayer; @@ -175,6 +176,12 @@ public void RemoveFromVisList(NetworkIdentity identity) visList.Remove(identity); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsVisible(NetworkIdentity identity) + { + return visList.Contains(identity); + } + /// /// Removes all objects that this player can see /// This is called when loading a new scene diff --git a/Assets/Mirage/Runtime/NetworkServer.cs b/Assets/Mirage/Runtime/NetworkServer.cs index f8a3b21b51d..dd9f48cb42b 100644 --- a/Assets/Mirage/Runtime/NetworkServer.cs +++ b/Assets/Mirage/Runtime/NetworkServer.cs @@ -45,6 +45,8 @@ public class NetworkServer : MonoBehaviour, INetworkServer [Tooltip("If disabled the server will not create a Network Peer to listen. This can be used to run server single player mode")] public bool Listening = true; + public SyncVarSendMode syncVarSendMode; + [Tooltip("Creates Socket for Peer to use")] public SocketFactory SocketFactory; @@ -136,7 +138,7 @@ public class NetworkServer : MonoBehaviour, INetworkServer public bool Active { get; private set; } public NetworkWorld World { get; private set; } - public SyncVarSender SyncVarSender { get; private set; } + public SyncVarSenderBase SyncVarSender { get; private set; } public MessageHandler MessageHandler { get; private set; } @@ -187,20 +189,10 @@ public void StartServer(NetworkClient localClient = null) logger.Assert(Players.Count == 0, "Player should have been reset since previous session"); logger.Assert(connections.Count == 0, "Connections should have been reset since previous session"); - World = new NetworkWorld(); - SyncVarSender = new SyncVarSender(); - - LocalClient = localClient; - MessageHandler = new MessageHandler(World, DisconnectOnException); - MessageHandler.RegisterHandler(World.Time.OnServerPing); - - ISocket socket = SocketFactory.CreateServerSocket(); - var dataHandler = new DataHandler(MessageHandler, connections); - Metrics = EnablePeerMetrics ? new Metrics(MetricsSize) : null; - Config config = PeerConfig; if (config == null) { + // note: dont write to PeerConfig property here. if we do we will not use MaxConnections if server starts a second time config = new Config { // only use MaxConnections if config was null @@ -208,6 +200,19 @@ public void StartServer(NetworkClient localClient = null) }; } + World = new NetworkWorld(); + + // max packet - 17 (reliable ack header) + SyncVarSender = SyncVarSenderBase.Create(syncVarSendMode, this, config.MaxPacketSize - 17); + + LocalClient = localClient; + MessageHandler = new MessageHandler(World, DisconnectOnException); + MessageHandler.RegisterHandler(World.Time.OnServerPing); + + ISocket socket = SocketFactory.CreateServerSocket(); + var dataHandler = new DataHandler(MessageHandler, connections); + Metrics = EnablePeerMetrics ? new Metrics(MetricsSize) : null; + NetworkWriterPool.Configure(config.MaxPacketSize); // Only create peer if listening diff --git a/Assets/Mirage/Runtime/ServerObjectManager.cs b/Assets/Mirage/Runtime/ServerObjectManager.cs index 6595d019d99..46d12187a33 100644 --- a/Assets/Mirage/Runtime/ServerObjectManager.cs +++ b/Assets/Mirage/Runtime/ServerObjectManager.cs @@ -523,7 +523,7 @@ static ArraySegment CreateSpawnMessagePayload(bool isOwner, NetworkIdentit // serialize all components with initialState = true // (can be null if has none) - identity.OnSerializeAll(true, ownerWriter, observersWriter); + identity.SerializeAllBehaviours(true, ownerWriter, observersWriter); // use owner segment if 'conn' owns this identity, otherwise // use observers segment diff --git a/Assets/Mirage/Runtime/SyncVarReceiver.cs b/Assets/Mirage/Runtime/SyncVarReceiver.cs index f5f877dff73..cc5f3c2cabb 100644 --- a/Assets/Mirage/Runtime/SyncVarReceiver.cs +++ b/Assets/Mirage/Runtime/SyncVarReceiver.cs @@ -32,10 +32,12 @@ private void AddHandlers(NetworkClient client) if (client.IsLocalClient) { client.MessageHandler.RegisterHandler(_ => { }); + client.MessageHandler.RegisterHandler(_ => { }); } else { client.MessageHandler.RegisterHandler(OnUpdateVarsMessage); + client.MessageHandler.RegisterHandler(OnGroupedSyncVars); } } @@ -43,14 +45,30 @@ void OnUpdateVarsMessage(UpdateVarsMessage msg) { if (logger.LogEnabled()) logger.Log("ClientScene.OnUpdateVarsMessage " + msg.netId); - if (objectLocator.TryGetIdentity(msg.netId, out NetworkIdentity localObject)) + if (objectLocator.TryGetIdentity(msg.netId, out NetworkIdentity identity)) { - using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload)) - localObject.OnDeserializeAll(networkReader, false); + using (PooledNetworkReader reader = NetworkReaderPool.GetReader(msg.payload)) + identity.OnDeserializeAll(reader, false); } else { - if (logger.WarnEnabled()) logger.LogWarning("Did not find target for sync message for " + msg.netId + " . Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message."); + if (logger.WarnEnabled()) logger.LogWarning($"Did not find target for sync message for {msg.netId}. Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message."); + } + } + + void OnGroupedSyncVars(GroupedSyncVars msg) + { + using (PooledNetworkReader reader = NetworkReaderPool.GetReader(msg.payload)) + { + uint netId = reader.ReadPackedUInt32(); + if (objectLocator.TryGetIdentity(netId, out NetworkIdentity identity)) + { + identity.OnDeserializeAll(reader, false); + } + else + { + if (logger.WarnEnabled()) logger.LogWarning($"Did not find target for sync message for {netId}. Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message."); + } } } } diff --git a/Assets/Mirage/Runtime/SyncVarSender.cs b/Assets/Mirage/Runtime/SyncVarSender.cs index f888510b76c..179a216cbf5 100644 --- a/Assets/Mirage/Runtime/SyncVarSender.cs +++ b/Assets/Mirage/Runtime/SyncVarSender.cs @@ -1,40 +1,188 @@ +using System; using System.Collections.Generic; +using System.ComponentModel; +using Mirage.Serialization; namespace Mirage { + public enum SyncVarSendMode + { + /// + /// SyncVar system that has been in Mirror and Mirage for a long time. Should work in call cases but might not be most efficient + /// + Legacy = 1, + /// + /// Groups Objects changes together before sending, reducing overall bandwidth because message headers are sent + /// + Grouped = 2, + // DeltaSnapshot_Experimental = 3, + // EventualConsistency_Experimental = 4, + } + /// /// Class that Syncs syncvar and other State /// - public class SyncVarSender + public abstract class SyncVarSenderBase { - private readonly HashSet DirtyObjects = new HashSet(); - private readonly List DirtyObjectsTmp = new List(); + protected readonly HashSet DirtyObjects = new HashSet(); + protected readonly List DirtyObjectsTmp = new List(); public void AddDirtyObject(NetworkIdentity dirty) { DirtyObjects.Add(dirty); } + internal abstract void Update(); - internal void Update() + internal static SyncVarSenderBase Create(SyncVarSendMode mode, NetworkServer server, int maxMessageBytes) { - DirtyObjectsTmp.Clear(); + switch (mode) + { + case SyncVarSendMode.Legacy: + return new SyncVarSender_Legacy(); + case SyncVarSendMode.Grouped: + return new SyncVarSender_Grouped(server, maxMessageBytes); + default: + throw new InvalidEnumArgumentException(); + } + } - foreach (NetworkIdentity identity in DirtyObjects) + public sealed class SyncVarSender_Legacy : SyncVarSenderBase + { + internal override void Update() { - if (identity != null) + DirtyObjectsTmp.Clear(); + + foreach (NetworkIdentity identity in DirtyObjects) + { + if (identity != null) + { + identity.UpdateVars_Legacy(); + + if (identity.AnyBehaviourDirty()) + DirtyObjectsTmp.Add(identity); + } + } + + DirtyObjects.Clear(); + + foreach (NetworkIdentity obj in DirtyObjectsTmp) + DirtyObjects.Add(obj); + } + } + + public sealed class SyncVarSender_Grouped : SyncVarSenderBase + { + private readonly NetworkServer server; + private readonly int maxMessageBitLength; + /// + /// net id is var int, so could be 5 bytes long + /// + const int MAX_NET_ID_SIZE = 5 * 8; + + /// + /// 2 bytes for message hash, 2 bytes for segment length + /// note: segment legnth uses var-int, so might only be sent as 1 byte + /// + const int MESSAGE_HEADER_SIZE = 4; + + public SyncVarSender_Grouped(NetworkServer server, int maxMessageBytes) + { + this.server = server; + // + maxMessageBitLength = (maxMessageBytes - MESSAGE_HEADER_SIZE) * 8; + } + + internal override void Update() + { + DirtyObjectsTmp.Clear(); + // copy to temp to make sure there are no null objects + foreach (NetworkIdentity identity in DirtyObjects) + { + if (identity != null) + { + DirtyObjectsTmp.Add(identity); + } + } + + + using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) + { + foreach (INetworkPlayer player in server.Players) + { + // skip if scene not ready + if (!player.SceneIsReady) continue; + + SendToPlayer(player, writer); + } + } + + DirtyObjects.Clear(); + foreach (NetworkIdentity identity in DirtyObjectsTmp) { - identity.UpdateVars(); + identity.ClearCachedUpdate(); - if (identity.StillDirty()) + if (identity.AnyBehaviourDirty()) DirtyObjectsTmp.Add(identity); } } - DirtyObjects.Clear(); + private void SendToPlayer(INetworkPlayer player, PooledNetworkWriter writer) + { + foreach (NetworkIdentity identity in DirtyObjectsTmp) + { + // skip if not visibile + if (!player.IsVisible(identity)) + continue; + + NetworkWriter cachedWriter = identity.GetCachedUpdate(player); + + // there might be nothing to write, in this case we can skip + if (cachedWriter == null) + continue; + + ThrowIfOverMaxSize(identity, cachedWriter); - foreach (NetworkIdentity obj in DirtyObjectsTmp) - DirtyObjects.Add(obj); + if (TooBig(writer, cachedWriter)) + { + SendGroupSyncVarMessage(player, writer); + } + + writer.WritePackedUInt32(identity.NetId); + writer.CopyFromWriter(cachedWriter, 0, cachedWriter.BitPosition); + } + + + if (writer.BitPosition > 0) + { + SendGroupSyncVarMessage(player, writer); + } + } + + private void ThrowIfOverMaxSize(NetworkIdentity identity, NetworkWriter cachedWriter) + { + if (cachedWriter.BitPosition + MAX_NET_ID_SIZE > maxMessageBitLength) + { + throw new InvalidOperationException($"Message size for '{identity.name}' was over max ({maxMessageBitLength / 8} bytes). Size was {cachedWriter.BitPosition / 8} bytes"); + } + } + + private bool TooBig(PooledNetworkWriter writer, NetworkWriter cachedWriter) + { + return writer.BitPosition + cachedWriter.BitPosition > maxMessageBitLength; + } + + private void SendGroupSyncVarMessage(INetworkPlayer player, PooledNetworkWriter writer) + { + player.Send(new GroupedSyncVars { payload = writer.ToArraySegment() }); + writer.Reset(); + } } + + } + [NetworkMessage] + public struct GroupedSyncVars + { + public ArraySegment payload; } } diff --git a/Assets/Tests/Editor/NetworkIdentityCallbackTests.cs b/Assets/Tests/Editor/NetworkIdentityCallbackTests.cs index 17220503353..4836d88d4a7 100644 --- a/Assets/Tests/Editor/NetworkIdentityCallbackTests.cs +++ b/Assets/Tests/Editor/NetworkIdentityCallbackTests.cs @@ -508,7 +508,7 @@ public void OnSerializeAllSafely() // serialize should propagate exceptions Assert.Throws(() => { - identity.OnSerializeAll(true, ownerWriter, observersWriter); + identity.SerializeAllBehaviours(true, ownerWriter, observersWriter); }); } @@ -549,7 +549,7 @@ public void OnDeserializeSafelyShouldDetectAndHandleDeSerializationMismatch() // serialize var ownerWriter = new NetworkWriter(1300); var observersWriter = new NetworkWriter(1300); - identity.OnSerializeAll(true, ownerWriter, observersWriter); + identity.SerializeAllBehaviours(true, ownerWriter, observersWriter); // reset component values comp1.value = 0; diff --git a/Assets/Tests/Performance/Runtime/NetworkWriter/NetworkIdentityPerformance.cs b/Assets/Tests/Performance/Runtime/NetworkWriter/NetworkIdentityPerformance.cs index 4a91127d6d9..c19b4c85523 100644 --- a/Assets/Tests/Performance/Runtime/NetworkWriter/NetworkIdentityPerformance.cs +++ b/Assets/Tests/Performance/Runtime/NetworkWriter/NetworkIdentityPerformance.cs @@ -55,7 +55,7 @@ void RunServerUpdateIsDirty() for (int j = 0; j < 1000; j++) { health.SetDirtyBit(1UL); - identity.UpdateVars(); + identity.UpdateVars_Legacy(); } } @@ -73,7 +73,7 @@ void RunServerUpdateNotDirty() { for (int j = 0; j < 1000; j++) { - identity.UpdateVars(); + identity.UpdateVars_Legacy(); } } } diff --git a/Assets/Tests/Performance/Runtime/NetworkWriter/NetworkIdentityPerformanceWithMultipleBehaviour.cs b/Assets/Tests/Performance/Runtime/NetworkWriter/NetworkIdentityPerformanceWithMultipleBehaviour.cs index 3e2d524b82b..69e00bb503d 100644 --- a/Assets/Tests/Performance/Runtime/NetworkWriter/NetworkIdentityPerformanceWithMultipleBehaviour.cs +++ b/Assets/Tests/Performance/Runtime/NetworkWriter/NetworkIdentityPerformanceWithMultipleBehaviour.cs @@ -54,7 +54,7 @@ void RunServerUpdateIsDirty() { health[i].SetDirtyBit(1UL); } - identity.UpdateVars(); + identity.UpdateVars_Legacy(); } } @@ -72,7 +72,7 @@ void RunServerUpdateNotDirty() { for (int j = 0; j < 1000; j++) { - identity.UpdateVars(); + identity.UpdateVars_Legacy(); } } } diff --git a/Assets/Tests/Runtime/ClientServer/SyncVarInitialOnlyTest.cs b/Assets/Tests/Runtime/ClientServer/SyncVarInitialOnlyTest.cs index 33ac27d781a..4f6e921650b 100644 --- a/Assets/Tests/Runtime/ClientServer/SyncVarInitialOnlyTest.cs +++ b/Assets/Tests/Runtime/ClientServer/SyncVarInitialOnlyTest.cs @@ -24,13 +24,13 @@ public class SyncVarInitialOnlyTest : ClientServerSetup public void ChangingInitOnlyVarWontSetBehaviourDirty() { serverComponent.weaponIndex = 10; - Assert.That(serverComponent.IsDirty(), Is.False); + Assert.That(serverComponent.NeedsSync(), Is.False); serverComponent.otherValue = 5.2f; - Assert.That(serverComponent.IsDirty(), Is.False); + Assert.That(serverComponent.NeedsSync(), Is.False); serverComponent.health = 20; - Assert.That(serverComponent.IsDirty(), Is.True); + Assert.That(serverComponent.NeedsSync(), Is.True); } [UnityTest] diff --git a/Assets/Tests/Runtime/SyncVarTest.cs b/Assets/Tests/Runtime/SyncVarTest.cs index 4c4f0c8260c..42d01a3b372 100644 --- a/Assets/Tests/Runtime/SyncVarTest.cs +++ b/Assets/Tests/Runtime/SyncVarTest.cs @@ -44,7 +44,7 @@ public void TestSettingStruct() // synchronize immediatelly player.syncInterval = 0f; - Assert.That(player.IsDirty(), Is.False, "First time object should not be dirty"); + Assert.That(player.NeedsSync(), Is.False, "First time object should not be dirty"); var myGuild = new MockPlayer.Guild { @@ -53,13 +53,13 @@ public void TestSettingStruct() player.guild = myGuild; - Assert.That(player.IsDirty(), "Setting struct should mark object as dirty"); - player.ClearAllDirtyBits(); - Assert.That(player.IsDirty(), Is.False, "ClearAllDirtyBits() should clear dirty flag"); + Assert.That(player.NeedsSync(), "Setting struct should mark object as dirty"); + player.MarkAsSynced(); + Assert.That(player.NeedsSync(), Is.False, "ClearAllDirtyBits() should clear dirty flag"); // clearing the guild should set dirty bit too player.guild = default; - Assert.That(player.IsDirty(), "Clearing struct should mark object as dirty"); + Assert.That(player.NeedsSync(), "Clearing struct should mark object as dirty"); } [Test] @@ -78,7 +78,7 @@ public void TestSyncIntervalAndClearDirtyComponents() name = "Back street boys" }; - Assert.That(player.IsDirty(), Is.False, "Sync interval not met, so not dirty yet"); + Assert.That(player.NeedsSync(), Is.False, "Sync interval not met, so not dirty yet"); // ClearDirtyComponents should do nothing since syncInterval is not // elapsed yet @@ -88,7 +88,7 @@ public void TestSyncIntervalAndClearDirtyComponents() player.lastSyncTime = Time.time - player.syncInterval; // should be dirty now - Assert.That(player.IsDirty(), Is.True, "Sync interval met, should be dirty"); + Assert.That(player.NeedsSync(), Is.True, "Sync interval met, should be dirty"); } [Test] @@ -106,7 +106,7 @@ public void TestSyncIntervalAndClearAllComponents() name = "Back street boys" }; - Assert.That(player.IsDirty(), Is.False, "Sync interval not met, so not dirty yet"); + Assert.That(player.NeedsSync(), Is.False, "Sync interval not met, so not dirty yet"); // ClearAllComponents should clear dirty even if syncInterval not // elapsed yet @@ -116,7 +116,7 @@ public void TestSyncIntervalAndClearAllComponents() player.lastSyncTime = Time.time - player.syncInterval; // should be dirty now - Assert.That(player.IsDirty(), Is.False, "Sync interval met, should still not be dirty"); + Assert.That(player.NeedsSync(), Is.False, "Sync interval met, should still not be dirty"); } [Test] @@ -133,7 +133,7 @@ public void TestSynchronizingObjects() player1.guild = myGuild; // serialize all the data as we would for the network - identity1.OnSerializeAll(true, ownerWriter, observersWriter); + identity1.SerializeAllBehaviours(true, ownerWriter, observersWriter); // set up a "client" object var gameObject2 = new GameObject(); diff --git a/Assets/Tests/Runtime/SyncVarVirtualTest.cs b/Assets/Tests/Runtime/SyncVarVirtualTest.cs index 4bf752544bb..75694ab92dc 100644 --- a/Assets/Tests/Runtime/SyncVarVirtualTest.cs +++ b/Assets/Tests/Runtime/SyncVarVirtualTest.cs @@ -81,7 +81,7 @@ private void SyncValuesWithClient() ownerWriter.Reset(); observersWriter.Reset(); - netIdServer.OnSerializeAll(true, ownerWriter, observersWriter); + netIdServer.SerializeAllBehaviours(true, ownerWriter, observersWriter); // apply all the data from the server object