public async Task AddOrUpdateAsyncTest() { DictionaryChange change = null; TransactedConcurrentDictionary <int, string> d = new TransactedConcurrentDictionary <int, string>( new Uri("test://mocks", UriKind.Absolute), (c) => { change = c; return(true); } ); using (var tx = _stateManager.CreateTransaction()) { await d.AddOrUpdateAsync(tx, 1, (k) => "One", (k, v) => "Two"); Assert.IsNull(change); await tx.CommitAsync(); Assert.AreEqual("One", change.Added); } change = null; using (var tx = _stateManager.CreateTransaction()) { await d.AddOrUpdateAsync(tx, 1, (k) => "One", (k, v) => "Two"); Assert.IsNull(change); await tx.CommitAsync(); Assert.AreEqual("Two", change.Added); } }
public async Task ContainsKeyAsyncTest() { DictionaryChange change = null; TransactedConcurrentDictionary <int, string> d = new TransactedConcurrentDictionary <int, string>( new Uri("test://mocks", UriKind.Absolute), (c) => { change = c; return(true); } ); using (var tx = _stateManager.CreateTransaction()) { await d.AddAsync(tx, 1, "One"); await Assert.ThrowsExceptionAsync <TimeoutException>( async() => { await ContainsKey(d, 1, TimeSpan.FromMilliseconds(20)); } ); await tx.CommitAsync(); Assert.IsTrue(await ContainsKey(d, 1)); } }
public async Task TryGetValueAsyncTest() { DictionaryChange change = null; TransactedConcurrentDictionary <int, string> d = new TransactedConcurrentDictionary <int, string>( new Uri("test://mocks", UriKind.Absolute), (c) => { change = c; return(true); } ); using (var tx = _stateManager.CreateTransaction()) { Assert.IsFalse((await d.TryGetValueAsync(tx, 1, LockMode.Default)).HasValue); Assert.IsTrue(await d.TryAddAsync(tx, 1, "One")); using (var tx2 = _stateManager.CreateTransaction()) { await Assert.ThrowsExceptionAsync <TimeoutException>( async() => { await d.TryGetValueAsync(tx2, 1, LockMode.Default, timeout: TimeSpan.FromMilliseconds(20)); } ); } await tx.CommitAsync(); Assert.AreEqual("One", change.Added); } }
public async Task ClearAsyncTest() { DictionaryChange change = null; TransactedConcurrentDictionary <int, string> d = new TransactedConcurrentDictionary <int, string>( new Uri("test://mocks", UriKind.Absolute), (c) => { change = c; return(true); } ); using (var tx = _stateManager.CreateTransaction()) { await d.AddAsync(tx, 1, "One"); await tx.CommitAsync(); Assert.AreEqual(1, await GetCount(d)); } change = null; await d.ClearAsync(); Assert.AreEqual(0, await GetCount(d)); Assert.IsNull(change); }
public void Add(object key, object value) { DictionaryChangedEventArgs changedEventArgs = new DictionaryChangedEventArgs(Change.Edit); Keys.Add((T1)key); Values.Add((T2)value); DictionaryChange?.Invoke(this, changedEventArgs); }
public static DictionaryChange SetValue(TKey key, TValue value) { var result = new DictionaryChange(); result.Key = key; result.Value = value; result.ChangeType = DictionaryChangeType.SetValue; return(result); }
public static DictionaryChange Remove(TKey key) { var result = new DictionaryChange(); result.Key = key; result.Value = default(TValue); result.ChangeType = DictionaryChangeType.RemoveKey; return(result); }
public object this[object key] { get { int index = Keys.IndexOf((T1)key); return(Values[index]); } set { DictionaryChangedEventArgs changedEventArgs = new DictionaryChangedEventArgs(Change.Edit); DictionaryChange?.Invoke(this, changedEventArgs); int index = Keys.IndexOf((T1)key); Values[index] = (T2)value; } }
protected void GetPermissionToStart(PfcExecutionContext myPfcec, StepStateMachine ssm) { PfcExecutionContext root = myPfcec; int ascents = m_rootHeight; while (ascents > 0) { root = (PfcExecutionContext)myPfcec.Parent.Payload; ascents--; } Exchange exchange = null; if (m_myIndex == 0) { //Console.WriteLine(myPfcec.Name + " is creating an exchange and injecting it into pfcec " + root.Name + " under key " + m_sequenceKey); exchange = new Exchange(myPfcec.Model.Executive); root.Add(m_sequenceKey, exchange); } else { //Console.WriteLine(myPfcec.Name + " is looking for an exchange in pfcec " + root.Name + " under key " + m_sequenceKey); DictionaryChange dc = new DictionaryChange(myPfcec_EntryAdded); while (true) { exchange = (Exchange)root[m_sequenceKey]; if (exchange == null) { root.EntryAdded += dc; m_idec = myPfcec.Model.Executive.CurrentEventController; m_idec.Suspend(); } else { root.EntryAdded -= dc; break; } } exchange.Take(m_myKey, true); // Only indices 1,2, ... take (and wait?). Index 0 only posts. //Console.WriteLine(myPfcec.Name + " got the key I was looking for!"); } Guid nextGuysKey = GuidOps.Increment(m_myKey); exchange.Post(nextGuysKey, nextGuysKey, false); //Console.WriteLine(myPfcec.Name + " posted the key the next guy is looking for!"); }
public async Task AddAsyncTest() { DictionaryChange change = null; TransactedConcurrentDictionary <int, string> d = new TransactedConcurrentDictionary <int, string>( new Uri("test://mocks", UriKind.Absolute), (c) => { change = c; return(true); } ); using (var tx = _stateManager.CreateTransaction()) { await d.AddAsync(tx, 1, "One"); await Assert.ThrowsExceptionAsync <ArgumentException>( async() => { await d.AddAsync(tx, 1, "Two"); } ); Assert.IsNull(change); using (var tx2 = _stateManager.CreateTransaction()) { await Assert.ThrowsExceptionAsync <TimeoutException>( async() => { await d.AddAsync(tx2, 1, "Three", TimeSpan.FromMilliseconds(20)); } ); } Assert.IsNull(change); await tx.CommitAsync(); } Assert.AreEqual("One", change.Added); Assert.IsNull(change.Removed); Assert.AreEqual("One", (await GetValue(d, 1)).Value); }
public async Task TryAddAsyncTest() { DictionaryChange change = null; TransactedConcurrentDictionary <int, string> d = new TransactedConcurrentDictionary <int, string>( new Uri("test://mocks", UriKind.Absolute), (c) => { change = c; return(true); } ); using (var tx = _stateManager.CreateTransaction()) { Assert.IsTrue(await d.TryAddAsync(tx, 1, "One")); Assert.IsFalse(await d.TryAddAsync(tx, 1, "Two")); using (var tx2 = _stateManager.CreateTransaction()) { await Assert.ThrowsExceptionAsync <TimeoutException>( async() => { await d.TryAddAsync(tx2, 1, "Three", timeout: TimeSpan.FromMilliseconds(20)); } ); } await tx.CommitAsync(); Assert.AreEqual("One", change.Added); } using (var tx = _stateManager.CreateTransaction()) { Assert.IsFalse(await d.TryAddAsync(tx, 1, "Three")); Assert.IsTrue(await d.TryAddAsync(tx, 4, "Four")); Assert.IsTrue(await d.TryAddAsync(tx, 5, "Five")); await tx.CommitAsync(); } Assert.AreEqual(3, await GetCount(d)); Assert.AreEqual("One", (await GetValue(d, 1)).Value); Assert.AreEqual("Four", (await GetValue(d, 4)).Value); Assert.AreEqual("Five", (await GetValue(d, 5)).Value); }
public async Task SetAsyncTest() { DictionaryChange change = null; TransactedConcurrentDictionary <int, string> d = new TransactedConcurrentDictionary <int, string>( new Uri("test://mocks", UriKind.Absolute), (c) => { change = c; return(true); } ); using (var tx = _stateManager.CreateTransaction()) { await Assert.ThrowsExceptionAsync <ArgumentException>( async() => { await d.SetAsync(tx, 1, "One"); } ); await d.AddAsync(tx, 2, "Two"); await tx.CommitAsync(); } using (var tx = _stateManager.CreateTransaction()) { await d.SetAsync(tx, 2, "Three"); await tx.CommitAsync(); Assert.AreEqual("Two", change.Removed); Assert.AreEqual("Three", change.Added); } Assert.AreEqual(1, await GetCount(d)); }
/// <summary> /// Queues a remove modification for a given key. Modifications are applied in Repaint. /// </summary> public void Remove(TKey key) { this.queuedChanges.Enqueue(DictionaryChange.Remove(key)); }
/// <summary> /// Queues a set value modification for a given key. Modifications are applied in Repaint. /// </summary> public void SetValue(TKey key, object value) { this.queuedChanges.Enqueue(DictionaryChange.SetValue(key, (TValue)value)); }
public async Task SetAsyncTest() { DictionaryChange change = null; TransactedConcurrentDictionary <int, string> d = new TransactedConcurrentDictionary <int, string>( new Uri("test://mocks", UriKind.Absolute), (c) => { change = c; return(true); } ); using (var tx = _stateManager.CreateTransaction()) { await d.SetAsync(tx, 1, "Zero"); } using (var tx = _stateManager.CreateTransaction()) { ConditionalValue <string> value = await d.TryGetValueAsync(tx, 1, LockMode.Default); Assert.IsFalse(value.HasValue); } using (var tx = _stateManager.CreateTransaction()) { await d.SetAsync(tx, 1, "One"); await tx.CommitAsync(); Assert.AreEqual("One", change.Added); Assert.AreEqual(null, change.Removed); } using (var tx = _stateManager.CreateTransaction()) { await d.SetAsync(tx, 1, "Two"); } using (var tx = _stateManager.CreateTransaction()) { ConditionalValue <string> value = await d.TryGetValueAsync(tx, 1, LockMode.Default); Assert.AreEqual("One", value.Value); } using (var tx = _stateManager.CreateTransaction()) { await d.AddAsync(tx, 2, "Two"); await tx.CommitAsync(); } using (var tx = _stateManager.CreateTransaction()) { await d.SetAsync(tx, 2, "Three"); await tx.CommitAsync(); Assert.AreEqual("Two", change.Removed); Assert.AreEqual("Three", change.Added); } Assert.AreEqual(2, await GetCount(d)); }
//For flowchart reacting to ModelItem changes we are concerned of the following scenarios: //1. FlowElements being deleted from the Flowchart.Nodes collection or Flowswitch cases being deleted from ItemsCollection //2. FlowElements being added to the Flowchart.Nodes collection or Flowswitch cases being added from ItemsCollection //3. Properties being changed in FlowStep(Next), FlowDecision(True, false), FlowSwitch(Default) (Any of the flowelemnet should be present in the elements collection). //4. Flowswitch cases being added/remove via Cases.Dicitionary void ModelTreeManager_EditingScopeCompleted(object sender, EditingScopeEventArgs e) { Fx.Assert(this.panel != null, "This code should not be hit if panel is null"); foreach (Change change in e.EditingScope.Changes) { //Case 1, 2. if (change is CollectionChange) { CollectionChange collectionChange = change as CollectionChange; if (collectionChange.Collection.Equals(this.ModelItem.Properties["Nodes"].Collection)) { if (collectionChange.Operation == CollectionChange.OperationType.Delete) { this.DeleteShapeVisual(this.flowNodeToUIElement[collectionChange.Item]); } else { this.AddFlowElementsToDesigner(new List <ModelItem> { collectionChange.Item }); //An editing scope change references the ModelItem. //Hence in case of multiple changes to the same modelItem within the same EditingScope, we will see all the changes on the ModelItem for each change. //Eg. Suppose following two changes are in the same editing scope: 1. Add ModelItem item1 to Collection, 2. Change a property on this MI, item1.Prop1 //In this case, EditingScope.Changes.Count will be 2. //Since an EditingScope change keeps a reference to the ModelItem changed, when we process the first change, the second change would already be reflected on the ModelItem. //Hence, while processing CollectionChange for item1, item1.Prop1 will already reflect the new value. //Also there will be another change notifying the change in item1.Prop1. //AddFlowElementsToDesigner() method, walks through the properties of a newly added item and creates any links if required. //This is necessary for Paste scenario where we want to create links between Items added to the Nodes Collection. //Because of this behavior of AddFlowElementsToDesigner(), before reacting to a property change for adding a link, we will always verify that the link does not already exists. } } if (collectionChange.Collection.Parent != null && collectionChange.Collection.Parent.Parent != null && this.ModelItem.Properties["Nodes"].Collection.Contains(collectionChange.Collection.Parent.Parent) && collectionChange.Collection.Parent.Parent.ItemType.IsGenericType && collectionChange.Collection.Parent.Parent.ItemType.GetGenericTypeDefinition() == typeof(FlowSwitch <>)) { ModelItem item = collectionChange.Item; string caseName = GenericFlowSwitchHelper.GetString(item.Properties["Key"].ComputedValue, item.Properties["Key"].PropertyType); Connector connector = this.GetLinkOnCanvas(collectionChange.Collection.Parent.Parent, item.Properties["Value"].Value, GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier + caseName); if (collectionChange.Operation == CollectionChange.OperationType.Delete) { if (connector != null) { this.DeleteLinkVisual(connector); } } else if (collectionChange.Operation == CollectionChange.OperationType.Insert) { if (connector == null) { //Prepending GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier to differentiate between the FlowSwitch's Property Default and key Default. connector = this.CreatePropertyLink(collectionChange.Collection.Parent.Parent, item.Properties["Value"].Value, GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier + caseName); Fx.Assert(connector != null, "Link not created"); this.panel.Children.Add(connector); } else { RefreshFlowSwitchLinkModelItem(/* flowSwitchModelItem = */ collectionChange.Collection.Parent.Parent, connector, false); } } } } else if (change is DictionaryChange) { // case 4 DictionaryChange dictionaryChange = change as DictionaryChange; if (dictionaryChange.Dictionary.Parent != null && this.ModelItem.Properties["Nodes"].Collection.Contains(dictionaryChange.Dictionary.Parent) && dictionaryChange.Dictionary.Parent.ItemType.IsGenericType && dictionaryChange.Dictionary.Parent.ItemType.GetGenericTypeDefinition() == typeof(FlowSwitch <>)) { ModelItem flowSwitchModelItem = dictionaryChange.Dictionary.Parent; ModelItem caseTargetModelItem = dictionaryChange.Value; string caseName = GenericFlowSwitchHelper.GetString(dictionaryChange.Key == null ? null : dictionaryChange.Key.GetCurrentValue(), dictionaryChange.Key == null ? null : dictionaryChange.Key.ItemType); string caseNameInModelItem = GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier + caseName; Connector connector = this.GetLinkOnCanvas( flowSwitchModelItem, caseTargetModelItem, caseNameInModelItem); if (dictionaryChange.Operation == DictionaryChange.OperationType.Delete) { if (connector != null) { this.DeleteLinkVisual(connector); } } else if (dictionaryChange.Operation == DictionaryChange.OperationType.Insert) { if (connector == null) { connector = this.CreatePropertyLink( flowSwitchModelItem, caseTargetModelItem, caseNameInModelItem); this.panel.Children.Add(connector); } } } } //Case 3. else if (change is PropertyChange) { PropertyChange propertyChange = change as PropertyChange; if (this.ModelItem.Properties["Nodes"].Collection.Contains(propertyChange.Owner) || (propertyChange.PropertyName == "StartNode" && propertyChange.Owner == this.ModelItem)) { if (propertyChange.OldValue != null && IsFlowNode(propertyChange.OldValue)) { Connector link = GetLinkOnCanvas(propertyChange.Owner, propertyChange.OldValue, propertyChange.PropertyName); //Debug.Assert(link != null, "Link not found on designer"); if (link != null) { this.DeleteLinkVisual(link); } } if (propertyChange.NewValue != null && IsFlowNode(propertyChange.NewValue)) { Connector oldLink = GetLinkOnCanvas(propertyChange.Owner, propertyChange.NewValue, propertyChange.PropertyName); //If this connector has already been added don't add again. if (oldLink == null) { Connector link = CreatePropertyLink(propertyChange.Owner, propertyChange.NewValue, propertyChange.PropertyName); Fx.Assert(link != null, "Link not created"); this.panel.Children.Add(link); } else { if (GenericFlowSwitchHelper.IsGenericFlowSwitch(propertyChange.Owner.ItemType)) { this.RefreshFlowSwitchLinkModelItem(/* flowSwitchModelItem = */ propertyChange.Owner, oldLink, true); } } } //handling for the case where the FlowStep.Action changes: //Explicitly adding a check for FlowStep, because other FlowNodes have properties of type Activity, which we don't want to react to. //AddFlowElementsToDesigner() will add the links originating out of the shape that is changing. //We have to take care of refreshing the links coming into the shape that is changing. if (typeof(FlowStep).IsAssignableFrom(propertyChange.Owner.ItemType)) { List <Connector> oldIncomingConnectors = new List <Connector>(); if (propertyChange.OldValue != null && IsFlowStepAction(propertyChange.OldValue)) { UIElement oldShape = this.flowNodeToUIElement[propertyChange.Owner]; oldIncomingConnectors = this.GetInComingConnectors(oldShape); this.DeleteShapeVisual(oldShape); } if (propertyChange.NewValue != null && IsFlowStepAction(propertyChange.NewValue)) { this.AddFlowElementsToDesigner(new List <ModelItem> { propertyChange.Owner }); foreach (Connector oldConnector in oldIncomingConnectors) { Connector newConnector = CreateLink(FreeFormPanel.GetSourceConnectionPoint(oldConnector), this.flowNodeToUIElement[propertyChange.Owner], FlowchartDesigner.GetLinkModelItem(oldConnector)); this.panel.Children.Add(newConnector); } } } } } } }