/// <summary> /// Performs this animation in a completely event-driven way. /// </summary> public EventDrivenPassInfo CalculateEventDriven() { this.PreCheckExecutionInternal(); try { int countSteps = 0; PrecalculateAnimations(); // Create shared UpdateState object UpdateState updateState = new UpdateState(TimeSpan.Zero); // Perform whole animation in an event-driven way List <EventDrivenStepInfo> steps = new List <EventDrivenStepInfo>(12); while (this.CountRunningAnimations > 0) { // Store some values for measurement int countAnimationsBegin = this.CountRunningAnimations; // Perform animation calculation TimeSpan timeTillNext = this.TimeTillCurrentAnimationStepFinished; updateState.Reset(timeTillNext); AnimationUpdateResult updateResult = this.Update(updateState); countSteps++; // Generate resport data steps.Add(new EventDrivenStepInfo() { AnimationCount = updateResult.CountFinishedAnimations, UpdateTime = timeTillNext }); } return(new EventDrivenPassInfo(steps)); } finally { this.PostCheckExecutionInternal(); } }
/// <summary> /// Called for each update step of this animation. /// </summary> /// <param name="updateState">The current state of the update pass.</param> /// <param name="animationState">The current state of the animation.</param> public AnimationUpdateResult Update(IAnimationUpdateState updateState, AnimationState animationState) { int countAnimationsFinished = 0; bool prevIgnorePauseState = updateState.IgnorePauseState; PreCheckExecutionInternal(); try { // Execute all pre-update actions if (m_preUpdateActionsCount > 0) { PerformPreupdateActionsInternal(); } // Cancel here if there are no animations at all if ((m_runningAnimationsCount == 0) && (m_runningSecondaryAnimationsCount == 0)) { m_timeTillNextPartFinished = Constants.UPDATE_STATE_MAX_TIME; return(AnimationUpdateResult.Empty); } // Check collection counters for plausibility if ((m_runningAnimationsCount < 0) || (m_runningSecondaryAnimationsCount < 0) || (m_preUpdateActionsCount < 0)) { throw new SeeingSharpGraphicsException("Internal error: Invalid animation count errors in Animation handler!"); } bool anySubAnimationFinishedOrCanceled = false; // Animation update loop for primary animations if (m_runningAnimationsCount > 0) { anySubAnimationFinishedOrCanceled |= UpdateQueueInternal(updateState, animationState, m_runningAnimations); } // Animation update loop for secondary animations if (m_runningSecondaryAnimationsCount > 0) { foreach (Queue <IAnimation> actSecondaryQueue in m_runningSecondaryAnimations) { anySubAnimationFinishedOrCanceled |= UpdateQueueInternal(updateState, animationState, actSecondaryQueue); } } // Dequeue all finished animations // Do also calculate time till next finished animation here while (anySubAnimationFinishedOrCanceled && (m_runningAnimationsCount > 0)) { if (m_runningAnimations.First().IsFinishedOrCanceled()) { anySubAnimationFinishedOrCanceled = true; countAnimationsFinished++; IAnimation currentAnimation = m_runningAnimations.Dequeue(); if (currentAnimation != null) { Interlocked.Decrement(ref m_runningAnimationsCount); } } else { break; } } if (anySubAnimationFinishedOrCanceled && (m_runningSecondaryAnimationsCount > 0)) { foreach (Queue <IAnimation> actSecondaryQueue in m_runningSecondaryAnimations) { while (actSecondaryQueue.Count > 0) { if (actSecondaryQueue.Peek().IsFinishedOrCanceled()) { anySubAnimationFinishedOrCanceled = true; countAnimationsFinished++; actSecondaryQueue.Dequeue(); } else { break; } } } } // Clear all secondary animations which are finished completely while ((m_runningSecondaryAnimationsCount > 0) && (m_runningSecondaryAnimations.Peek().Count == 0)) { Queue <IAnimation> dummy = m_runningSecondaryAnimations.Dequeue(); Interlocked.Decrement(ref m_runningSecondaryAnimationsCount); } // Calculate time till next partial animation step if (anySubAnimationFinishedOrCanceled) { UpdateTimeTillNextPartFinished(); } else { m_timeTillNextPartFinished = m_timeTillNextPartFinished - updateState.UpdateTime; if (m_timeTillNextPartFinished < m_defaultCycleTime) { m_timeTillNextPartFinished = m_defaultCycleTime; } } } finally { updateState.IgnorePauseState = prevIgnorePauseState; PostCheckExecutionInternal(); } // Return some diagnostics about the executed animation AnimationUpdateResult result = new AnimationUpdateResult(); result.CountFinishedAnimations = countAnimationsFinished; return(result); }