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);
        }
示例#6
0
            public static DictionaryChange SetValue(TKey key, TValue value)
            {
                var result = new DictionaryChange();

                result.Key        = key;
                result.Value      = value;
                result.ChangeType = DictionaryChangeType.SetValue;

                return(result);
            }
示例#7
0
            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;
            }
        }
示例#9
0
        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));
        }
示例#13
0
 /// <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));
 }
示例#14
0
 /// <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);
                                }
                            }
                        }
                    }
                }
            }
        }