Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Media / Animation / Subtree.cs / 1 / Subtree.cs
//------------------------------------------------------------------------------
// Microsoft Windows Client Platform
// Copyright (c) Microsoft Corporation, 2003
//
// File: Subtree.cs
//-----------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using MS.Internal.PresentationCore;
namespace System.Windows.Media.Animation
{
[FriendAccessAllowed] // Built into Core, also used by Framework.
[System.Flags]
internal enum SubtreeFlag
{
Reset = 1,
ProcessRoot = 2,
SkipSubtree = 4,
}
///
/// An object that enumerates the clocks of a subtree of Clock
/// objects.
///
internal struct PrefixSubtreeEnumerator
{
#region Constructor
///
/// Creates an enumerator that iterates over a subtree of clocks
/// in prefix order.
///
///
/// The clock that is the root of the subtree to enumerate.
///
///
/// True to include the root in the enumeration, false otherwise.
///
internal PrefixSubtreeEnumerator(Clock root, bool processRoot)
{
_rootClock = root;
_currentClock = null;
_flags = processRoot ? (SubtreeFlag.Reset | SubtreeFlag.ProcessRoot) : SubtreeFlag.Reset;
}
#endregion // Constructor
#region Methods
///
/// Causes the enumerator to not enumerate the clocks in the subtree rooted
/// at the current clock.
///
internal void SkipSubtree()
{
_flags |= SubtreeFlag.SkipSubtree;
}
///
/// Advances the enumerator to the next element of the collection.
///
///
/// true if the enumerator was successfully advanced to the next element,
/// false if the enumerator has passed the end of the collection.
///
public bool MoveNext()
{
// Get the iteration started in the right place, if we are just starting
if ((_flags & SubtreeFlag.Reset) != 0)
{
// We are just getting started. The first clock is either the root
// or its first child
if ((_flags & SubtreeFlag.ProcessRoot) != 0)
{
// Start with the root
_currentClock = _rootClock;
}
else
{
// Start with the root's first child
if (_rootClock != null)
{
ClockGroup rootClockGroup = _rootClock as ClockGroup;
if (rootClockGroup != null)
{
_currentClock = rootClockGroup.FirstChild;
}
else
{
_currentClock = null;
}
}
}
// Next time we won't be getting started anymore
_flags &= ~SubtreeFlag.Reset;
}
else if (_currentClock != null)
{
// The next clock is possibly the first child of the current clock
ClockGroup currentClockGroup = _currentClock as ClockGroup;
Clock nextClock = (currentClockGroup == null) ? null : currentClockGroup.FirstChild;
// Skip the children if explicitly asked to do so, or if there aren't any
if (((_flags & SubtreeFlag.SkipSubtree) != 0) || (nextClock == null))
{
// Pop back to the first ancestor that has siblings (current clock included). Don't
// go back further than the root of the subtree. At the end of this loop, nextClock
// will point to the proper next clock.
while ((_currentClock != _rootClock) && ((nextClock = _currentClock.NextSibling) == null))
{
_currentClock = _currentClock.InternalParent;
}
// Don't process siblings of the root
if (_currentClock == _rootClock)
{
nextClock = null;
}
_flags &= ~SubtreeFlag.SkipSubtree;
}
_currentClock = nextClock;
}
return _currentClock != null;
}
///
/// Sets the enumerator to its initial position, which is before the
/// first element in the collection.
///
public void Reset()
{
_currentClock = null;
_flags = (_flags & SubtreeFlag.ProcessRoot) | SubtreeFlag.Reset;
}
#endregion // Methods
#region Properties
///
/// Gets the current element in the collection.
///
internal Clock Current
{
get
{
return _currentClock;
}
}
#endregion // Properties
#region Data
private Clock _rootClock;
private Clock _currentClock;
private SubtreeFlag _flags;
#endregion // Data
}
///
/// An object that enumerates the clocks of a subtree of Clock
/// objects.
///
internal struct PostfixSubtreeEnumerator
{
#region Constructor
internal PostfixSubtreeEnumerator(Clock root, bool processRoot)
{
_rootClock = root;
_currentClock = null;
_flags = processRoot ? (SubtreeFlag.Reset | SubtreeFlag.ProcessRoot) : SubtreeFlag.Reset;
}
#endregion // Constructor
#region Methods
///
/// Advances the enumerator to the next element of the collection.
///
///
/// true if the enumerator was successfully advanced to the next element,
/// false if the enumerator has passed the end of the collection.
///
public bool MoveNext()
{
// Get started in the right place
if ((_flags & SubtreeFlag.Reset) != 0)
{
_currentClock = _rootClock;
_flags &= ~SubtreeFlag.Reset;
}
else if (_currentClock == _rootClock)
{
// We last saw the root clock, so we are done
_currentClock = null;
}
// Skip trying to iterate if we are already past the end
if (_currentClock != null)
{
Clock nextClock = _currentClock;
// The next clock is either our next sibling's first leaf
// or, if we don't have a sibling, our parent. If the current
// clock is null, however, we are just starting, so skip this
// move and go straight to the descent part
if ((_currentClock != _rootClock) && (nextClock = _currentClock.NextSibling) == null)
{
// We have no siblings, so the next clock is our parent
_currentClock = _currentClock.InternalParent;
}
else
{
// We have a next sibling or we are the root. In either case, find the
// first leaf clock under this subtree
ClockGroup currentClockGroup;
do
{
_currentClock = nextClock;
currentClockGroup = _currentClock as ClockGroup;
}
while ((nextClock = _currentClock.FirstChild) != null);
}
// Don't process the root, unless specifically requested
if ((_currentClock == _rootClock) && ((_flags & SubtreeFlag.ProcessRoot) == 0))
{
_currentClock = null;
}
}
return _currentClock != null;
}
#endregion // Methods
#region Properties
///
/// Gets the current element in the collection.
///
internal Clock Current
{
get
{
return _currentClock;
}
}
#endregion // Properties
#region Data
private Clock _rootClock;
private Clock _currentClock;
private SubtreeFlag _flags;
#endregion // Data
}
///
/// An object that enumerates the timelines of a tree of Timeline
/// objects.
///
[FriendAccessAllowed] // Built into Core, also used by Framework.
internal struct TimelineTreeEnumerator
{
#region Constructor
///
/// Creates an enumerator that iterates over a subtree of timelines
/// in prefix order.
///
///
/// The timeline that is the root of the subtree to enumerate.
///
///
/// True to include the root in the enumeration, false otherwise.
///
internal TimelineTreeEnumerator(Timeline root, bool processRoot)
{
_rootTimeline = root;
_flags = processRoot ? (SubtreeFlag.Reset | SubtreeFlag.ProcessRoot) : SubtreeFlag.Reset;
// Start with stacks of capacity 10. That's relatively small, yet
// it covers very large trees without reallocation of stack data.
// Note that given the way we use the stacks we need one less entry
// for indices than for timelines, as we don't care what the index
// of the root timeline is.
_indexStack = new Stack(9);
_timelineStack = new Stack(10);
}
#endregion // Constructor
#region Methods
///
/// Causes the enumerator to not enumerate the timelines in the subtree rooted
/// at the current timeline.
///
internal void SkipSubtree()
{
_flags |= SubtreeFlag.SkipSubtree;
}
///
/// Advances the enumerator to the next element of the collection.
///
///
/// true if the enumerator was successfully advanced to the next element,
/// false if the enumerator has passed the end of the collection.
///
public bool MoveNext()
{
TimelineCollection children;
// Get the iteration started in the right place, if we are just starting
if ((_flags & SubtreeFlag.Reset) != 0)
{
// The reset flag takes effect only once
_flags &= ~SubtreeFlag.Reset;
// We are just getting started. The first timeline is the root
_timelineStack.Push(_rootTimeline);
// If we are not supposed to return the root, simply skip it
if ((_flags & SubtreeFlag.ProcessRoot) == 0)
{
MoveNext();
}
}
else if (_timelineStack.Count > 0)
{
// Only TimelineGroup can have children
TimelineGroup timelineGroup = _timelineStack.Peek() as TimelineGroup;
// The next timeline is possibly the first child of the current timeline
// If we have children move to the first one, unless we were
// asked to skip the subtree
if ( ((_flags & SubtreeFlag.SkipSubtree) == 0)
&& timelineGroup != null
&& (children = timelineGroup.Children) != null
&& children.Count > 0
)
{
_timelineStack.Push(children[0]);
_indexStack.Push((int)0);
}
else
{
// The skip subtree flag takes effect only once
_flags &= ~SubtreeFlag.SkipSubtree;
// Move to the first ancestor that has unvisited children,
// then move to the first unvisited child. If we get to
// the root it means we are done.
_timelineStack.Pop();
while (_timelineStack.Count > 0)
{
timelineGroup = _timelineStack.Peek() as TimelineGroup;
// This has to be non-null since we already went down the tree
children = timelineGroup.Children;
int index = (int)_indexStack.Pop() + 1;
if (index < children.Count)
{
// Move to the next child, and we are done
_timelineStack.Push(children[index]);
_indexStack.Push(index);
break;
}
_timelineStack.Pop();
}
}
}
return _timelineStack.Count > 0;
}
#endregion // Methods
#region Properties
///
/// Gets the current element in the collection.
///
internal Timeline Current
{
get
{
return _timelineStack.Peek();
}
}
#endregion // Properties
#region Data
private Timeline _rootTimeline;
private SubtreeFlag _flags;
private Stack _indexStack;
private Stack _timelineStack;
#endregion // Data
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- EnvironmentPermission.cs
- SiteMapNodeItem.cs
- Fonts.cs
- XMLDiffLoader.cs
- TimeSpanSecondsConverter.cs
- DetailsViewInsertEventArgs.cs
- IPAddress.cs
- SiblingIterators.cs
- GridViewRowEventArgs.cs
- GlyphInfoList.cs
- CornerRadius.cs
- CompilerState.cs
- TemplateParser.cs
- SoapServerMessage.cs
- DurableMessageDispatchInspector.cs
- Rect.cs
- XmlNavigatorStack.cs
- SrgsOneOf.cs
- FileRegion.cs
- OracleEncoding.cs
- BindingGraph.cs
- SmiContext.cs
- sqlnorm.cs
- IndentedTextWriter.cs
- Point3DCollection.cs
- SQLBinaryStorage.cs
- SubtreeProcessor.cs
- EditableRegion.cs
- ToolStripSplitStackLayout.cs
- OdbcCommandBuilder.cs
- SettingsBindableAttribute.cs
- XslAstAnalyzer.cs
- WhitespaceSignificantCollectionAttribute.cs
- UriParserTemplates.cs
- DesignerExtenders.cs
- SystemKeyConverter.cs
- NameValueFileSectionHandler.cs
- TypeDependencyAttribute.cs
- SurrogateSelector.cs
- XmlSerializer.cs
- CmsInterop.cs
- DateBoldEvent.cs
- SerializationAttributes.cs
- KnownTypesHelper.cs
- ToolStripDropTargetManager.cs
- UnsafeNativeMethods.cs
- ConfigViewGenerator.cs
- TextBox.cs
- CodePropertyReferenceExpression.cs
- ProgressiveCrcCalculatingStream.cs
- OracleNumber.cs
- DigitShape.cs
- CommandHelpers.cs
- CommandValueSerializer.cs
- PeerApplicationLaunchInfo.cs
- webproxy.cs
- InstanceNormalEvent.cs
- SafeFindHandle.cs
- FixedFlowMap.cs
- WebPartConnectionsDisconnectVerb.cs
- DistinctQueryOperator.cs
- TextChangedEventArgs.cs
- ExceptionValidationRule.cs
- BitmapMetadataBlob.cs
- PasswordDeriveBytes.cs
- PathSegment.cs
- SqlExpander.cs
- SamlDoNotCacheCondition.cs
- SystemFonts.cs
- WebPartHelpVerb.cs
- ToolStripItemRenderEventArgs.cs
- FixedPageAutomationPeer.cs
- SimpleTextLine.cs
- ListItem.cs
- OracleInternalConnection.cs
- MSAANativeProvider.cs
- Util.cs
- DSASignatureFormatter.cs
- ProgressPage.cs
- CodeIndexerExpression.cs
- DataPagerField.cs
- ObjectDataSourceChooseMethodsPanel.cs
- MsmqChannelListenerBase.cs
- TrayIconDesigner.cs
- BindingOperations.cs
- EntitySetRetriever.cs
- NameValuePermission.cs
- PocoPropertyAccessorStrategy.cs
- InternalControlCollection.cs
- formatter.cs
- ZoneButton.cs
- BasicViewGenerator.cs
- QueryOperatorEnumerator.cs
- GACIdentityPermission.cs
- ExtendedProperty.cs
- DayRenderEvent.cs
- BmpBitmapEncoder.cs
- SafeHGlobalHandleCritical.cs
- ListViewGroupItemCollection.cs
- DecoderNLS.cs