/// <summary> /// Open the specified collection /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name">The name of the collection to open</param> /// <param name="mode">The mode used to open the collection</param> /// <param name="collectionType">The type of the Collection (e.g. Ordered, Unordered)</param> /// <param name="connectedCallback">Callback to call when the collection is connected</param> /// <returns></returns> public SharedCollection Open <T>(string name, ObjectMode mode, CollectionType collectionType) where T : INotifyPropertyChanged { client.VerifyAccess(); if (!this.client.IsConnected) { throw new InvalidOperationException("Cannot open collection before the Client is connected"); } if (this.pendingCollections.ContainsKey(name)) { throw new InvalidOperationException("The specified collection is already in the process of being opened"); } CollectionEntry entry = null; if (this.ContainsKey(name)) { if (mode != ObjectMode.Open && mode != ObjectMode.OpenOrCreate) { throw new ArgumentException("Invalid ObjectMode. Specified collection has already been opened on this client. Try using ObjectMode.Open", "mode"); } entry = this[name]; // Make sure type of collection matches T if (entry.Type != typeof(T)) { throw new ArgumentException("Specified type does not match that of existing collection"); } } else { switch (collectionType) { case CollectionType.Ordered: entry = new OrderedCollectionEntry(this.client, name, typeof(T)); // Start the heartbeat timer when an ordered collection is created // TODO ransomr optimize heartbeats so only sent when there are ordered collections with changes, make thread safe if (this.HeartbeatTimer == null) { this.HeartbeatTimer = new DispatcherTimer(); this.HeartbeatTimer.Tick += this.SendCollectionHeartbeat; this.HeartbeatTimer.Interval = TimeSpan.FromSeconds(Constants.HeartbeatIntervalSeconds); this.HeartbeatTimer.Start(); } break; case CollectionType.Unordered: entry = new UnorderedCollectionEntry(this.client, name, typeof(T)); break; } AddCollection(entry, mode, Source.Client); } // Register a new reference to the SharedObservableCollection return(entry.Register <T>()); }
private void ApplyTransform(OrderedCollectionEntry collection, ref CollectionOperation incoming) { List <CollectionOperation> updatedOperations = new List <CollectionOperation>(); foreach (var operation in collection.LocalOperations) { CollectionOperation newOperation; CollectionOperation.ApplyTransform(operation, ref incoming, out newOperation); updatedOperations.Add(newOperation); } // Replace local operations with updated, transformed versions collection.LocalOperations = updatedOperations; }