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
- ElementUtil.cs
- VectorKeyFrameCollection.cs
- WhitespaceReader.cs
- DateTimeConverter2.cs
- StylusEditingBehavior.cs
- BinaryConverter.cs
- ToolStripLocationCancelEventArgs.cs
- MinimizableAttributeTypeConverter.cs
- IsolatedStorageException.cs
- ColorEditor.cs
- GlyphShapingProperties.cs
- ClientScriptManager.cs
- TriggerBase.cs
- COM2ColorConverter.cs
- WindowsUpDown.cs
- InternalPermissions.cs
- DashStyle.cs
- SmtpDateTime.cs
- DispatchProxy.cs
- DataGridViewAutoSizeModeEventArgs.cs
- GroupBoxRenderer.cs
- NotifyIcon.cs
- VideoDrawing.cs
- ZipIOLocalFileDataDescriptor.cs
- DesignerOptionService.cs
- MDIWindowDialog.cs
- ProcessManager.cs
- OracleTransaction.cs
- CryptoKeySecurity.cs
- KeyFrames.cs
- AssemblyHash.cs
- TimeZone.cs
- SqlCommandAsyncResult.cs
- MasterPageParser.cs
- DragEvent.cs
- ClosableStream.cs
- XmlDictionary.cs
- TypeDescriptorContext.cs
- MenuBase.cs
- UInt64.cs
- MobileListItemCollection.cs
- PropertyItemInternal.cs
- _ScatterGatherBuffers.cs
- StateFinalizationActivity.cs
- AsymmetricSignatureFormatter.cs
- DelegateBodyWriter.cs
- VirtualDirectoryMapping.cs
- TitleStyle.cs
- XmlElementAttribute.cs
- FixedPage.cs
- ContainerParagraph.cs
- PermissionSetTriple.cs
- XmlAttributeHolder.cs
- ToolboxItemAttribute.cs
- EventSetterHandlerConverter.cs
- HtmlTextArea.cs
- TreeNode.cs
- UserPreferenceChangedEventArgs.cs
- CodeArrayCreateExpression.cs
- AsyncDataRequest.cs
- StorageMappingItemLoader.cs
- DefaultValueConverter.cs
- LocationFactory.cs
- CommandLineParser.cs
- StrongName.cs
- ToolStripLabel.cs
- PasswordDeriveBytes.cs
- AsymmetricSignatureFormatter.cs
- RectangleGeometry.cs
- TypeSemantics.cs
- InitializingNewItemEventArgs.cs
- TypeForwardedToAttribute.cs
- PersonalizationAdministration.cs
- PreviewPrintController.cs
- BamlBinaryReader.cs
- GroupItemAutomationPeer.cs
- RowType.cs
- StringSorter.cs
- XmlValidatingReader.cs
- ToolstripProfessionalRenderer.cs
- CalendarDay.cs
- ServiceReference.cs
- ProfileSettingsCollection.cs
- FontUnitConverter.cs
- IPipelineRuntime.cs
- AnonymousIdentificationModule.cs
- ImageDrawing.cs
- XPathParser.cs
- FixedSOMTableCell.cs
- SerializationSectionGroup.cs
- X509ChainElement.cs
- TemplateAction.cs
- Environment.cs
- InfocardExtendedInformationCollection.cs
- Condition.cs
- SHA384.cs
- HandlerBase.cs
- CannotUnloadAppDomainException.cs
- VisualBrush.cs
- EdmFunction.cs