Esempio n. 1
0
        /// <summary>
        /// Attempt to advance replay playback for a given time.
        /// </summary>
        /// <param name="proposedTime">The time which is to be displayed.</param>
        /// <returns>Whether playback is still valid.</returns>
        private bool updateReplay(ref double proposedTime)
        {
            double?newTime;

            if (FrameStablePlayback)
            {
                // when stability is turned on, we shouldn't execute for time values the replay is unable to satisfy.
                newTime = ReplayInputHandler.SetFrameFromTime(proposedTime);
            }
            else
            {
                // when stability is disabled, we don't really care about accuracy.
                // looping over the replay will allow it to catch up and feed out the required values
                // for the current time.
                while ((newTime = ReplayInputHandler.SetFrameFromTime(proposedTime)) != proposedTime)
                {
                    if (newTime == null)
                    {
                        // special case for when the replay actually can't arrive at the required time.
                        // protects from potential endless loop.
                        break;
                    }
                }
            }

            if (newTime == null)
            {
                return(false);
            }

            proposedTime = newTime.Value;
            return(true);
        }
Esempio n. 2
0
        private void updateClock()
        {
            if (parentGameplayClock == null)
            {
                setClock(); // LoadComplete may not be run yet, but we still want the clock.
            }
            validState = true;

            manualClock.Rate      = parentGameplayClock.Rate;
            manualClock.IsRunning = parentGameplayClock.IsRunning;

            var newProposedTime = parentGameplayClock.CurrentTime;

            try
            {
                if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f)
                {
                    newProposedTime = manualClock.Rate > 0
                        ? Math.Min(newProposedTime, manualClock.CurrentTime + sixty_frame_time)
                        : Math.Max(newProposedTime, manualClock.CurrentTime - sixty_frame_time);
                }

                if (!isAttached)
                {
                    manualClock.CurrentTime = newProposedTime;
                }
                else
                {
                    double?newTime = ReplayInputHandler.SetFrameFromTime(newProposedTime);

                    if (newTime == null)
                    {
                        // we shouldn't execute for this time value. probably waiting on more replay data.
                        validState = false;

                        requireMoreUpdateLoops  = true;
                        manualClock.CurrentTime = newProposedTime;
                        return;
                    }

                    manualClock.CurrentTime = newTime.Value;
                }

                requireMoreUpdateLoops = manualClock.CurrentTime != parentGameplayClock.CurrentTime;
            }
            finally
            {
                // The manual clock time has changed in the above code. The framed clock now needs to be updated
                // to ensure that the its time is valid for our children before input is processed
                framedClock.ProcessFrame();
            }
        }
Esempio n. 3
0
        private void updateClock()
        {
            if (parentGameplayClock == null)
            {
                setClock(); // LoadComplete may not be run yet, but we still want the clock.
            }
            validState             = true;
            requireMoreUpdateLoops = false;

            var newProposedTime = parentGameplayClock.CurrentTime;

            try
            {
                if (FrameStablePlayback)
                {
                    if (firstConsumption)
                    {
                        // On the first update, frame-stability seeking would result in unexpected/unwanted behaviour.
                        // Instead we perform an initial seek to the proposed time.

                        // process frame (in addition to finally clause) to clear out ElapsedTime
                        manualClock.CurrentTime = newProposedTime;
                        framedClock.ProcessFrame();

                        firstConsumption = false;
                    }
                    else if (manualClock.CurrentTime < gameplayStartTime)
                    {
                        manualClock.CurrentTime = newProposedTime = Math.Min(gameplayStartTime, newProposedTime);
                    }
                    else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f)
                    {
                        newProposedTime = newProposedTime > manualClock.CurrentTime
                            ? Math.Min(newProposedTime, manualClock.CurrentTime + sixty_frame_time)
                            : Math.Max(newProposedTime, manualClock.CurrentTime - sixty_frame_time);
                    }
                }

                if (isAttached)
                {
                    double?newTime;

                    if (FrameStablePlayback)
                    {
                        // when stability is turned on, we shouldn't execute for time values the replay is unable to satisfy.
                        if ((newTime = ReplayInputHandler.SetFrameFromTime(newProposedTime)) == null)
                        {
                            // setting invalid state here ensures that gameplay will not continue (ie. our child
                            // hierarchy won't be updated).
                            validState = false;

                            // potentially loop to catch-up playback.
                            requireMoreUpdateLoops = true;

                            return;
                        }
                    }
                    else
                    {
                        // when stability is disabled, we don't really care about accuracy.
                        // looping over the replay will allow it to catch up and feed out the required values
                        // for the current time.
                        while ((newTime = ReplayInputHandler.SetFrameFromTime(newProposedTime)) != newProposedTime)
                        {
                            if (newTime == null)
                            {
                                // special case for when the replay actually can't arrive at the required time.
                                // protects from potential endless loop.
                                validState = false;
                                return;
                            }
                        }
                    }

                    newProposedTime = newTime.Value;
                }
            }
            finally
            {
                if (newProposedTime != manualClock.CurrentTime)
                {
                    direction = newProposedTime > manualClock.CurrentTime ? 1 : -1;
                }

                manualClock.CurrentTime = newProposedTime;
                manualClock.Rate        = Math.Abs(parentGameplayClock.Rate) * direction;
                manualClock.IsRunning   = parentGameplayClock.IsRunning;

                requireMoreUpdateLoops |= manualClock.CurrentTime != parentGameplayClock.CurrentTime;

                // The manual clock time has changed in the above code. The framed clock now needs to be updated
                // to ensure that the its time is valid for our children before input is processed
                framedClock.ProcessFrame();
            }
        }
Esempio n. 4
0
        private void updateClock()
        {
            if (parentGameplayClock == null)
            {
                setClock(); // LoadComplete may not be run yet, but we still want the clock.
            }
            validState = true;

            manualClock.Rate      = parentGameplayClock.Rate;
            manualClock.IsRunning = parentGameplayClock.IsRunning;

            var newProposedTime = parentGameplayClock.CurrentTime;

            try
            {
                if (!FrameStablePlayback)
                {
                    manualClock.CurrentTime = newProposedTime;
                    requireMoreUpdateLoops  = false;
                    return;
                }
                else if (firstConsumption)
                {
                    // On the first update, frame-stability seeking would result in unexpected/unwanted behaviour.
                    // Instead we perform an initial seek to the proposed time.
                    manualClock.CurrentTime = newProposedTime;

                    // do a second process to clear out ElapsedTime
                    framedClock.ProcessFrame();

                    firstConsumption = false;
                }
                else if (manualClock.CurrentTime < gameplayStartTime)
                {
                    manualClock.CurrentTime = newProposedTime = Math.Min(gameplayStartTime, newProposedTime);
                }
                else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f)
                {
                    newProposedTime = newProposedTime > manualClock.CurrentTime
                        ? Math.Min(newProposedTime, manualClock.CurrentTime + sixty_frame_time)
                        : Math.Max(newProposedTime, manualClock.CurrentTime - sixty_frame_time);
                }

                if (!isAttached)
                {
                    manualClock.CurrentTime = newProposedTime;
                }
                else
                {
                    double?newTime = ReplayInputHandler.SetFrameFromTime(newProposedTime);

                    if (newTime == null)
                    {
                        // we shouldn't execute for this time value. probably waiting on more replay data.
                        validState = false;

                        requireMoreUpdateLoops  = true;
                        manualClock.CurrentTime = newProposedTime;
                        return;
                    }

                    manualClock.CurrentTime = newTime.Value;
                }

                requireMoreUpdateLoops = manualClock.CurrentTime != parentGameplayClock.CurrentTime;
            }
            finally
            {
                // The manual clock time has changed in the above code. The framed clock now needs to be updated
                // to ensure that the its time is valid for our children before input is processed
                framedClock.ProcessFrame();
            }
        }