Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Statements / Flowchart.cs / 1305376 / Flowchart.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Statements
{
using System.Activities;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime;
using System.Runtime.Collections;
using System.Windows.Markup;
[ContentProperty("Nodes")]
public sealed class Flowchart : NativeActivity
{
Collection variables;
Collection nodes;
Collection allNodes;
CompletionCallback onStepCompleted;
CompletionCallback onDecisionCompleted;
Variable currentNode;
public Flowchart()
{
this.currentNode = new Variable();
this.allNodes = new Collection();
}
public Collection Variables
{
get
{
if (this.variables == null)
{
this.variables = new ValidatingCollection
{
// disallow null values
OnAddValidationCallback = item =>
{
if (item == null)
{
throw FxTrace.Exception.ArgumentNull("item");
}
}
};
}
return this.variables;
}
}
[DependsOn("Variables")]
public FlowNode StartNode
{
get;
set;
}
[DependsOn("StartNode")]
public Collection Nodes
{
get
{
if (this.nodes == null)
{
this.nodes = new ValidatingCollection
{
// disallow null values
OnAddValidationCallback = item =>
{
if (item == null)
{
throw FxTrace.Exception.ArgumentNull("item");
}
}
};
}
return this.nodes;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.SetVariablesCollection(this.Variables);
metadata.AddImplementationVariable(this.currentNode);
GatherAllNodes(metadata);
HashSet uniqueChildren = new HashSet();
for (int i = 0; i < this.allNodes.Count; i++)
{
this.allNodes[i].GetChildActivities(uniqueChildren);
}
List children = new List(uniqueChildren.Count);
foreach (Activity child in uniqueChildren)
{
children.Add(child);
}
metadata.SetChildrenCollection(new Collection(children));
}
void GatherAllNodes(NativeActivityMetadata metadata)
{
// Clear out our cached list of all nodes
this.allNodes.Clear();
if (this.StartNode == null && this.Nodes.Count > 0)
{
metadata.AddValidationError(SR.FlowchartMissingStartNode(this.DisplayName));
}
else
{
DepthFirstVisitNodes((n) => VisitNode(n, metadata), this.StartNode);
}
}
// Returns true if we should visit connected nodes
bool VisitNode(FlowNode node, NativeActivityMetadata metadata)
{
if (node.Open(this, metadata))
{
Fx.Assert(node.Index == -1 && !this.allNodes.Contains(node), "Corrupt Flowchart.allNodes.");
node.Index = this.allNodes.Count;
this.allNodes.Add(node);
return true;
}
return false;
}
void DepthFirstVisitNodes(Func visitNodeCallback, FlowNode start)
{
Fx.Assert(visitNodeCallback != null, "This must be supplied since it stops us from infinitely looping.");
List connected = new List();
Stack stack = new Stack();
if (start == null)
{
return;
}
stack.Push(start);
while (stack.Count > 0)
{
FlowNode current = stack.Pop();
if (current == null)
{
continue;
}
if (visitNodeCallback(current))
{
connected.Clear();
current.GetConnectedNodes(connected);
for (int i = 0; i < connected.Count; i++)
{
stack.Push(connected[i]);
}
}
}
}
protected override void Execute(NativeActivityContext context)
{
if (this.StartNode != null)
{
if (TD.FlowchartStartIsEnabled())
{
TD.FlowchartStart(this.DisplayName);
}
ExecuteNodeChain(context, this.StartNode, null);
}
else
{
if (TD.FlowchartEmptyIsEnabled())
{
TD.FlowchartEmpty(this.DisplayName);
}
}
}
void ExecuteNodeChain(NativeActivityContext context, FlowNode node, ActivityInstance completedInstance)
{
if (node == null)
{
if (context.IsCancellationRequested)
{
Fx.Assert(completedInstance != null, "cannot request cancel if we never scheduled any children");
// we are done but the last child didn't complete successfully
if (completedInstance.State != ActivityInstanceState.Closed)
{
context.MarkCanceled();
}
}
return;
}
if (context.IsCancellationRequested)
{
// we're not done and cancel has been requested
context.MarkCanceled();
return;
}
Fx.Assert(node != null, "caller should validate");
FlowNode current = node;
do
{
FlowNode next;
if (ExecuteSingleNode(context, current, out next))
{
current = next;
}
else
{
this.currentNode.Set(context, current.Index);
current = null;
}
}
while (current != null);
}
bool ExecuteSingleNode(NativeActivityContext context, FlowNode node, out FlowNode nextNode)
{
Fx.Assert(node != null, "caller should validate");
FlowStep step = node as FlowStep;
if (step != null)
{
if (this.onStepCompleted == null)
{
this.onStepCompleted = new CompletionCallback(OnStepCompleted);
}
return step.Execute(context, this.onStepCompleted, out nextNode);
}
nextNode = null;
FlowDecision decision = node as FlowDecision;
if (decision != null)
{
if (this.onDecisionCompleted == null)
{
this.onDecisionCompleted = new CompletionCallback(OnDecisionCompleted);
}
return decision.Execute(context, this.onDecisionCompleted);
}
IFlowSwitch switchNode = node as IFlowSwitch;
Fx.Assert(switchNode != null, "unrecognized FlowNode");
return switchNode.Execute(context, this);
}
FlowNode GetCurrentNode(NativeActivityContext context)
{
int index = this.currentNode.Get(context);
FlowNode result = this.allNodes[index];
Fx.Assert(result != null, "corrupt internal state");
return result;
}
void OnStepCompleted(NativeActivityContext context, ActivityInstance completedInstance)
{
FlowStep step = GetCurrentNode(context) as FlowStep;
Fx.Assert(step != null, "corrupt internal state");
FlowNode next = step.Next;
ExecuteNodeChain(context, next, completedInstance);
}
void OnDecisionCompleted(NativeActivityContext context, ActivityInstance completedInstance, bool result)
{
FlowDecision decision = GetCurrentNode(context) as FlowDecision;
Fx.Assert(decision != null, "corrupt internal state");
FlowNode next = result ? decision.True : decision.False;
ExecuteNodeChain(context, next, completedInstance);
}
internal void OnSwitchCompleted(NativeActivityContext context, ActivityInstance completedInstance, T result)
{
IFlowSwitch switchNode = GetCurrentNode(context) as IFlowSwitch;
Fx.Assert(switchNode != null, "corrupt internal state");
FlowNode next = switchNode.GetNextNode(result);
ExecuteNodeChain(context, next, completedInstance);
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BindingCollection.cs
- XslCompiledTransform.cs
- TrackingParameters.cs
- RijndaelManagedTransform.cs
- ECDiffieHellmanCngPublicKey.cs
- SqlBulkCopy.cs
- ImportContext.cs
- VerificationAttribute.cs
- DataTableExtensions.cs
- MemoryFailPoint.cs
- SqlServices.cs
- ResourceContainer.cs
- OpCodes.cs
- FormatterServices.cs
- SqlConnection.cs
- SoapTypeAttribute.cs
- ReadOnlyCollectionBuilder.cs
- CategoryList.cs
- DataGridAddNewRow.cs
- StoreItemCollection.Loader.cs
- EncoderParameters.cs
- Delegate.cs
- SoapHttpTransportImporter.cs
- ECDsaCng.cs
- XPathDescendantIterator.cs
- ByteStreamMessageUtility.cs
- Hashtable.cs
- PersonalizablePropertyEntry.cs
- BrushValueSerializer.cs
- RecognitionEventArgs.cs
- InfoCardRSAPKCS1SignatureFormatter.cs
- FolderLevelBuildProvider.cs
- IconConverter.cs
- FontWeights.cs
- Transform3DGroup.cs
- RtfToXamlLexer.cs
- InvalidComObjectException.cs
- HttpContext.cs
- XslVisitor.cs
- RuleElement.cs
- DocumentOrderComparer.cs
- GiveFeedbackEventArgs.cs
- ActiveXSite.cs
- ClientConvert.cs
- TemplateManager.cs
- TypeInfo.cs
- HttpCookie.cs
- Configuration.cs
- SafeNativeMethods.cs
- ZipFileInfo.cs
- NonParentingControl.cs
- FileEnumerator.cs
- EventMappingSettings.cs
- MeasureItemEvent.cs
- SspiHelper.cs
- ObjectDataSourceEventArgs.cs
- BadImageFormatException.cs
- SaveFileDialogDesigner.cs
- DataReaderContainer.cs
- Panel.cs
- HashMembershipCondition.cs
- COM2IDispatchConverter.cs
- HttpModulesSection.cs
- FileStream.cs
- LineInfo.cs
- DataGridTablesFactory.cs
- ReflectionPermission.cs
- ConnectionConsumerAttribute.cs
- PriorityChain.cs
- OleDbDataReader.cs
- ControlPager.cs
- SynchronizationContext.cs
- CachedTypeface.cs
- ModelFactory.cs
- UnionExpr.cs
- PerformanceCounterPermissionEntryCollection.cs
- TransactedBatchingElement.cs
- XslTransformFileEditor.cs
- CommandDevice.cs
- Stacktrace.cs
- SequenceNumber.cs
- SessionPageStatePersister.cs
- XmlNotation.cs
- InfiniteIntConverter.cs
- ValidatingReaderNodeData.cs
- HiddenFieldDesigner.cs
- Attributes.cs
- AssemblyBuilder.cs
- StyleModeStack.cs
- ItemAutomationPeer.cs
- SessionStateModule.cs
- TextComposition.cs
- Metadata.cs
- CssClassPropertyAttribute.cs
- EnumType.cs
- DrawingAttributes.cs
- XmlIlVisitor.cs
- UrlPath.cs
- ProtectedProviderSettings.cs
- PeerUnsafeNativeCryptMethods.cs