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();
    }
}