AnimationLayer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Media / Animation / AnimationLayer.cs / 1 / AnimationLayer.cs

                            // AnimationLayer.cs 

using System.Collections.Generic;
using System.Diagnostics;
 
namespace System.Windows.Media.Animation
{ 
    internal class AnimationLayer 
    {
        private object _snapshotValue = DependencyProperty.UnsetValue; 
        private IList _animationClocks;
        private AnimationStorage _ownerStorage;
        private EventHandler _removeRequestedHandler;
        private bool _hasStickySnapshotValue; 

        internal AnimationLayer(AnimationStorage ownerStorage) 
        { 
            Debug.Assert(ownerStorage != null);
 
            _ownerStorage = ownerStorage;
            _removeRequestedHandler = new EventHandler(OnRemoveRequested);
        }
 
        internal void ApplyAnimationClocks(
            IList newAnimationClocks, 
            HandoffBehavior handoffBehavior, 
            object defaultDestinationValue)
        { 
            Debug.Assert(
                newAnimationClocks == null
                || (newAnimationClocks.Count > 0
                    && !newAnimationClocks.Contains(null))); 

            if (handoffBehavior == HandoffBehavior.SnapshotAndReplace) 
            { 
                Debug.Assert(defaultDestinationValue != DependencyProperty.UnsetValue,
                    "We need a valid default destination value when peforming a snapshot and replace."); 

                EventHandler handler = new EventHandler(OnCurrentStateInvalidated);

                // If we have a sticky snapshot value, the clock that would have 
                // unstuck it is being replaced, so we need to remove our event
                // handler from that clock. 
                if (_hasStickySnapshotValue) 
                {
                    _animationClocks[0].CurrentStateInvalidated -= handler; 

                    DetachAnimationClocks();
                }
                // Otherwise if we have at least one clock take a new snapshot 
                // value.
                else if (_animationClocks != null) 
                { 
                    _snapshotValue = GetCurrentValue(defaultDestinationValue);
 
                    DetachAnimationClocks();
                }
                // Otherwise we can use the defaultDestinationValue as the
                // new snapshot value. 
                else
                { 
                    _snapshotValue = defaultDestinationValue; 
                }
 
                // If we have a new clock in a stopped state, then the snapshot
                // value will be sticky.
                if (newAnimationClocks != null
                    && newAnimationClocks[0].CurrentState == ClockState.Stopped) 
                {
                    _hasStickySnapshotValue = true; 
                    newAnimationClocks[0].CurrentStateInvalidated += handler; 
                }
                // Otherwise it won't be sticky. 
                else
                {
                    _hasStickySnapshotValue = false;
                } 

                SetAnimationClocks(newAnimationClocks); 
            } 
            else
            { 
                Debug.Assert(handoffBehavior == HandoffBehavior.Compose,
                    "Unhandled handoffBehavior value.");
                Debug.Assert(defaultDestinationValue == DependencyProperty.UnsetValue,
                    "We shouldn't take the time to calculate a default destination value when it isn't needed."); 

                if (newAnimationClocks == null) 
                { 
                    return;
                } 
                else if (_animationClocks == null)
                {
                    SetAnimationClocks(newAnimationClocks);
                } 
                else
                { 
                    AppendAnimationClocks(newAnimationClocks); 
                }
            } 
        }

        private void DetachAnimationClocks()
        { 
            Debug.Assert(_animationClocks != null);
 
            int count = _animationClocks.Count; 

            for (int i = 0; i < count; i++) 
            {
                _ownerStorage.DetachAnimationClock(_animationClocks[i], _removeRequestedHandler);
            }
 
            _animationClocks = null;
        } 
 
        private void SetAnimationClocks(
            IList animationClocks) 
        {
            Debug.Assert(animationClocks != null);
            Debug.Assert(animationClocks.Count > 0);
            Debug.Assert(!animationClocks.Contains(null)); 
            Debug.Assert(_animationClocks == null);
 
            _animationClocks = animationClocks; 

            int count = animationClocks.Count; 

            for (int i = 0; i < count; i++)
            {
                _ownerStorage.AttachAnimationClock(animationClocks[i], _removeRequestedHandler); 
            }
        } 
 
        private void OnCurrentStateInvalidated(object sender, EventArgs args)
        { 
            Debug.Assert(_hasStickySnapshotValue,
                "_hasStickySnapshotValue should be set to true if OnCurrentStateInvalidated has been called.");

            _hasStickySnapshotValue = false; 

            ((AnimationClock)sender).CurrentStateInvalidated -= new EventHandler(OnCurrentStateInvalidated); 
        } 

        private void OnRemoveRequested(object sender, EventArgs args) 
        {
            Debug.Assert(_animationClocks != null
                         && _animationClocks.Count > 0,
                "An AnimationClock no longer associated with a property should not have a RemoveRequested event handler."); 

            AnimationClock animationClock = (AnimationClock)sender; 
 
            int index = _animationClocks.IndexOf(animationClock);
 
            Debug.Assert(index >= 0,
                "An AnimationClock no longer associated with a property should not have a RemoveRequested event handler.");

            if (_hasStickySnapshotValue 
                && index == 0)
            { 
                _animationClocks[0].CurrentStateInvalidated -= new EventHandler(OnCurrentStateInvalidated); 
                _hasStickySnapshotValue = false;
            } 

            _animationClocks.RemoveAt(index);

            _ownerStorage.DetachAnimationClock(animationClock, _removeRequestedHandler); 

            AnimationStorage tmpOwnerStorage = _ownerStorage; 
 
            if (_animationClocks.Count == 0)
            { 
                _animationClocks = null;
                _snapshotValue = DependencyProperty.UnsetValue;
                _ownerStorage.RemoveLayer(this);
                _ownerStorage = null; 
            }
 
            // _ownerStorage may be null here. 

            tmpOwnerStorage.WritePostscript(); 
        }

        private void AppendAnimationClocks(
            IList newAnimationClocks) 
        {
            Debug.Assert(newAnimationClocks != null); 
            Debug.Assert(newAnimationClocks.Count > 0); 
            Debug.Assert(!newAnimationClocks.Contains(null));
            // _animationClocks may be null or non-null here. 

            int newClocksCount = newAnimationClocks.Count;
            List animationClockList = _animationClocks as List;
 
            // If _animationClocks is not a List then make it one.
            if (animationClockList == null) 
            { 
                int oldClocksCount = (_animationClocks == null) ? 0 : _animationClocks.Count;
 
                animationClockList = new List(oldClocksCount + newClocksCount);

                for (int i = 0; i < oldClocksCount; i++)
                { 
                    animationClockList.Add(_animationClocks[i]);
                } 
 
                _animationClocks = animationClockList;
            } 

            for (int i = 0; i < newClocksCount; i++)
            {
                AnimationClock clock = newAnimationClocks[i]; 

                animationClockList.Add(clock); 
                _ownerStorage.AttachAnimationClock(clock, _removeRequestedHandler); 
            }
        } 

        internal object GetCurrentValue(
            object defaultDestinationValue)
        { 
            Debug.Assert(defaultDestinationValue != DependencyProperty.UnsetValue);
 
            // We have a sticky snapshot value if changes have been made to the 
            // animations in this layer since the last tick. This flag will be
            // unset when the next tick starts. 
            //
            // Since CurrentTimeInvaliated is raised before CurrentStateInvalidated
            // we need to check the state of the first clock as well to avoid
            // potential first frame issues. In this case _hasStickySnapshotValue 
            // will be updated to false shortly.
            if (   _hasStickySnapshotValue 
                && _animationClocks[0].CurrentState == ClockState.Stopped) 
            {
                return _snapshotValue; 
            }

            // This layer just contains a snapshot value or a fill value after
            // all the clocks have been completed. 
            if (_animationClocks == null)
            { 
                Debug.Assert(_snapshotValue != DependencyProperty.UnsetValue); 

                // In this case, we're using _snapshotValue to store the value, 
                // but the value here does not represent the snapshotValue. It
                // represents the fill value of an animation clock that has been
                // removed for performance reason because we know it will never
                // be restarted. 

                return _snapshotValue; 
            } 

            object currentLayerValue = _snapshotValue; 
            bool hasUnstoppedClocks = false;

            if (currentLayerValue == DependencyProperty.UnsetValue)
            { 
                currentLayerValue = defaultDestinationValue;
            } 
 
            int count = _animationClocks.Count;
 
            Debug.Assert(count > 0);

            for (int i = 0; i < count; i++)
            { 
                AnimationClock clock = _animationClocks[i];
 
                if (clock.CurrentState != ClockState.Stopped) 
                {
                    hasUnstoppedClocks = true; 

                    currentLayerValue = clock.GetCurrentValue(
                        currentLayerValue,
                        defaultDestinationValue); 
                }
            } 
 
            if (hasUnstoppedClocks)
            { 
                return currentLayerValue;
            }
            else
            { 
                return defaultDestinationValue;
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK