fix #1073 sync components with different intervals and add test (#1077)

This commit is contained in:
vis2k 2019-09-12 14:56:59 +02:00 committed by Paul Pacheco
parent 245dcfd1d9
commit dcafadfdba
2 changed files with 50 additions and 2 deletions

View File

@ -1230,8 +1230,14 @@ internal void MirrorUpdate()
NetworkServer.SendToReady(this, varsMessage, false); NetworkServer.SendToReady(this, varsMessage, false);
} }
// only clear bits if we sent something // clear dirty bits only for the components that we serialized
ClearAllComponentsDirtyBits(); // 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();
} }
NetworkWriterPool.Recycle(ownerWriter); NetworkWriterPool.Recycle(ownerWriter);
NetworkWriterPool.Recycle(observersWriter); NetworkWriterPool.Recycle(observersWriter);
@ -1251,5 +1257,18 @@ internal void ClearAllComponentsDirtyBits()
comp.ClearAllDirtyBits(); comp.ClearAllDirtyBits();
} }
} }
// clear only dirty component's dirty bits. ignores components which
// may be dirty but not ready to be synced yet (because of syncInterval)
internal void ClearDirtyComponentsDirtyBits()
{
foreach (NetworkBehaviour comp in NetworkBehaviours)
{
if (comp.IsDirty())
{
comp.ClearAllDirtyBits();
}
}
}
} }
} }

View File

@ -51,6 +51,35 @@ public void TestSettingStruct()
Assert.That(player.IsDirty(), "Clearing struct should mark object as dirty"); Assert.That(player.IsDirty(), "Clearing struct should mark object as dirty");
} }
[Test]
public void TestSyncIntervalAndClearDirtyComponents()
{
GameObject gameObject = new GameObject();
MockPlayer player = gameObject.AddComponent<MockPlayer>();
player.lastSyncTime = Time.time;
// synchronize immediately
player.syncInterval = 1f;
player.guild = new MockPlayer.Guild
{
name = "Back street boys"
};
Assert.That(player.IsDirty(), Is.False, "Sync interval not met, so not dirty yet");
// ClearDirtyComponents should do nothing since syncInterval is not
// elapsed yet
player.netIdentity.ClearDirtyComponentsDirtyBits();
// set lastSyncTime far enough back to be ready for syncing
player.lastSyncTime = Time.time - player.syncInterval;
// should be dirty now
Assert.That(player.IsDirty(), Is.True, "Sync interval met, should be dirty");
}
[Test] [Test]
public void TestSyncIntervalAndClearAllComponents() public void TestSyncIntervalAndClearAllComponents()
{ {