#if UNITY_2020_3_OR_NEWER && UNITY_EDITOR_WIN
using FishNet.CodeAnalysis.Annotations;
#endif
using FishNet.Connection;
using FishNet.Documenting;
using FishNet.Object.Synchronizing.Internal;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace FishNet.Object
{
public abstract partial class NetworkBehaviour : MonoBehaviour
{
#region Public.
///
/// True if OnStartServer has been called.
///
[APIExclude]
public bool OnStartServerCalled { get; private set; }
///
/// True if OnStartClient has been called.
///
[APIExclude]
public bool OnStartClientCalled { get; private set; }
#endregion
#region Private.
///
/// True if OnStartNetwork has been called.
///
private bool _onStartNetworkCalled;
///
/// True if OnStopNetwork has been called.
///
private bool _onStopNetworkCalled;
#endregion
///
/// Invokes OnStartXXXX for synctypes, letting them know the NetworkBehaviour start cycle has been completed.
///
internal void InvokeSyncTypeOnStartCallbacks(bool asServer)
{
foreach (SyncBase item in _syncVars.Values)
item.OnStartCallback(asServer);
foreach (SyncBase item in _syncObjects.Values)
item.OnStartCallback(asServer);
}
///
/// Invokes OnStopXXXX for synctypes, letting them know the NetworkBehaviour stop cycle is about to start.
///
internal void InvokeSyncTypeOnStopCallbacks(bool asServer)
{
foreach (SyncBase item in _syncVars.Values)
item.OnStopCallback(asServer);
foreach (SyncBase item in _syncObjects.Values)
item.OnStopCallback(asServer);
}
///
/// Invokes the OnStart/StopNetwork.
///
///
internal void InvokeOnNetwork(bool start)
{
if (start)
{
if (_onStartNetworkCalled)
return;
OnStartNetwork_Internal();
}
else
{
if (_onStopNetworkCalled)
return;
OnStopNetwork_Internal();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnStartNetwork_Internal()
{
_onStartNetworkCalled = true;
_onStopNetworkCalled = false;
OnStartNetwork();
}
///
/// Called when the network has initialized this object. May be called for server or client but will only be called once.
/// When as host or server this method will run before OnStartServer.
/// When as client only the method will run before OnStartClient.
///
public virtual void OnStartNetwork() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnStopNetwork_Internal()
{
_onStopNetworkCalled = true;
_onStartNetworkCalled = false;
OnStopNetwork();
}
///
/// Called when the network is deinitializing this object. May be called for server or client but will only be called once.
/// When as host or server this method will run after OnStopServer.
/// When as client only this method will run after OnStopClient.
///
public virtual void OnStopNetwork() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnStartServer_Internal()
{
OnStartServerCalled = true;
OnStartServer();
}
///
/// Called on the server after initializing this object.
/// SyncTypes modified before or during this method will be sent to clients in the spawn message.
///
public virtual void OnStartServer() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnStopServer_Internal()
{
OnStartServerCalled = false;
ReturnRpcLinks();
OnStopServer();
}
///
/// Called on the server before deinitializing this object.
///
public virtual void OnStopServer() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnOwnershipServer_Internal(NetworkConnection prevOwner)
{
//When switching ownership always clear replicate cache on server.
ClearReplicateCache(true);
OnOwnershipServer(prevOwner);
}
///
/// Called on the server after ownership has changed.
///
/// Previous owner of this object.
public virtual void OnOwnershipServer(NetworkConnection prevOwner) { }
///
/// Called on the server after a spawn message for this object has been sent to clients.
/// Useful for sending remote calls or data to clients.
///
/// Connection the object is being spawned for.
public virtual void OnSpawnServer(NetworkConnection connection) { }
///
/// Called on the server before a despawn message for this object has been sent to connection.
/// Useful for sending remote calls or actions to clients.
///
public virtual void OnDespawnServer(NetworkConnection connection) { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnStartClient_Internal()
{
OnStartClientCalled = true;
OnStartClient();
}
///
/// Called on the client after initializing this object.
///
public virtual void OnStartClient() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnStopClient_Internal()
{
OnStartClientCalled = false;
OnStopClient();
}
///
/// Called on the client before deinitializing this object.
///
public virtual void OnStopClient() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnOwnershipClient_Internal(NetworkConnection prevOwner)
{
//If losing or gaining ownership then clear replicate cache.
if (IsOwner || prevOwner == LocalConnection)
{
ClearReplicateCache(false);
}
OnOwnershipClient(prevOwner);
}
///
/// Called on the client after gaining or losing ownership.
///
/// Previous owner of this object.
public virtual void OnOwnershipClient(NetworkConnection prevOwner) { }
}
}