/// <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()); }
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); }
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(); }
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); }
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); }
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()); }
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); }
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); }
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()); }
public StringSyncSource(SyncSourceRoot syncSourceRoot, int referenceId, string baseObject) : base(syncSourceRoot, referenceId, baseObject) { }