using System; namespace Mirror { /// SyncObjects sync state between server and client. E.g. SyncLists. // SyncObject should be a class (instead of an interface) for a few reasons: // * NetworkBehaviour stores SyncObjects in a list. structs would be a copy // and OnSerialize would use the copy instead of the original struct. // * Obsolete functions like Flush() don't need to be defined by each type // * OnDirty/IsRecording etc. default functions can be defined once here // for example, handling 'OnDirty wasn't initialized' with a default // function that throws an exception will be useful for SyncVar public abstract class SyncObject { /// Used internally to set owner NetworkBehaviour's dirty mask bit when changed. public Action OnDirty; /// Used internally to check if we are currently tracking changes. // prevents ever growing .changes lists: // if a monster has no observers but we keep modifing a SyncObject, // then the changes would never be flushed and keep growing, // because OnSerialize isn't called without observers. // => Func so we can set it to () => observers.Count > 0 // without depending on NetworkComponent/NetworkIdentity here. // => virtual so it sipmly always records by default public Func IsRecording = () => true; /// Discard all the queued changes // Consider the object fully synchronized with clients public abstract void ClearChanges(); // Deprecated 2021-09-17 [Obsolete("Deprecated: Use ClearChanges instead.")] public void Flush() => ClearChanges(); /// Write a full copy of the object public abstract void OnSerializeAll(NetworkWriter writer); /// Write the changes made to the object since last sync public abstract void OnSerializeDelta(NetworkWriter writer); /// Reads a full copy of the object public abstract void OnDeserializeAll(NetworkReader reader); /// Reads the changes made to the object since last sync public abstract void OnDeserializeDelta(NetworkReader reader); /// Resets the SyncObject so that it can be re-used public abstract void Reset(); } }