public void Test_FieldValueFactory_With_Single_Value_Produces_Correct_FieldValueUpdate([EntityDataCollectionTestRange] int index, [Values(1, 2, 3, 4, 5, 6, 7, 8)] int value)
        {
            //arrange
            ChangeTrackingEntityFieldDataCollectionDecorator <TestFieldType> collection = new ChangeTrackingEntityFieldDataCollectionDecorator <TestFieldType>(new EntityFieldDataCollection <TestFieldType>());
            FieldValueUpdateFactory updateFactory = new FieldValueUpdateFactory();

            //act
            collection.SetFieldValue <int>(index, value);
            FieldValueUpdate fieldValueUpdate = updateFactory.Create(new EntityFieldUpdateCreationContext(collection, collection.ChangeTrackingArray));


            //assert
            Assert.AreEqual(1, fieldValueUpdate.FieldValueUpdateMask.EnumerateSetBitsByIndex().Count(), $"Found more than 1 set bit.");
            Assert.AreEqual(value, fieldValueUpdate.FieldValueUpdates.First(), $"Serialized value was not expected value.");
            Assert.AreEqual(index, fieldValueUpdate.FieldValueUpdateMask.EnumerateSetBitsByIndex().First(), $"Index: {index} was expected to be in the update but was not.");
        }
        public void Test_FieldValueFactory_With_Multiple_Value_Produces_Correct_FieldValueUpdate()
        {
            //arrange
            ChangeTrackingEntityFieldDataCollectionDecorator <TestFieldType> collection = new ChangeTrackingEntityFieldDataCollectionDecorator <TestFieldType>(new EntityFieldDataCollection <TestFieldType>());
            FieldValueUpdateFactory updateFactory = new FieldValueUpdateFactory();

            //act
            collection.SetFieldValue <int>(1, 5);
            collection.SetFieldValue <int>(2, 4);
            collection.SetFieldValue <int>(3, 7);
            FieldValueUpdate fieldValueUpdate = updateFactory.Create(new EntityFieldUpdateCreationContext(collection, collection.ChangeTrackingArray));


            //assert
            Assert.AreEqual(3, fieldValueUpdate.FieldValueUpdateMask.EnumerateSetBitsByIndex().Count(), $"Found more than 1 set bit.");
            Assert.AreEqual(5, fieldValueUpdate.FieldValueUpdates.First(), $"Serialized value was not expected value.");
            Assert.AreEqual(1, fieldValueUpdate.FieldValueUpdateMask.EnumerateSetBitsByIndex().First(), $"Index: {1} was expected to be first index.");
        }
        /// <inheritdoc />
        public void Tick()
        {
            using (LockingPolicy.ReaderLock(null, CancellationToken.None))
            {
                //For every player we need to do some processing so that we can entity data update values
                foreach (var guid in PlayerGuids)
                {
                    InterestCollection interest = GetEntityInterestCollection(guid);

                    //Even if we only know ourselves we should do this anyway
                    //so that the client can receieve entity data changes about itself

                    //TODO: We probably won't send an update about ALL entites, so this is some wasted allocations and time
                    List <EntityAssociatedData <FieldValueUpdate> > updates = new List <EntityAssociatedData <FieldValueUpdate> >(interest.ContainedEntities.Count);

                    foreach (var interestingEntityGuid in interest.ContainedEntities)
                    {
                        //Don't build an update for entities that don't have any changes
                        if (!ChangeTrackerHasChangesForEntity(interestingEntityGuid))
                        {
                            continue;
                        }

                        //TODO: We should cache this update value so we don't need to recompute it for ALL players who are interested
                        //This is the update collection for the particular Entity with guid interestingEntityGuid
                        //We want to use the CHANGE TRACKING bitarray for updates. If this was initial discovery we'd use the SIT bitarray to send all set values.
                        FieldValueUpdate update = UpdateFactory.Create(new EntityFieldUpdateCreationContext(ChangeTrackingCollections[interestingEntityGuid], ChangeTrackingCollections[interestingEntityGuid].ChangeTrackingArray));

                        updates.Add(new EntityAssociatedData <FieldValueUpdate>(interestingEntityGuid, update));
                    }

                    //It's possible no entity had updates, so we should not send a packet update
                    if (updates.Count != 0)
                    {
                        SendUpdate(guid, updates);
                    }
                }

                foreach (var dataEntityCollection in ChangeTrackingCollections.Values)
                {
                    dataEntityCollection.ClearTrackedChanges();
                }
            }
        }
Beispiel #4
0
 /// <inheritdoc />
 public EntityCreationData([NotNull] NetworkEntityGuid entityGuid, [NotNull] IMovementData initialMovementData, [NotNull] FieldValueUpdate initialFieldValues)
 {
     EntityGuid          = entityGuid ?? throw new ArgumentNullException(nameof(entityGuid));
     InitialMovementData = initialMovementData ?? throw new ArgumentNullException(nameof(initialMovementData));
     InitialFieldValues  = initialFieldValues ?? throw new ArgumentNullException(nameof(initialFieldValues));
 }
        private static EntityFieldDataCollection <EntityDataFieldType> CreateEntityDataCollectionFromPayload(FieldValueUpdate fieldUpdateValues)
        {
            //TODO: We need better initial handling for entity data
            EntityFieldDataCollection <EntityDataFieldType> entityData = new EntityFieldDataCollection <EntityDataFieldType>();

            int currentSentIndex = 0;

            foreach (var setIndex in fieldUpdateValues.FieldValueUpdateMask.EnumerateSetBitsByIndex())
            {
                entityData.SetFieldValue(setIndex, fieldUpdateValues.FieldValueUpdates.ElementAt(currentSentIndex));
                currentSentIndex++;
            }

            return(entityData);
        }