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
- StylusButton.cs
- LineSegment.cs
- AutomationIdentifierGuids.cs
- ReadOnlyDictionary.cs
- ProxyWebPart.cs
- DrawingBrush.cs
- FixedBufferAttribute.cs
- SiteMapPath.cs
- SurrogateSelector.cs
- XmlUnspecifiedAttribute.cs
- GlobalizationAssembly.cs
- SchemaName.cs
- ObjectListFieldCollection.cs
- LinearQuaternionKeyFrame.cs
- WizardSideBarListControlItem.cs
- ProviderConnectionPointCollection.cs
- DependencyPropertyValueSerializer.cs
- SQLInt16Storage.cs
- HttpModuleCollection.cs
- JavaScriptSerializer.cs
- AvTrace.cs
- SimpleColumnProvider.cs
- PathParser.cs
- EventItfInfo.cs
- OpCopier.cs
- Parameter.cs
- BrushConverter.cs
- XmlTextWriter.cs
- Int32Converter.cs
- TypeDependencyAttribute.cs
- BaseTemplatedMobileComponentEditor.cs
- ColorPalette.cs
- Rule.cs
- JsonSerializer.cs
- DesignerFrame.cs
- ErrorReporting.cs
- EntityDataSourceStatementEditorForm.cs
- HttpChannelBindingToken.cs
- DispatchChannelSink.cs
- HttpModuleActionCollection.cs
- CheckBoxPopupAdapter.cs
- DbConnectionPoolCounters.cs
- WebPartDisplayModeCancelEventArgs.cs
- MetadataProperty.cs
- ParameterToken.cs
- WeakReference.cs
- UserControl.cs
- SecurityRuntime.cs
- Literal.cs
- CodeChecksumPragma.cs
- FilteredDataSetHelper.cs
- ConstructorNeedsTagAttribute.cs
- ParenExpr.cs
- GridViewRowCollection.cs
- MailWebEventProvider.cs
- TraceContextEventArgs.cs
- ObjectStateManager.cs
- SimpleHandlerFactory.cs
- OpenTypeLayoutCache.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- JsonByteArrayDataContract.cs
- PasswordRecovery.cs
- FrugalList.cs
- LayoutExceptionEventArgs.cs
- ContextStaticAttribute.cs
- AnonymousIdentificationModule.cs
- RelatedView.cs
- LogLogRecord.cs
- Lazy.cs
- COM2ComponentEditor.cs
- Internal.cs
- ReaderContextStackData.cs
- QueryExpression.cs
- WindowsRichEdit.cs
- ReliableMessagingVersionConverter.cs
- RoleService.cs
- Membership.cs
- WebPartEditorCancelVerb.cs
- ConfigXmlCDataSection.cs
- ListChunk.cs
- COM2Properties.cs
- ScriptManagerProxy.cs
- FileVersion.cs
- FloatUtil.cs
- ObjectManager.cs
- ThumbAutomationPeer.cs
- X509Extension.cs
- DataGridViewLinkColumn.cs
- QueryExpr.cs
- ExpressionNode.cs
- HuffCodec.cs
- Grant.cs
- DocumentNUp.cs
- LogicalExpr.cs
- HttpConfigurationSystem.cs
- DockAndAnchorLayout.cs
- SingleConverter.cs
- RSAPKCS1SignatureFormatter.cs
- Vector3D.cs
- FullTextBreakpoint.cs