public ObservableDictionarySourceSynchronizer(SourceSynchronizerRoot sourceSynchronizerRoot, int referenceId, Collections.ObservableDictionary <TKey, TValue> reference) : base(sourceSynchronizerRoot, referenceId, reference)
 {
     _keySerializer               = sourceSynchronizerRoot.Settings.Serializers.FindSerializerByType(typeof(TKey));
     _valueSerializer             = sourceSynchronizerRoot.Settings.Serializers.FindSerializerByType(typeof(TValue));
     Reference.CollectionChanged += OnCollectionChanged;
     AddReferences();
 }
        public ObjectSourceSynchronizer(SourceSynchronizerRoot sourceSynchronizerRoot, int referenceId,
                                        object reference) :
            base(sourceSynchronizerRoot, referenceId, reference)
        {
            Type type = Reference.GetType();

            SynchronizableMember[] synchronizableMembers = sourceSynchronizerRoot.SynchronizableMemberFactory.FromType(type);
            SynchronizableSourceMembers = new SynchronizableSourceMember[synchronizableMembers.Length];
            for (var i = 0; i < synchronizableMembers.Length; i++)
            {
                SynchronizableMember synchronizableMember = synchronizableMembers[i];
                var synchronizableSourceMember            = new SynchronizableSourceMember(Reference, synchronizableMember);
                SynchronizableSourceMembers[i] = synchronizableSourceMember;
            }

            for (var i = 0; i < SynchronizableSourceMembers.Length; i++)
            {
                SynchronizableSourceMember synchronizableSourceMember = SynchronizableSourceMembers[i];
                if (!synchronizableSourceMember.IsValueType)
                {
                    object initialValue = synchronizableSourceMember.Value;
                    if (initialValue != null)
                    {
                        sourceSynchronizerRoot.Synchronize(initialValue);
                    }
                }
            }
        }
Example #3
0
        public void SynchronizingString_ThatIsNotReferenceEqual_Test()
        {
            var sourceGameWorld = new NotifyPropertyChangedTestGameWorld {
                RandomIntProperty = 5
            };

            // Concatenating 1 to make sure the string is a new object
            sourceGameWorld.Players.Add("player1", new NotifyPropertyChangedTestPlayer {
                Name = "sameString" + 1, Health = 100, Level = 30
            });

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(sourceGameWorld);

            var TargetSynchronizerRoot = new TargetSynchronizerRoot <NotifyPropertyChangedTestGameWorld>(SourceSynchronizerRoot.WriteFullAndDispose());

            sourceGameWorld.Players.Add("player2", new NotifyPropertyChangedTestPlayer {
                Name = "sameString" + 1, Health = 44, Level = 1337
            });
            SynchronizationPacket writeChangesAndDispose = SourceSynchronizerRoot.WriteChangesAndDispose();

            TargetSynchronizerRoot.Read(writeChangesAndDispose.SetTick(TimeSpan.Zero));

            NotifyPropertyChangedTestGameWorld targetGameWorld = TargetSynchronizerRoot.Reference;

            AssertExtension.AssertCloneEqual(sourceGameWorld, targetGameWorld);
        }
        public void AddingItems_AfterClear_ShouldSynchronizeItems()
        {
            var hashSetTestObject = new NotifyPropertyChangedHashSetTestObject {
                RandomIntProperty = 5
            };

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(hashSetTestObject);

            hashSetTestObject.Players.Clear();

            var TargetSynchronizerRoot = new TargetSynchronizerRoot <NotifyPropertyChangedHashSetTestObject>(SourceSynchronizerRoot.WriteFullAndDispose());

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

            TargetSynchronizerRoot.Read(SourceSynchronizerRoot.WriteChangesAndDispose().SetTick(TimeSpan.FromMilliseconds(10)));

            NotifyPropertyChangedHashSetTestObject targetGameWorld = TargetSynchronizerRoot.Reference;

            AssertExtension.AssertCloneEqual(hashSetTestObject, targetGameWorld);
        }
        public void AddingItems_AfterClear_ShouldSynchronizeItems()
        {
            var sourceGameWorld = new NotifyPropertyChangedTestGameWorld {
                RandomIntProperty = 5
            };

            var sourceSynchronizerRoot = new SourceSynchronizerRoot(sourceGameWorld);

            sourceGameWorld.Players.Clear();

            var targetSynchronizerRoot = new TargetSynchronizerRoot <NotifyPropertyChangedTestGameWorld>(sourceSynchronizerRoot.WriteFullAndDispose());

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

            targetSynchronizerRoot.Read(sourceSynchronizerRoot.WriteChangesAndDispose().SetTick(TimeSpan.FromMilliseconds(10)));

            NotifyPropertyChangedTestGameWorld targetGameWorld = targetSynchronizerRoot.Reference;

            AssertExtension.AssertCloneEqual(sourceGameWorld, targetGameWorld);
        }
        public void Synchronizing_PrivateField_Test()
        {
            var privateMock            = new PrivateFieldMock(5);
            var SourceSynchronizerRoot = new SourceSynchronizerRoot(privateMock);
            var TargetSynchronizerRoot = new TargetSynchronizerRoot <PrivateFieldMock>(SourceSynchronizerRoot.WriteFullAndDispose());

            Assert.Equal(5, TargetSynchronizerRoot.Reference.GetTestValue);
        }
Example #7
0
        public SourceSynchronizer Synchronize(SourceSynchronizerRoot sourceSynchronizerRoot, int referenceId, object reference)
        {
            Type[] genericArgs = reference.GetType().GetGenericArguments();
            Type   observableHashSetSyncSourceObjectType = typeof(ObservableHashSetSourceSynchronizer <>).MakeGenericType(genericArgs);

            return((SourceSynchronizer)Activator.CreateInstance(observableHashSetSyncSourceObjectType, sourceSynchronizerRoot,
                                                                referenceId, reference));
        }
        public void Synchronizing_PropertyWithoutSetterThroughConstructor_Synchronizes()
        {
            var getterOnlyConstructorMockSource = new NotifyPropertyChangedGetterOnlyConstructorMock(5);
            var SourceSynchronizerRoot          = new SourceSynchronizerRoot(getterOnlyConstructorMockSource);
            var TargetSynchronizerRoot          = new TargetSynchronizerRoot <NotifyPropertyChangedGetterOnlyConstructorMock>(SourceSynchronizerRoot.WriteFullAndDispose());
            NotifyPropertyChangedGetterOnlyConstructorMock notifyPropertyChangedGetterOnlyConstructorMockRoot = TargetSynchronizerRoot.Reference;

            Assert.Equal(getterOnlyConstructorMockSource.IntProperty, notifyPropertyChangedGetterOnlyConstructorMockRoot.IntProperty);
        }
        public void Constructing_DependencyConstructorParameter_ResolvesFromDependencyResolver()
        {
            var dependencyConstructorMock = new NotifyPropertyChangedConstructedDependencyMock();

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(dependencyConstructorMock);

            var TargetSynchronizerRoot = new TargetSynchronizerRoot <NotifyPropertyChangedConstructedDependencyMock>(SourceSynchronizerRoot.WriteFullAndDispose(), serviceProvider: new TestServiceProvider());

            Assert.NotNull(TargetSynchronizerRoot.Reference.SomeService);
        }
Example #10
0
        public Server()
        {
            Map  = new Map();
            Self = new Player(Utils.RandomColor());
            Map.Players.Add(Self);

            _gameWorldSyncSourceRoot = new SourceSynchronizerRoot(Map);
            _tcpListener             = new TcpListener(IPAddress.Loopback, 1234);
            _tcpListener.Start();
        }
        public void Clear_ShouldThrowNotImplemented()
        {
            var sourceDictionary       = new ObservableDictionary <int, string>();
            var SourceSynchronizerRoot = new SourceSynchronizerRoot(sourceDictionary);

            byte[] data = SourceSynchronizerRoot.WriteFullAndDispose();
            var    TargetSynchronizerRoot = new TargetSynchronizerRoot <ObservableDictionary <int, string> >(data);

            Assert.Throws <NotSupportedException>(() => { TargetSynchronizerRoot.Reference.Clear(); });
        }
Example #12
0
 private void AddReference(TKey item)
 {
     if (typeof(TKey).IsValueType == false)
     {
         if (item != null)
         {
             SourceSynchronizerRoot.Synchronize(item);
         }
     }
 }
        public void Synchronizing_Test()
        {
            var playerMock = new PlayerMock();

            playerMock.Level = 5;
            var sourceSynchronizerRoot = new SourceSynchronizerRoot(playerMock);
            var targetSynchronizerRoot = new TargetSynchronizerRoot <PlayerMock>(sourceSynchronizerRoot.WriteFullAndDispose());

            Assert.Equal(5, targetSynchronizerRoot.Reference.Level);
        }
Example #14
0
        private static void RunMonoSyncTest(int entityCount)
        {
            Console.WriteLine();
            Console.WriteLine($"Benchmark with {entityCount} entities");

            // Initialization
            Console.Write("Initializing: ");
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            var world          = new MonoSyncWorld();
            var syncSourceRoot = new SourceSynchronizerRoot(world);

            using (world.Entities.BeginMassUpdate())
            {
                for (int i = 0; i < entityCount; i++)
                {
                    world.Entities.Add(i, new Entity());
                }
            }
            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds + "MS");
            stopwatch.Reset();

            // Full write
            Console.Write("Full write: ");
            stopwatch.Start();


            WriteSession fullWriteSession = syncSourceRoot.BeginWrite();
            var          syncTargetRoot   = new TargetSynchronizerRoot <MonoSyncWorld>(fullWriteSession.WriteFull());

            fullWriteSession.Dispose();

            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds + "MS");
            stopwatch.Reset();

            int changes = entityCount / 10;

            Console.Write($"{changes} changes write: ");
            stopwatch.Start();

            for (int i = 0; i < changes; i++)
            {
                world.Entities[i].XPos = 2;
            }
            using (WriteSession writeSession = syncSourceRoot.BeginWrite())
            {
                var data = writeSession.WriteChanges().SetTick(TimeSpan.Zero);
                syncTargetRoot.Read(data);
            }
            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds + "MS");
        }
        public void AddingItems_ThatAreReferences_ShouldTrackAddedItems()
        {
            var sourceDictionary = new ObservableDictionary <int, string>();

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(sourceDictionary);

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

            Assert.Equal(3, SourceSynchronizerRoot.TrackedObjects.Count());
        }
        public void AddingItems_ThatAreReferences_ShouldTrackAddedItems()
        {
            var sourceHashSet = new ObservableHashSet <string>();

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(sourceHashSet);

            sourceHashSet.Add("1");
            sourceHashSet.Add("2");

            Assert.Equal(3, SourceSynchronizerRoot.TrackedObjects.Count());
        }
Example #17
0
        public void Initializing_NonConstructorPropertyWithoutSetter_ThrowsSetterNotFoundException()
        {
            var attributeMarkedMethodMockSource = new NotifyPropertyChangedGetterOnlyMock();

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(attributeMarkedMethodMockSource);

            Assert.Throws <SetterNotAvailableException>(() =>
            {
                var TargetSynchronizerRoot = new TargetSynchronizerRoot(SourceSynchronizerRoot.WriteFullAndDispose());
            });
        }
        public void Initializing_WithItems_ShouldTrackExistingItems()
        {
            var sourceHashSet = new ObservableHashSet <string>()
            {
                "1", "2"
            };

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(sourceHashSet);

            Assert.Equal(3, SourceSynchronizerRoot.TrackedObjects.Count());
        }
        public void Synchronizing_PropertiesUsedAsConstructorParameters_ShouldNotSynchronizeAfterConstructor()
        {
            var sourceConstructorMock = new NotifyPropertyChangedSynchronizeConstructorMock();

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(sourceConstructorMock);

            var TargetSynchronizerRoot =
                new TargetSynchronizerRoot <NotifyPropertyChangedSynchronizeConstructorMock>(SourceSynchronizerRoot.WriteFullAndDispose());
            NotifyPropertyChangedSynchronizeConstructorMock targetConstructorMock = TargetSynchronizerRoot.Reference;

            Assert.Equal(1, targetConstructorMock.DictionarySetCount);
        }
        public void Initializing_WithItems_ShouldTrackExistingItems()
        {
            var sourceDictionary = new ObservableDictionary <int, string>
            {
                { 1, "1" },
                { 2, "2" }
            };

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(sourceDictionary);

            Assert.Equal(3, SourceSynchronizerRoot.TrackedObjects.Count());
        }
        public ArraySourceSynchronizer(SourceSynchronizerRoot sourceSynchronizerRoot, int referenceId, object reference) : base(sourceSynchronizerRoot, referenceId, reference)
        {
            Type type = reference.GetType();

            _elementSerializer = sourceSynchronizerRoot.Settings.Serializers.FindSerializerByType(type.GetElementType());
            if (type.GetElementType().IsValueType == false)
            {
                foreach (object item in Reference)
                {
                    sourceSynchronizerRoot.Synchronize(item);
                }
            }
        }
        public void Synchronizing_Array_Test()
        {
            int[,,] expected = new int[3, 3, 5]
            {
                { { 1, 2, 6, 4, 5 }, { 2, 2, 3, 4, 5 }, { 3, 2, 3, 4, 5 } },
                { { 1, 2, 3, 4, 5 }, { 2, 2, 3, 4, 5 }, { 3, 2, 3, 4, 5 } },
                { { 1, 2, 3, 4, 5 }, { 99, 2, 3, 4, 5 }, { 3, 2, 3, 99, 3 } }
            };
            var SourceSynchronizerRoot = new SourceSynchronizerRoot(expected);
            var TargetSynchronizerRoot = new TargetSynchronizerRoot <int[, , ]>(SourceSynchronizerRoot.WriteFullAndDispose());

            Assert.Equal(expected, TargetSynchronizerRoot.Reference);
        }
        public void Changing_ConstructorProperty_Synchronizes()
        {
            var getterOnlyConstructorMockSource = new ConstructedPropertyChangeSynchronizationMock(5f);

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(getterOnlyConstructorMockSource);
            var TargetSynchronizerRoot = new TargetSynchronizerRoot <ConstructedPropertyChangeSynchronizationMock>(SourceSynchronizerRoot.WriteFullAndDispose());

            ConstructedPropertyChangeSynchronizationMock getterOnlyConstructorMockRoot = TargetSynchronizerRoot.Reference;

            Assert.Equal(getterOnlyConstructorMockSource.Accessor, getterOnlyConstructorMockRoot.Accessor);

            TargetSynchronizerRoot.Read(SourceSynchronizerRoot.WriteChangesAndDispose().SetTick(TimeSpan.Zero));

            Assert.Equal(getterOnlyConstructorMockSource.Accessor, getterOnlyConstructorMockRoot.Accessor);
        }
        public void Synchronizing_MarkedParameterizedConstructor_InvokesConstructorWithParameters()
        {
            var sourceConstructorMock = new NotifyPropertyChangedSynchronizeConstructorMock();

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(sourceConstructorMock);

            var TargetSynchronizerRoot =
                new TargetSynchronizerRoot <NotifyPropertyChangedSynchronizeConstructorMock>(SourceSynchronizerRoot.WriteFullAndDispose());

            TargetSynchronizerRoot.Read(SourceSynchronizerRoot.WriteChangesAndDispose().SetTick(TimeSpan.Zero));

            NotifyPropertyChangedSynchronizeConstructorMock targetConstructorMock = TargetSynchronizerRoot.Reference;

            Assert.True(targetConstructorMock.SyncConstructorCalled);
        }
        public void Synchronizing_GetterManual_Resolves()
        {
            var sourceConstructorMock = new NotifyPropertyChangedManualGetterOnlyMock();

            var sourceSynchronizerRoot = new SourceSynchronizerRoot(sourceConstructorMock);

            Assert.Equal(5, sourceConstructorMock.SomeValue);

            sourceConstructorMock.SomeValue = 6;

            var TargetSynchronizerRoot = new TargetSynchronizerRoot <NotifyPropertyChangedManualGetterOnlyMock>(sourceSynchronizerRoot.WriteFullAndDispose());

            NotifyPropertyChangedManualGetterOnlyMock targetConstructorMock = TargetSynchronizerRoot.Reference;

            Assert.Equal(6, targetConstructorMock.SomeValue);
        }
        private void AddReferencesFromKeyValuePair(KeyValuePair <TKey, TValue> newItem)
        {
            if (typeof(TKey).IsValueType == false)
            {
                if (newItem.Key != null)
                {
                    SourceSynchronizerRoot.Synchronize(newItem.Key);
                }
            }

            if (typeof(TValue).IsValueType == false)
            {
                if (newItem.Value != null)
                {
                    SourceSynchronizerRoot.Synchronize(newItem.Value);
                }
            }
        }
Example #27
0
        public void SettingReferenceToNull_ThatIsCyclic_WillNotBeUntracked()
        {
            var selfReferencingChild = new NotifyPropertyChangedReferencingCircleHelper();

            selfReferencingChild.Other = selfReferencingChild;

            var referenceToChild = new NotifyPropertyChangedReferencingCircleHelper {
                Other = selfReferencingChild
            };

            var SourceSynchronizerRoot = new SourceSynchronizerRoot(referenceToChild);

            Assert.Equal(2, SourceSynchronizerRoot.TrackedObjects.Count());

            referenceToChild.Other = null;

            Assert.Equal(2, SourceSynchronizerRoot.TrackedObjects.Count());
        }
        public void SynchronizingFull_TargetObjectEqualsSource()
        {
            var sourceGameWorld = new NotifyPropertyChangedTestGameWorld {
                RandomIntProperty = 5
            };

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

            var sourceSynchronizerRoot = new SourceSynchronizerRoot(sourceGameWorld);

            var targetSynchronizerRoot = new TargetSynchronizerRoot <NotifyPropertyChangedTestGameWorld>(sourceSynchronizerRoot.WriteFullAndDispose());
            NotifyPropertyChangedTestGameWorld targetGameWorld = targetSynchronizerRoot.Reference;

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

            var sourceSynchronizerRoot = new SourceSynchronizerRoot(sourceDictionary);

            var targetSynchronizerRoot = new TargetSynchronizerRoot <ObservableDictionary <int, string> >(
                sourceSynchronizerRoot.WriteFullAndDispose());

            ObservableDictionary <int, string> targetDictionary = targetSynchronizerRoot.Reference;

            targetDictionary.Add(1, "2");

            targetSynchronizerRoot.Clock.OwnTick = TimeSpan.FromMilliseconds(5);

            //Set tick older than client tick
            byte[] changes = sourceSynchronizerRoot.WriteChangesAndDispose().SetTick(TimeSpan.FromMilliseconds(5));
            targetSynchronizerRoot.Read(changes);

            // Recently added item should be rolled back
            Assert.Empty(targetDictionary);
        }
        private void SourceObjectOnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // Value changed event might be from a non-sync property
            if (TryGetMemberByName(e.PropertyName, out SynchronizableSourceMember syncSourceProperty))
            {
                object newValue = syncSourceProperty.Value;

                // Synchronize newly added references
                if (syncSourceProperty.IsValueType == false)
                {
                    if (newValue != null)
                    {
                        SourceSynchronizerRoot.Synchronize(newValue);
                    }
                }
                _changedProperties[syncSourceProperty.Index] = true;
                if (Dirty == false)
                {
                    MarkDirty();
                }
            }
        }