/// <summary>
        ///     References from the source <see cref="ObservableDictionary{TKey,TValue}" /> are tracked,
        ///     because the <see cref="NotifyCollectionChangedAction.Reset" /> action doesn't specify the removed items
        /// </summary>
        /// <param name="reference"></param>

        #region

        private void RemoveReference(object reference)
        {
            if (reference == null)
            {
                return;
            }

            if (_trackedReferences.TryGetValue(reference, out int count))
            {
                if (--count <= 0)
                {
                    _trackedReferences.Remove(reference);
                }
                else
                {
                    _trackedReferences[reference] = count;
                }
            }
            else
            {
                throw new InvalidOperationException("removal of un-tracked reference");
            }

            SyncSourceRoot.RemoveReference(reference);
        }
        public void SynchronizeChangesAddedItemTest()
        {
            var sourceGameWorld = new TestGameWorld();

            sourceGameWorld.RandomIntProperty = 5;

            var syncSourceRoot = new SyncSourceRoot(sourceGameWorld, _sourceSettings);

            var syncTargetRoot =
                new SyncTargetRoot <TestGameWorld>(syncSourceRoot.WriteFullAndDispose(), _targetSettings);

            sourceGameWorld.Players.Add("player1", new TestPlayer {
                Health = 100, Level = 30
            });
            sourceGameWorld.Players.Add("player2", new TestPlayer {
                Health = 44, Level = 1337
            });


            syncTargetRoot.Read(syncSourceRoot.WriteChangesAndDispose().SetTick(0));

            TestGameWorld targetGameWorld = syncTargetRoot.Root;

            AssertExtension.AssertCloneEqual(sourceGameWorld, targetGameWorld);
        }
        public void ObservableDictionaryAddItemTest()
        {
            var sourceDictionary = new ObservableDictionary <int, string>();

            sourceDictionary.Add(1, "1");
            sourceDictionary.Add(2, "2");

            // Full write
            var syncSourceRoot = new SyncSourceRoot(sourceDictionary, _sourceSettings);


            var syncTargetRoot =
                new SyncTargetRoot <ObservableDictionary <int, string> >(syncSourceRoot.WriteFullAndDispose(),
                                                                         _targetSettings);
            ObservableDictionary <int, string> targetDictionary = syncTargetRoot.Root;

            foreach (KeyValuePair <int, string> keyValuePair in sourceDictionary)
            {
                Assert.Equal(keyValuePair.Value, targetDictionary[keyValuePair.Key]);
            }

            // Changes

            sourceDictionary.Add(3, "3");


            byte[] changesSynchronization = syncSourceRoot.WriteChangesAndDispose().SetTick(0);

            syncTargetRoot.Read(changesSynchronization);

            foreach (KeyValuePair <int, string> keyValuePair in sourceDictionary)
            {
                Assert.Equal(keyValuePair.Value, targetDictionary[keyValuePair.Key]);
            }
        }
 public ObservableDictionarySyncSource(SyncSourceRoot syncSourceRoot, int referenceId,
                                       ObservableDictionary <TKey, TValue> baseObject,
                                       IFieldSerializerResolver fieldSerializerResolver) : base(syncSourceRoot, referenceId, baseObject)
 {
     _keySerializer                = fieldSerializerResolver.FindMatchingSerializer(typeof(TKey));
     _valueSerializer              = fieldSerializerResolver.FindMatchingSerializer(typeof(TValue));
     BaseObject.CollectionChanged += OnCollectionChanged;
     AddNewItemReferences(BaseObject.ToList());
 }
Example #5
0
        public NotifyPropertyChangedSyncSource(SyncSourceRoot syncSourceRoot, int referenceId,
                                               INotifyPropertyChanged baseObject,
                                               IFieldSerializerResolver fieldSerializerResolver) :
            base(syncSourceRoot, referenceId, baseObject)
        {
            baseObject.PropertyChanged += SourceObjectOnPropertyChanged;

            _changeTracker.Dirty += ChangeTrackerOnDirty;
            PropertyInfo[] properties = BaseObject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
            (PropertyInfo info, SyncAttribute attibute)[] syncProperties =
        public void ObservableDictionaryReferenceTrackOnPreAddTest()
        {
            var sourceDictionary = new ObservableDictionary <int, string>();

            sourceDictionary.Add(1, "1");
            sourceDictionary.Add(2, "2");

            var syncSourceRoot = new SyncSourceRoot(sourceDictionary, SyncSourceSettings.Default);

            Assert.Equal(3, syncSourceRoot.TrackedReferences.Count());
        }
        public SyncSource Create(SyncSourceRoot syncSourceRoot, int referenceId, object baseType,
                                 IFieldSerializerResolver fieldSerializerResolver)
        {
            Type[] genericArgs = baseType.GetType().GetGenericArguments();
            Type   observableDictionarySyncSourceObjectType =
                typeof(ObservableDictionarySyncSource <,>).MakeGenericType(genericArgs);

            return((SyncSource)Activator.CreateInstance(observableDictionarySyncSourceObjectType, syncSourceRoot,
                                                        referenceId,
                                                        baseType, fieldSerializerResolver));
        }
        private void RemoveAllReference()
        {
            foreach (KeyValuePair <object, int> referenceCounter in _trackedReferences)
            {
                for (var i = 0; i < referenceCounter.Value; i++)
                {
                    SyncSourceRoot.RemoveReference(referenceCounter.Key);
                }
            }

            _trackedReferences.Clear();
        }
        public void PropertiesUsedInConstructorShouldNotSynchronizeOnConstructionTest()
        {
            var sourceConstructorMock = new SynchronizeConstructorMock();

            var syncSourceRoot = new SyncSourceRoot(sourceConstructorMock, _sourceSettings);

            var syncTargetRoot =
                new SyncTargetRoot <SynchronizeConstructorMock>(syncSourceRoot.WriteFullAndDispose(), _targetSettings);
            SynchronizeConstructorMock targetConstructorMock = syncTargetRoot.Root;

            Assert.Equal(1, targetConstructorMock.DictionarySetCount);
        }
Example #10
0
        public Server()
        {
            Map = new Map();
            Map.Players.Add(0, new Player(Utils.RandomColor()));

            var settings = SyncSourceSettings.Default;

            settings.TypeEncoder = new TweenGameTypeEncoder();
            settings.FieldDeserializerResolverFactory = new TweenGameFieldSerializerFactory();
            _gameWorldSyncSourceRoot = new SyncSourceRoot(Map, settings);
            _tcpListener             = new TcpListener(IPAddress.Loopback, 1234);
            _tcpListener.Start();
        }
Example #11
0
        public void WriteChangesShouldCreateNewReferenceTest()
        {
            var sourceGameWorld = new TestGameWorld {
                RandomIntProperty = 5
            };
            var syncSourceRoot = new SyncSourceRoot(sourceGameWorld, _sourceSettings);

            var           syncTargetRoot = new SyncTargetRoot <TestGameWorld>(syncSourceRoot.WriteFullAndDispose(), _targetSettings);
            TestGameWorld previousTargetTestGameWorld = syncTargetRoot.Root;

            syncTargetRoot.Read(syncSourceRoot.WriteChangesAndDispose().SetTick(0));

            Assert.Equal(previousTargetTestGameWorld, syncTargetRoot.Root);
        }
        public void SyncConstructorShouldBeCalledTest()
        {
            var sourceConstructorMock = new SynchronizeConstructorMock();

            var syncSourceRoot = new SyncSourceRoot(sourceConstructorMock, _sourceSettings);

            var syncTargetRoot =
                new SyncTargetRoot <SynchronizeConstructorMock>(syncSourceRoot.WriteFullAndDispose(), _targetSettings);

            syncTargetRoot.Read(syncSourceRoot.WriteChangesAndDispose().SetTick(0));

            SynchronizeConstructorMock targetConstructorMock = syncTargetRoot.Root;

            Assert.True(targetConstructorMock.SyncConstructorCalled);
        }
Example #13
0
        public void AddingReferenceThatWasPreviouslyRemovedShouldBeRemovedFromTheRemovedReferences()
        {
            var observableDictionary = new ObservableDictionary <int, string>();
            var syncSourceRoot       = new SyncSourceRoot(observableDictionary, _sourceSettings);

            observableDictionary.Add(1, "1");
            Assert.Equal(2, syncSourceRoot.TrackedReferences.Count());
            Assert.Empty(syncSourceRoot.RemovedReferences);

            // Simulate write to mark synchronized
            syncSourceRoot.BeginWrite().Dispose();

            observableDictionary.Remove(1);
            Assert.Single(syncSourceRoot.RemovedReferences);

            observableDictionary.Add(1, "1");
            Assert.Empty(syncSourceRoot.RemovedReferences);
        }
        private void AddReference(object reference)
        {
            if (reference == null)
            {
                return;
            }

            if (_trackedReferences.TryGetValue(reference, out int count))
            {
                _trackedReferences[reference] = ++count;
            }
            else
            {
                _trackedReferences[reference] = 1;
            }

            SyncSourceRoot.AddReference(reference);
        }
Example #15
0
        public void ReferenceCycleShouldNotBeCollectedByReferenceCountTest()
        {
            var selfReferencingChild = new ReferencingCircleHelper();

            selfReferencingChild.Other = selfReferencingChild;

            var referenceToChild = new ReferencingCircleHelper {
                Other = selfReferencingChild
            };

            var syncSourceRoot = new SyncSourceRoot(referenceToChild, _sourceSettings);

            Assert.Equal(2, syncSourceRoot.TrackedReferences.Count());

            referenceToChild.Other = null;

            Assert.Equal(2, syncSourceRoot.TrackedReferences.Count());
        }
Example #16
0
        public void RemovedReferenceShouldBeCollectedByReferenceCounterTest()
        {
            var observableDictionary = new ObservableDictionary <int, string>();
            var syncSourceRoot       = new SyncSourceRoot(observableDictionary, _sourceSettings);

            observableDictionary.Add(1, "1");

            syncSourceRoot.BeginWrite().Dispose();

            Assert.Equal(2, syncSourceRoot.TrackedReferences.Count());

            observableDictionary.Remove(1);

            // Object are removed after write
            syncSourceRoot.WriteChangesAndDispose();

            Assert.Single(syncSourceRoot.TrackedReferences);
        }
Example #17
0
        public void RemovingAChangedReferenceShouldAlsoRemoveItFromDirtyListTest()
        {
            var world  = new TestGameWorld();
            var player = new TestPlayer();

            world.Players.Add("player", player);
            var syncSourceRoot = new SyncSourceRoot(world, _sourceSettings);

            var syncTargetRoot = new SyncTargetRoot(syncSourceRoot.WriteFullAndDispose(), _targetSettings);

            player.Health = 3;

            world.Players.Remove("player");

            // Changes are removed after write
            syncSourceRoot.WriteChangesAndDispose().SetTick(0);

            Assert.DoesNotContain(player, syncSourceRoot.DirtyReferences);
        }
Example #18
0
        public void ReferenceCycleShouldBeCollectedByGarbageCollectionTest()
        {
            var selfReferencingChild = new ReferencingCircleHelper();

            selfReferencingChild.Other = selfReferencingChild;

            var referenceToChild = new ReferencingCircleHelper {
                Other = selfReferencingChild
            };

            var syncSourceRoot = new SyncSourceRoot(referenceToChild, _sourceSettings);

            Assert.Equal(2, syncSourceRoot.TrackedReferences.Count());

            referenceToChild.Other = null;

            syncSourceRoot.GarbageCollect();

            syncSourceRoot.WriteChangesAndDispose();

            Assert.Single(syncSourceRoot.TrackedReferences);
        }
        public void MoreThanEightSyncAttributesTest()
        {
            var sourceTestMock = new SynchronizeManySyncAttributesTest()
            {
                Test  = 0,
                Test2 = 2,
                Test3 = 34,
                Test4 = 43,
                Test5 = 122,
                Test6 = 99999999.32423,
                Test7 = 3434,
                Test8 = 23,
                Test9 = 2
            };

            var syncSourceRoot = new SyncSourceRoot(sourceTestMock, _sourceSettings);

            var target =
                new SyncTargetRoot <SynchronizeManySyncAttributesTest>(syncSourceRoot.WriteFullAndDispose(), _targetSettings);

            AssertExtension.AssertCloneEqual(sourceTestMock, target.Root);
        }
 public SyncSource Create(SyncSourceRoot syncSourceRoot, int referenceId, object baseType,
                          IFieldSerializerResolver fieldSerializerResolver)
 {
     return(new StringSyncSource(syncSourceRoot, referenceId, baseType as string));
 }
 public static SynchronizationPacket WriteChangesAndDispose(this SyncSourceRoot syncSourceRoot)
 {
     using WriteSession session = syncSourceRoot.BeginWrite();
     return(session.WriteChanges());
 }
 public SyncSource Create(SyncSourceRoot syncSourceRoot, int referenceId, object baseType,
                          IFieldSerializerResolver fieldSerializerResolver)
 {
     return(new NotifyPropertyChangedSyncSource(syncSourceRoot, referenceId, baseType as INotifyPropertyChanged,
                                                fieldSerializerResolver));
 }
 public static byte[] WriteFullAndDispose(this SyncSourceRoot syncSourceRoot)
 {
     using WriteSession session = syncSourceRoot.BeginWrite();
     return(session.WriteFull());
 }
Example #24
0
 public StringSyncSource(SyncSourceRoot syncSourceRoot, int referenceId, string baseObject) :
     base(syncSourceRoot, referenceId, baseObject)
 {
 }