Beispiel #1
0
        public static T GetValue <T>(this AnimationInstance <T> animationInstance, T defaultSource, T defaultTarget)
        {
            T result = default(T);

            animationInstance.GetValue(ref defaultSource, ref defaultTarget, ref result);
            return(result);
        }
Beispiel #2
0
    /// <summary>
    /// Unregisters the specified animation instance.
    /// </summary>
    /// <param name="animationInstance">The animation instance.</param>
    /// <remarks>
    /// <para>
    /// This method removes the specified animation tree from the animation system. If 
    /// <see cref="AnimationInstance.AutoRecycleEnabled"/> is set on the root node of the animation 
    /// tree, then all instances will be recycled.
    /// </para>
    /// <para>
    /// Adding and removing animation instances is usually controlled by 
    /// <see cref="AnimationTransition"/> instances.
    /// </para>
    /// </remarks>
    /// <exception cref="ArgumentException">
    /// Cannot remove <paramref name="animationInstance"/> from the animation system. The animation 
    /// instance is not a root instance.
    /// </exception>
    internal void Remove(AnimationInstance animationInstance)
    {
      if (!animationInstance.IsRoot)
        throw new ArgumentException("Cannot remove animation instance from animation system because it is not the root instance.");

      // Remove animation instance.
      bool removed = _rootInstances.Remove(animationInstance);
      if (removed)
      {
        // Remove animation transitions, if any.
        StopTransitions(animationInstance);

        // Stop all secondary animations.
        animationInstance.StopSecondaryAnimations(this);

        // Remove animations from composition chains.
        animationInstance.RemoveFromCompositionChains(this);

        // Note: The instances are not unassigned from the properties.
        // Animations can be restart when using an animation controller.
        //animationInstance.Unassign();

        // Reset animation time (State = Stopped).
        animationInstance.Time = null;

        // Recycle instance, if no longer needed.
        if (animationInstance.AutoRecycleEnabled)
        {
          // If the instance is in the completedInstances list, we need to wait 
          // until the Completed events were fired in ApplyAnimations().
          if (!_completedInstances.Contains(animationInstance))
            animationInstance.Recycle();
        }
      }
    }
Beispiel #3
0
    /// <summary>
    /// Starts the animations using the specified transition.
    /// </summary>
    /// <param name="animationInstance">The animation instance.</param>
    /// <param name="transition">
    /// The animation transition. (Can be <see langword="null"/>, in which case
    /// <see cref="AnimationTransitions.SnapshotAndReplace()"/> will be used.)
    /// </param>
    internal void StartAnimation(AnimationInstance animationInstance, AnimationTransition transition)
    {
      if (transition == null)
        transition = AnimationTransitions.SnapshotAndReplace();

      transition.AnimationInstance = animationInstance;
      Add(transition);
    }
    /// <summary>
    /// Determines the index of a specific item in the <see cref="IList{T}"/>.
    /// </summary>
    /// <param name="item">
    /// The object to locate in the <see cref="IList{T}"/>.
    /// </param>
    /// <returns>
    /// The index of <paramref name="item"/> if found in the list; otherwise, -1.
    /// </returns>
    /// <exception cref="ArgumentException">
    /// <paramref name="item"/> is not of type <see cref="AnimationInstance{T}"/>.
    /// </exception>
    int IList<AnimationInstance>.IndexOf(AnimationInstance item)
    {
      var animationInstance = item as AnimationInstance<T>;
      if (animationInstance == null)
        return -1;

      return IndexOf(animationInstance);
    }
Beispiel #5
0
        /// <inheritdoc/>
        public AnimationInstance CreateInstance()
        {
            var animationInstance = AnimationInstance.Create(this);

            animationInstance.Children.Add(Timeline.CreateInstance());

            return(animationInstance);
        }
    /// <summary>
    /// Inserts an item to the <see cref="IList{T}"/> at the specified index.
    /// </summary>
    /// <param name="index">
    /// The zero-based index at which <paramref name="item"/> should be inserted.
    /// </param>
    /// <param name="item">
    /// The object to insert into the <see cref="IList{T}"/>.
    /// </param>
    /// <exception cref="ArgumentOutOfRangeException">
    /// <paramref name="index"/> is not a valid index in the <see cref="IList{T}"/>.
    /// </exception>
    /// <exception cref="NotSupportedException">
    /// The <see cref="IList{T}"/> is read-only.
    /// </exception>
    /// <exception cref="ArgumentException">
    /// <paramref name="item"/> is not of type <see cref="AnimationInstance{T}"/>.
    /// </exception>
    void IList<AnimationInstance>.Insert(int index, AnimationInstance item)
    {
      var animationInstance = item as AnimationInstance<T>;
      if (animationInstance == null)
        throw new ArgumentException("Cannot add animation instance to animation composition chain. The instance is not of the correct type.", "item");

      Insert(index, animationInstance);
    }
    /// <summary>
    /// Determines whether the <see cref="ICollection{T}"/> contains a specific value.
    /// </summary>
    /// <param name="item">The object to locate in the <see cref="ICollection{T}"/>.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="item"/> is found in the 
    /// <see cref="ICollection{T}"/>; otherwise, <see langword="false"/>.
    /// </returns>
    bool ICollection<AnimationInstance>.Contains(AnimationInstance item)
    {
      var animationInstance = item as AnimationInstance<T>;
      if (animationInstance == null)
        return false;

      return Contains(animationInstance);
    }
    /// <summary>
    /// Removes the first occurrence of a specific object from the <see cref="ICollection{T}"/>.
    /// </summary>
    /// <param name="item">The object to remove from the <see cref="ICollection{T}"/>.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="item"/> was successfully removed from the 
    /// <see cref="ICollection{T}"/>; otherwise, <see langword="false"/>. This method also returns 
    /// <see langword="false"/> if <paramref name="item"/> is not found in the original 
    /// <see cref="ICollection{T}"/>.
    /// </returns>
    bool ICollection<AnimationInstance>.Remove(AnimationInstance item)
    {
      var animationInstance = item as AnimationInstance<T>;
      if (animationInstance == null)
        return false;

      return Remove(animationInstance);
    }
    /// <summary>
    /// Adds an item to the <see cref="ICollection{T}"/>.
    /// </summary>
    /// <param name="item">
    /// The object to add to the <see cref="ICollection{T}"/>.
    /// </param>
    /// <exception cref="ArgumentException">
    /// <paramref name="item"/> is not of type <see cref="AnimationInstance{T}"/>.
    /// </exception>
    void ICollection<AnimationInstance>.Add(AnimationInstance item)
    {
      var animationInstance = item as AnimationInstance<T>;
      if (animationInstance == null)
        throw new ArgumentException("Cannot add animation instance to animation composition chain. The instance is not of the correct type.", "item");

      Add(animationInstance);
    }
Beispiel #10
0
        /// <summary>
        /// Gradually replaces the specified animation with the new animation. The new animation fades
        /// in over the specified duration. After this duration the previous animation is stopped and
        /// removed from the animation system.
        /// </summary>
        /// <param name="previousAnimation">The animation that should be replaced.</param>
        /// <param name="fadeInDuration">The duration over which the new animation fades in.</param>
        /// <returns>The <see cref="AnimationTransition"/>.</returns>
        public static AnimationTransition Replace(AnimationInstance previousAnimation, TimeSpan fadeInDuration)
        {
            if (fadeInDuration > TimeSpan.Zero)
            {
                return(new FadeInAndReplaceTransition(previousAnimation, fadeInDuration));
            }

            return(new ReplaceTransition(previousAnimation));
        }
Beispiel #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AnimationController"/> struct.
        /// </summary>
        internal AnimationController(AnimationManager animationManager, AnimationInstance animationInstance)
        {
            Debug.Assert(animationManager != null, "The animation system is null.");
            Debug.Assert(animationInstance != null, "The animation instance is null.");
            Debug.Assert(animationInstance.RunCount > 0, "The animation instance has an invalid RunCount.");

            _id = animationInstance.RunCount;
            _animationManager  = animationManager;
            _animationInstance = animationInstance;
        }
Beispiel #12
0
        /// <inheritdoc/>
        public AnimationInstance CreateInstance()
        {
            var animationInstance = AnimationInstance.Create(this);

            foreach (var timeline in _timelines)
            {
                animationInstance.Children.Add(timeline.CreateInstance());
            }

            return(animationInstance);
        }
Beispiel #13
0
    /// <summary>
    /// Removes the animation transitions controlling the given animation instance.
    /// </summary>
    /// <param name="animationInstance">The animation instance.</param>
    private void StopTransitions(AnimationInstance animationInstance)
    {
      for (int i = _transitions.Count - 1; i >= 0; i--)
      {
        if (i >= _transitions.Count)
        {
          // Multiple transitions were removed in the previous iteration.
          // --> Skip index.
          continue;
        }

        var transition = _transitions[i];
        if (transition.AnimationInstance == animationInstance)
          Remove(transition);
      }
    }
Beispiel #14
0
    /// <summary>
    /// Removes all animations before the specified animation.
    /// </summary>
    /// <param name="animationInstance">The animation instance.</param>
    internal void RemoveBefore(AnimationInstance animationInstance)
    {
      Debug.Assert(animationInstance.IsRoot, "The animation instance in RemoveBefore needs to be a root instance.");
      Debug.Assert(_tempProperties.Count == 0, "Temporary list of animatable properties has not been reset.");
      Debug.Assert(_tempInstances.Count == 0, "Temporary list of animation instances has not been reset.");

      // Get all animated properties.
      animationInstance.GetAssignedProperties(_tempProperties);

      // Collect all animation instances before animationInstance.
      foreach (var property in _tempProperties)
      {
        if (property == null)
          continue;

        int index;
        IAnimationCompositionChain compositionChain;
        _compositionChains.Get(property, out index, out compositionChain);

        if (compositionChain == null)
          continue;

        var numberOfInstances = compositionChain.Count;
        for (int i = 0; i < numberOfInstances; i++)
        {
          var instance = compositionChain[i];
          var rootInstance = instance.GetRoot();
          if (rootInstance == animationInstance)
          {
            // Break inner loop, continue with next composition chain.
            break;
          }

          if (!_tempInstances.Contains(rootInstance))
            _tempInstances.Add(rootInstance);
        }
      }

      // Stop the found animation instances.
      foreach (var oldInstance in _tempInstances)
        Remove(oldInstance);

      _tempProperties.Clear();
      _tempInstances.Clear();
    }
Beispiel #15
0
    /// <summary>
    /// Registers the specified animation instance.
    /// </summary>
    /// <param name="animationInstance">The animation instance.</param>
    /// <param name="handoffBehavior">
    /// A value indicating how the new animations interact with existing ones.
    /// </param>
    /// <param name="previousInstance">
    /// Optional: The animation instance after which <paramref name="animationInstance"/> will be 
    /// added in the animation composition chain. If set to <see langword="null"/> 
    /// <paramref name="animationInstance"/> will be appended at the end of the composition chain. 
    /// This parameter is only relevant when <paramref name="handoffBehavior"/> is 
    /// <see cref="HandoffBehavior.Compose"/>. 
    /// </param>
    /// <remarks>
    /// <para>
    /// This method adds the specified animation tree (<paramref name="animationInstance"/> and all
    /// of its children) to the animation system. The animation system will from now on
    /// automatically advance and update the animations.
    /// </para>
    /// <para>
    /// Adding and removing animation instances is usually controlled by 
    /// <see cref="AnimationTransition"/> instances.
    /// </para>
    /// </remarks>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="animationInstance" /> is <see langword="null"/>.
    /// </exception>
    /// <exception cref="ArgumentException">
    /// Cannot add <paramref name="animationInstance"/> to animation system. The animation instance 
    /// is already registered, or it is not a root instance.
    /// </exception>
    internal void Add(AnimationInstance animationInstance, HandoffBehavior handoffBehavior, AnimationInstance previousInstance)
    {
      if (animationInstance == null)
        throw new ArgumentNullException("animationInstance");
      if (_rootInstances.Contains(animationInstance))        // TODO: This is slow if there are many animation instances!
        throw new ArgumentException("Cannot add animation instance to animation system. The animation instance is already registered.");
      if (!animationInstance.IsRoot)
        throw new ArgumentException("Cannot add animation instance to animation system because it is not a root instance. You need to disconnect the instance from its parent first.");

      _rootInstances.Add(animationInstance);

      // Normally, the time is NaN and starts to run now. (Unless the user has set a custom 
      // time value.)
      if (animationInstance.Time == null)
        animationInstance.Time = TimeSpan.Zero;

      animationInstance.AddToCompositionChains(this, handoffBehavior, previousInstance);
    }
Beispiel #16
0
        /// <summary>
        /// Resets this animation instance.
        /// </summary>
        internal void Reset()
        {
            Debug.Assert(SpeedProperty.IsAnimated == false, "The speed ratio is still animated. Make sure that all animations are stopped before recycling an animation instance!");
            Debug.Assert(WeightProperty.IsAnimated == false, "The animation weight is still animated. Make sure that all animations are stopped before recycling an animation instance!");
            Debug.Assert(State == AnimationState.Stopped, "Animation instance is still running.");

            _animation          = null;
            _autoRecycleEnabled = false;
            _isPaused           = false;
            _isStateValid       = false;
            _parent             = null;
            _state = AnimationState.Stopped;
            _time  = null;
            _speedProperty.Value  = 1.0f;
            _weightProperty.Value = 1.0f;
            _children.Clear();
            Completed = null;

            // The animation instance requires a new ID: Increment RunCount.
            _runCount++;
        }
Beispiel #17
0
 /// <summary>
 /// Replaces the specified animation with the new animation. The new animation takes effect
 /// immediately. The previous animation is stopped and removed from the animation system.
 /// </summary>
 /// <param name="previousAnimation">The animation that should be replaced.</param>
 /// <returns>The <see cref="AnimationTransition"/>.</returns>
 public static AnimationTransition Replace(AnimationInstance previousAnimation)
 {
     return(new ReplaceTransition(previousAnimation));
 }
Beispiel #18
0
 /// <summary>
 /// Throws an <see cref="InvalidOperationException"/>.
 /// </summary>
 /// <param name="index">
 /// The zero-based index at which <paramref name="child"/> should be inserted.
 /// </param>
 /// <param name="child">The object to insert.</param>
 /// <exception cref="InvalidOperationException">
 /// Cannot add animation instance. The current animation instance cannot have children.
 /// </exception>
 protected override void InsertItem(int index, AnimationInstance child)
 {
     throw new InvalidOperationException("Cannot add animation instance. The current animation instance cannot have children.");
 }
Beispiel #19
0
 /// <inheritdoc/>
 public AnimationInstance CreateInstance()
 {
     return(AnimationInstance <T> .Create(this));
 }
Beispiel #20
0
 /// <summary>
 /// Combines the new animation with existing animations by inserting the new animation after the
 /// specified animation into the composition chains. The new animation takes effect immediately.
 /// </summary>
 /// <param name="previousAnimation">
 /// The animation after which the new animation should be added.
 /// </param>
 /// <returns>The <see cref="AnimationTransition"/>.</returns>
 public static AnimationTransition Compose(AnimationInstance previousAnimation)
 {
     return(new ComposeTransition(previousAnimation));
 }
Beispiel #21
0
 /// <summary>
 /// Applies this animation tree to the assigned properties.
 /// </summary>
 /// <param name="animationManager">The <see cref="AnimationManager"/>.</param>
 /// <param name="handoffBehavior">
 /// A value indicating how the new animations interact with existing ones.
 /// </param>
 /// <param name="previousInstance">
 /// Optional: The animation instance after which this animation instance will be added in the
 /// animation composition chain. If set to <see langword="null"/> this animation instance will
 /// be appended at the end of the composition chain. This parameter is only relevant when
 /// <paramref name="handoffBehavior"/> is <see cref="HandoffBehavior.Compose"/>.
 /// </param>
 internal virtual void AddToCompositionChains(AnimationManager animationManager, HandoffBehavior handoffBehavior, AnimationInstance previousInstance)
 {
     foreach (var child in Children)
     {
         child.AddToCompositionChains(animationManager, handoffBehavior, previousInstance);
     }
 }
Beispiel #22
0
        /// <inheritdoc/>
        internal override void AddToCompositionChains(AnimationManager animationManager, HandoffBehavior handoffBehavior, AnimationInstance previousInstance)
        {
            var property = Property;

            if (property == null)
            {
                return;
            }

            // Get (or create) the animation composition chain.
            var compositionChain = animationManager.GetCompositionChain(property, Animation.Traits, true);

            if (handoffBehavior == HandoffBehavior.SnapshotAndReplace)
            {
                // Make a snapshot of the current animation value.
                compositionChain.TakeSnapshot();
            }

            if (handoffBehavior == HandoffBehavior.Replace || handoffBehavior == HandoffBehavior.SnapshotAndReplace)
            {
                // Remove all previous animations.
                if (compositionChain.Count > 0)
                {
                    var rootInstance = this.GetRoot();
                    for (int i = compositionChain.Count - 1; i >= 0; i--)
                    {
                        var animationInstance = compositionChain[i];

                        // Do not remove animation instances of the same animation tree!
                        if (animationInstance.GetRoot() != rootInstance)
                        {
                            compositionChain.RemoveAt(i);
                        }
                    }
                }
            }

            AnimationInstance <T> referenceInstance = null;

            if (previousInstance != null)
            {
                // previousInstance is either a single animation instance or an animation tree that
                // should be replaced. Find the instance that is assigned to the current property.
                referenceInstance = previousInstance.GetAssignedInstance(Property) as AnimationInstance <T>;
            }

            if (referenceInstance == null)
            {
                // Add at the end of the animation composition chain.
                compositionChain.Add(this);
            }
            else
            {
                // Insert in animation composition chain at a certain index.
                int index = compositionChain.IndexOf(referenceInstance);
                if (index == -1)
                {
                    // The referenceInstance has not been applied to the current property.
                    compositionChain.Add(this);
                }
                else
                {
                    // Insert after referenceInstance.
                    index++;

                    // Other animation instances of the same animation tree might have already been
                    // inserted after referenceInstance. To maintain the correct order we need to add
                    // this instance after the other instances of the same tree.
                    var rootInstance      = this.GetRoot();
                    var numberOfInstances = compositionChain.Count;
                    while (index < numberOfInstances && compositionChain[index].GetRoot() == rootInstance)
                    {
                        index++;
                    }

                    compositionChain.Insert(index, this);
                }
            }
        }
Beispiel #23
0
 /// <summary>
 /// Stops the specified animations.
 /// </summary>
 /// <param name="animationInstance">The animation instance.</param>
 internal void StopAnimation(AnimationInstance animationInstance)
 {
   if (animationInstance != null)
     Remove(animationInstance);
 }