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
- XmlAttribute.cs
- UrlAuthFailedErrorFormatter.cs
- QuaternionAnimation.cs
- DataServiceRequestOfT.cs
- EnumConverter.cs
- SuppressIldasmAttribute.cs
- PersistenceMetadataNamespace.cs
- OpenFileDialog.cs
- webproxy.cs
- InputReport.cs
- CustomLineCap.cs
- OutputCacheProfileCollection.cs
- XmlAttributeOverrides.cs
- BidOverLoads.cs
- SiteMapDataSourceDesigner.cs
- InteropBitmapSource.cs
- HandlerMappingMemo.cs
- KeyedCollection.cs
- XmlSecureResolver.cs
- SqlConnection.cs
- ClientTargetSection.cs
- EventDescriptor.cs
- ResourceDictionary.cs
- CompositeDataBoundControl.cs
- RangeBase.cs
- MemberInfoSerializationHolder.cs
- PassportAuthentication.cs
- HttpListenerPrefixCollection.cs
- BaseValidatorDesigner.cs
- ConnectionsZone.cs
- WebPartDeleteVerb.cs
- OdbcConnectionHandle.cs
- ButtonChrome.cs
- CriticalFinalizerObject.cs
- ClusterSafeNativeMethods.cs
- Panel.cs
- SqlDataSourceQueryEditorForm.cs
- UpdatableGenericsFeature.cs
- DataGridHeaderBorder.cs
- WindowsSlider.cs
- WorkflowControlEndpoint.cs
- PageSetupDialog.cs
- namescope.cs
- QueryStringParameter.cs
- AttributeQuery.cs
- GlobalizationAssembly.cs
- ParallelDesigner.cs
- NameValueSectionHandler.cs
- ToolStripLabel.cs
- ProvidersHelper.cs
- DecimalAverageAggregationOperator.cs
- ExceptionHandler.cs
- ProfileSection.cs
- OleDbConnectionInternal.cs
- Baml2006ReaderFrame.cs
- TemplatedAdorner.cs
- ObjectHandle.cs
- Mutex.cs
- Receive.cs
- MarkupObject.cs
- CapabilitiesPattern.cs
- ObjectStateFormatter.cs
- PolicyVersionConverter.cs
- ZipIOFileItemStream.cs
- DesignerActionKeyboardBehavior.cs
- IPipelineRuntime.cs
- Point4DValueSerializer.cs
- ObjectDataSourceStatusEventArgs.cs
- XmlJsonWriter.cs
- ConfigXmlComment.cs
- TableCell.cs
- Tool.cs
- Button.cs
- ReferencedCollectionType.cs
- FixedHyperLink.cs
- DbConnectionPoolGroupProviderInfo.cs
- TreeViewTemplateSelector.cs
- ApplicationId.cs
- TextParaClient.cs
- HtmlLink.cs
- BodyWriter.cs
- AttachedPropertyBrowsableForTypeAttribute.cs
- ProvidersHelper.cs
- FlagsAttribute.cs
- ChtmlTextWriter.cs
- ZipIOLocalFileBlock.cs
- SrgsToken.cs
- PictureBox.cs
- ControlCollection.cs
- NegationPusher.cs
- SqlClientMetaDataCollectionNames.cs
- CompilerGlobalScopeAttribute.cs
- InfoCardUIAgent.cs
- ChameleonKey.cs
- PropertyItemInternal.cs
- Privilege.cs
- SimpleBitVector32.cs
- Geometry.cs
- DesignerToolStripControlHost.cs
- HttpCookiesSection.cs