feat: new virtual OnStopServer called when object is unspawned (#1743)

This commit is contained in:
Paul Pacheco 2020-04-20 03:36:03 -05:00 committed by GitHub
parent 86ac5ad40b
commit d1695dd16f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 0 deletions

View File

@ -840,6 +840,12 @@ public virtual void OnStopClient()
/// </summary>
public virtual void OnStartServer() { }
/// <summary>
/// Invoked on the server when the object is unspawned
/// <para>Useful for saving object data in persistant storage</para>
/// </summary>
public virtual void OnStopServer() { }
/// <summary>
/// Called on every NetworkBehaviour when it is activated on a client.
/// <para>Objects on the host have this function called, as there is a local client on the host. The values of SyncVars on object are guaranteed to be initialized correctly with the latest state from the server when this function is called on the client.</para>

View File

@ -598,6 +598,26 @@ internal void OnStartServer()
}
}
internal void OnStopServer()
{
foreach (NetworkBehaviour comp in NetworkBehaviours)
{
// an exception in OnStartServer should be caught, so that one
// component's exception doesn't stop all other components from
// being initialized
// => this is what Unity does for Start() etc. too.
// one exception doesn't stop all the other Start() calls!
try
{
comp.OnStopServer();
}
catch (Exception e)
{
Debug.LogError("Exception in OnStopServer:" + e.Message + " " + e.StackTrace);
}
}
}
bool clientStarted;
internal void OnStartClient()
{

View File

@ -1094,6 +1094,8 @@ static void DestroyObject(NetworkIdentity identity, bool destroyServerObject)
identity.OnStopClient();
}
identity.OnStopServer();
// when unspawning, dont destroy the server's object
if (destroyServerObject)
{

View File

@ -105,6 +105,22 @@ class NetworkDestroyCalledNetworkBehaviour : NetworkBehaviour
public override void OnStopClient() { ++called; }
}
class StopServerCalledNetworkBehaviour : NetworkBehaviour
{
public int called;
public override void OnStopServer() { ++called; }
}
class StopServerExceptionNetworkBehaviour : NetworkBehaviour
{
public int called;
public override void OnStopServer()
{
++called;
throw new Exception("some exception");
}
}
class SetHostVisibilityExceptionNetworkBehaviour : NetworkVisibility
{
public int called;
@ -1038,6 +1054,38 @@ public void OnNetworkDestroy()
Assert.That(comp.called, Is.EqualTo(1));
}
[Test]
public void OnStopServer()
{
// add components
StopServerCalledNetworkBehaviour comp = gameObject.AddComponent<StopServerCalledNetworkBehaviour>();
// make sure our test values are set to 0
Assert.That(comp.called, Is.EqualTo(0));
identity.OnStopServer();
Assert.That(comp.called, Is.EqualTo(1));
}
[Test]
public void OnStopServerEx()
{
// add components
StopServerExceptionNetworkBehaviour compEx = gameObject.AddComponent<StopServerExceptionNetworkBehaviour>();
// make sure our test values are set to 0
Assert.That(compEx.called, Is.EqualTo(0));
// call OnNetworkDestroy in identity
// one component will throw an exception, but that shouldn't stop
// OnNetworkDestroy from being called in the second one
// exception will log an error
LogAssert.ignoreFailingMessages = true;
identity.OnStopServer();
LogAssert.ignoreFailingMessages = false;
Assert.That(compEx.called, Is.EqualTo(1));
}
[Test]
public void AddObserver()
{