IndependentAnimationStorage.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / Animation / IndependentAnimationStorage.cs / 1305600 / IndependentAnimationStorage.cs

                            // IndependentAnimationStorage.cs 

using MS.Internal;
using System.Collections.Generic;
using System.Diagnostics; 
using System.Windows.Threading;
using System.Windows.Media.Composition; 
 
namespace System.Windows.Media.Animation
{ 
    /// 
    ///
    /// 
    internal abstract class IndependentAnimationStorage : AnimationStorage, DUCE.IResource 
    {
        protected MediaContext.ResourcesUpdatedHandler       _updateResourceHandler; 
        protected DUCE.MultiChannelResource     _duceResource = new DUCE.MultiChannelResource(); 
        private bool _isValid = true;
 
        #region Constructor

        protected IndependentAnimationStorage()
            : base() 
        {
        } 
 
        #endregion
 
        #region Protected

        protected abstract void UpdateResourceCore(DUCE.Channel channel);
 
        //
        // Method which returns the DUCE type of this class. 
        // The base class needs this type when calling CreateOrAddRefOnChannel. 
        // By providing this via a virtual, we avoid a per-instance storage cost.
        // 
        protected abstract DUCE.ResourceType ResourceType { get; }

        #endregion
 
        #region DUCE.IResource
 
        ///  
        /// AddRefOnChannel
        ///  
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel)
        {
            //
            using (CompositionEngineLock.Acquire()) 
            {
#if DEBUG 
                // We assume that a multi-channel resource can only be multi-channel 
                // if it is Frozen and does not have animated properties. In this case we know
                // the target resource has at least one animated property so we expect that this 
                // independently animated property resource will only be added to the channel
                // associated with the MediaContext associated with the target object's Dispatcher.

                DependencyObject d = (DependencyObject)_dependencyObject.Target; 

                // I'm not sure how our target animated DependencyObject would get garbage 
                // collected before we call AddRefOnChannel on one of its animated property 
                // resources, but if it happens it will be a bad thing.
                Debug.Assert(d != null); 

                // Any animated DependencyObject must be associated with a Dispatcher because the
                // AnimationClocks doing the animating must be associated with a Dispatcher.
                Debug.Assert(d.Dispatcher != null); 

                // Make sure the target belongs to this thread 
                Debug.Assert(d.CheckAccess()); 
#endif
 
                if (_duceResource.CreateOrAddRefOnChannel(this, channel, ResourceType))
                {
                    _updateResourceHandler = new MediaContext.ResourcesUpdatedHandler(UpdateResource);
 
                    UpdateResourceCore(channel);
                } 
 
                return _duceResource.GetHandle(channel);
            } 
        }

        /// 
        /// ReleaseOnChannel 
        /// 
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel) 
        { 
            //
            using (CompositionEngineLock.Acquire()) 
            {
                Debug.Assert(_duceResource.IsOnChannel(channel));

                //release from this channel 
                _duceResource.ReleaseOnChannel(channel);
 
                if (!_duceResource.IsOnAnyChannel) 
                {
                    // If this was the last reference on the channel then clear up our state. 
                    // Again, we assume here that if the target DependencyObject is animated that
                    // it will be associated with a Dispatcher and that this animation resource
                    // will also be associated with that Dispatcher's channel.
 
                    DependencyObject d = (DependencyObject)_dependencyObject.Target;
 
                    // DependencyObject shouldn't have been garbage collected before we've 
                    // released all of its property animation resources.
                    Debug.Assert(d != null); 

                    // The target DependencyObject should be associated with a Dispatcher.
                    Debug.Assert(d.Dispatcher != null);
 
                    // Make sure the target belongs to this thread
                    Debug.Assert(d.CheckAccess()); 
 
                    // If we're invalid, that means we've added our _updateResourceHandler to the
                    // MediaContext's ResourcesUpdated event. Since we've been entirely released 
                    // from the channel we can cancel this update by removing the handler.
                    if (!_isValid)
                    {
                        MediaContext mediaContext = MediaContext.From(d.Dispatcher); 
                        mediaContext.ResourcesUpdated -= _updateResourceHandler;
                        _isValid = true; 
                    } 

                    _updateResourceHandler = null; 
                }
            }
        }
 
        /// 
        /// Returns the DUCE.ResourceHandle associated with this resource. 
        ///  
        DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel)
        { 
            DUCE.ResourceHandle handle;

            using (CompositionEngineLock.Acquire())
            { 
                handle = _duceResource.GetHandle(channel);
            } 
 
            return handle;
        } 

        int DUCE.IResource.GetChannelCount()
        {
            return _duceResource.GetChannelCount(); 
        }
 
        DUCE.Channel DUCE.IResource.GetChannel(int index) 
        {
            return _duceResource.GetChannel(index); 
        }

        /// 
        /// This is only implemented by Visual and Visual3D. 
        /// 
        void DUCE.IResource.RemoveChildFromParent(DUCE.IResource parent, DUCE.Channel channel) 
        { 
            throw new NotImplementedException();
        } 

        /// 
        /// This is only implemented by Visual and Visual3D.
        ///  
        DUCE.ResourceHandle DUCE.IResource.Get3DHandle(DUCE.Channel channel)
        { 
            throw new NotImplementedException(); 
        }
 

        #endregion

        #region Private 

        private void UpdateResource(DUCE.Channel channel, bool skipOnChannelCheck) 
        { 
            Debug.Assert(!skipOnChannelCheck || _duceResource.IsOnChannel(channel));
 
            if (skipOnChannelCheck || _duceResource.IsOnChannel(channel))
            {
                UpdateResourceCore(channel);
 
                _isValid = true;
            } 
        } 

        #endregion 

        #region Internal

        ///  
        /// If necessary this method will add an event handler to the MediaContext's
        /// ResourcesUpdated event which will be raised the next time we render. This prevents us 
        /// from updating this animated property value resource more than once per rendered frame. 
        /// 
        internal void InvalidateResource() 
        {
            // If _isValid is false we've already added the event handler for the next frame.
            // If _updateResourceHandler is null we haven't been added to our channel yet so
            //     there's no need to update anything. 
            if (   _isValid
                && _updateResourceHandler != null) 
            { 
                DependencyObject d = (DependencyObject)_dependencyObject.Target;
 
                // If d is null it means the resource that we're animating has been garbage
                // collected and had not fully been released it from its channel. This is
                // highly unlikely and if it occurs something has gone horribly wrong.
                Debug.Assert(d != null); 

                // Just make sure that this resource has been added to the channel associated 
                // with the MediaContext associated with the target object's Dispatcher. 
                Debug.Assert(_duceResource.IsOnAnyChannel);
 
                // Set this flag so that we won't add the event handler to the MediaContext's
                // ResourcesUpdated event again before the next frame is rendered.
                _isValid = false;
 
                MediaContext.CurrentMediaContext.ResourcesUpdated += _updateResourceHandler;
            } 
        } 

        #endregion 

        #region Static helper methods

        internal static DUCE.ResourceHandle GetResourceHandle(DependencyObject d, DependencyProperty dp, DUCE.Channel channel) 
        {
            Debug.Assert(d != null); 
            Debug.Assert(dp != null); 
            Debug.Assert(d is Animatable ? ((Animatable)d).HasAnimatedProperties : true);
 
            IndependentAnimationStorage storage = AnimationStorage.GetStorage(d, dp) as IndependentAnimationStorage;

            if (storage == null)
            { 
                return DUCE.ResourceHandle.Null;
            } 
            else 
            {
                Debug.Assert(storage._duceResource.IsOnChannel(channel)); 

                return ((DUCE.IResource)storage).GetHandle(channel);
            }
        } 

        #endregion 
    } 
}

// 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