internal static AnimationStorage EnsureStorage(
            DependencyObject d,
            DependencyProperty dp)
        {
            FrugalMap animatedPropertyMap = AnimatedPropertyMapField.GetValue(d);
            object    currentStorage      = animatedPropertyMap[dp.GlobalIndex];

            if (currentStorage == DependencyProperty.UnsetValue)
            {
                return(CreateStorage(d, dp));
            }
            else
            {
                return((AnimationStorage)currentStorage);
            }
        }
Ejemplo n.º 2
0
        internal virtual void ReleaseOnChannelAnimations(DUCE.Channel channel)
        {
            if (IAnimatable_HasAnimatedProperties)
            {
                FrugalMap animatedPropertiesMap = AnimationStorage.GetAnimatedPropertiesMap(this);

                Debug.Assert(animatedPropertiesMap.Count > 0);

                for (int i = 0; i < animatedPropertiesMap.Count; i++)
                {
                    Int32  dpGlobalIndex;
                    Object storageObject;

                    animatedPropertiesMap.GetKeyValuePair(i, out dpGlobalIndex, out storageObject);

                    DUCE.IResource storage = storageObject as DUCE.IResource;

                    if (storage != null)
                    {
                        storage.ReleaseOnChannel(channel);
                    }
                }
            }
        }
 /// <summary>
 ///     Constructor for EventHandlersStore
 /// </summary>
 public EventHandlersStore()
 {
     _entries = new FrugalMap();
 }
        /// <summary>
        /// This should be called at the end of any method that alters the
        /// storage in any way.  This method will make sure the peer dp is
        /// set correctly and notify Animatables if something changes.
        /// </summary>
        internal void WritePostscript()
        {
            DependencyObject d = (DependencyObject)_dependencyObject.Target;

            if (d == null)
            {
                return;
            }

            FrugalMap animatedPropertyMap = AnimatedPropertyMapField.GetValue(d);

            if (animatedPropertyMap.Count == 0 ||
                animatedPropertyMap[_dependencyProperty.GlobalIndex] == DependencyProperty.UnsetValue)
            {
                if (!IsEmpty)
                {
                    // This is kind of tricky:
                    //
                    // Because FrugalMap is a struct instead of a class, we must
                    // be sure to add this AnimationStorage to the map before
                    // setting the FrugalMap into the UncommonField storage. If
                    // we don't and the FrugalMap is empty then an empty FrugalMap
                    // will be set into the UncommonField storage. If we were to
                    // then add our AnimationStorage to the local FrugalMap, it
                    // would only allocate its own internal storage at that point
                    // which would not apply to the FrugalMap we set into the
                    // UncommonField storage. Once a FrugalMap has allocated its
                    // internal storage, though, that storage is copied with the
                    // FrugalMap. This is what will happen when we add our
                    // AnimationStorage to the FrugalMap first as we do below:

                    animatedPropertyMap[_dependencyProperty.GlobalIndex] = this;

                    // Since FrugalMap is a struct and adding a new value to it
                    // may re-allocate the storage, we need to set this value
                    // each time we make a change to the map.

                    AnimatedPropertyMapField.SetValue(d, animatedPropertyMap);

                    if (animatedPropertyMap.Count == 1)
                    {
                        d.IAnimatable_HasAnimatedProperties = true;
                    }

                    // If this the target is an Animatable we'll need to
                    // invalidate it so that the animation resource for this
                    // newly animated property will be passed across to the UCE.
                    Animatable a = d as Animatable;

                    if (a != null)
                    {
                        a.RegisterForAsyncUpdateResource();
                    }

                    // If this AnimationStorage is a resource, add it to the
                    // channel now.
                    DUCE.IResource animationResource = this as DUCE.IResource;

                    if (animationResource != null)
                    {
                        DUCE.IResource targetResource = d as DUCE.IResource;

                        if (targetResource != null)
                        {
                            using (CompositionEngineLock.Acquire())
                            {
                                int channelCount = targetResource.GetChannelCount();

                                for (int i = 0; i < channelCount; i++)
                                {
                                    DUCE.Channel channel = targetResource.GetChannel(i);
                                    if (!targetResource.GetHandle(channel).IsNull)
                                    {
                                        animationResource.AddRefOnChannel(channel);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                Debug.Assert(animatedPropertyMap.Count > 0);
                Debug.Assert(animatedPropertyMap[_dependencyProperty.GlobalIndex] != DependencyProperty.UnsetValue);

                if (IsEmpty)
                {
                    // If this AnimationStorage is a resource, release it from
                    // the channel now.
                    DUCE.IResource animationResource = this as DUCE.IResource;

                    if (animationResource != null)
                    {
                        DUCE.IResource targetResource = d as DUCE.IResource;

                        if (targetResource != null)
                        {
                            using (CompositionEngineLock.Acquire())
                            {
                                int channelCount = targetResource.GetChannelCount();

                                for (int i = 0; i < channelCount; i++)
                                {
                                    DUCE.Channel channel = targetResource.GetChannel(i);
                                    if (!targetResource.GetHandle(channel).IsNull)
                                    {
                                        animationResource.ReleaseOnChannel(channel);
                                    }
                                }
                            }
                        }
                    }

                    // If this the target is an Animatable we'll need to
                    // invalidate it so that the animation resource for this
                    // no longer animated property will no longer be passed
                    // across to the UCE.
                    Animatable a = d as Animatable;

                    if (a != null)
                    {
                        a.RegisterForAsyncUpdateResource();
                    }

                    animatedPropertyMap[_dependencyProperty.GlobalIndex] = DependencyProperty.UnsetValue;

                    if (animatedPropertyMap.Count == 0)
                    {
                        AnimatedPropertyMapField.ClearValue(d);

                        d.IAnimatable_HasAnimatedProperties = false;
                    }
                    else
                    {
                        AnimatedPropertyMapField.SetValue(d, animatedPropertyMap);
                    }

                    // We've removed animation storage for this DP, so if we were storing the local
                    // base value here then it has to go back to its non-animated storage spot.
                    if (_baseValue != DependencyProperty.UnsetValue)
                    {
                        d.SetValue(_dependencyProperty, _baseValue);
                    }
                }
            }

            // recompute animated value
            d.InvalidateProperty(_dependencyProperty);
        }