Code:
/ 4.0 / 4.0 / 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. // 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PropertyItemInternal.cs
- ColorConvertedBitmap.cs
- TextCompositionManager.cs
- PageThemeBuildProvider.cs
- WebPartsPersonalizationAuthorization.cs
- AncestorChangedEventArgs.cs
- SystemIcmpV4Statistics.cs
- DataMemberAttribute.cs
- StyleHelper.cs
- WindowsFormsSynchronizationContext.cs
- safex509handles.cs
- UserPreferenceChangingEventArgs.cs
- RemotingService.cs
- WinEventHandler.cs
- DocumentAutomationPeer.cs
- LongValidatorAttribute.cs
- brushes.cs
- ProviderMetadataCachedInformation.cs
- TableMethodGenerator.cs
- TileBrush.cs
- AppDomainCompilerProxy.cs
- CustomLineCap.cs
- Package.cs
- QueryExecutionOption.cs
- PersonalizationProviderCollection.cs
- MenuEventArgs.cs
- BitmapDecoder.cs
- OledbConnectionStringbuilder.cs
- ThreadExceptionEvent.cs
- ProcessModule.cs
- ToolboxComponentsCreatedEventArgs.cs
- _CacheStreams.cs
- PtsHost.cs
- ResourceAssociationType.cs
- Int64AnimationBase.cs
- DefaultBinder.cs
- TrackingCondition.cs
- ResourceDefaultValueAttribute.cs
- PropertyInfoSet.cs
- SEHException.cs
- IPGlobalProperties.cs
- TiffBitmapEncoder.cs
- TabPage.cs
- RootCodeDomSerializer.cs
- DataGridItemCollection.cs
- ListViewGroupItemCollection.cs
- WebPartPersonalization.cs
- GeneralTransform2DTo3D.cs
- TemplateNodeContextMenu.cs
- LocalizabilityAttribute.cs
- GeometryConverter.cs
- RelationshipManager.cs
- relpropertyhelper.cs
- __Filters.cs
- XmlHierarchicalDataSourceView.cs
- SyndicationFeed.cs
- Utils.cs
- ImageSourceConverter.cs
- HttpCookiesSection.cs
- DbConnectionPoolOptions.cs
- X509Chain.cs
- ObjectComplexPropertyMapping.cs
- SuppressMessageAttribute.cs
- XmlWhitespace.cs
- FlowDocumentReaderAutomationPeer.cs
- XmlSchemaSimpleTypeList.cs
- SingleStorage.cs
- _ConnectStream.cs
- Size.cs
- CodeTypeConstructor.cs
- PointAnimationClockResource.cs
- SqlMultiplexer.cs
- SystemResourceHost.cs
- IsolatedStorageFileStream.cs
- EmptyEnumerator.cs
- WebResponse.cs
- ExtensionWindowResizeGrip.cs
- XmlNodeComparer.cs
- AlphabeticalEnumConverter.cs
- NativeMethods.cs
- SizeConverter.cs
- MessageQueuePermissionAttribute.cs
- LineGeometry.cs
- GroupBoxAutomationPeer.cs
- ApplicationServiceHelper.cs
- PerfCounters.cs
- DataKey.cs
- EntityStoreSchemaGenerator.cs
- CompModSwitches.cs
- StylusButtonCollection.cs
- StrokeNodeEnumerator.cs
- NonBatchDirectoryCompiler.cs
- MatrixAnimationUsingPath.cs
- UrlPath.cs
- PatternMatcher.cs
- MatrixCamera.cs
- XPathNode.cs
- ColumnWidthChangingEvent.cs
- UniqueID.cs
- MenuCommands.cs