示例#1
0
        /// <summary>
        /// Deactivates and disables this root clock.
        /// </summary>
        internal void RootDisable()
        {
            Debug.Assert(IsTimeManager, "Invalid call to RootDeactivate for a non-root Clock");

            // Reset the state of the timing tree
            WeakRefEnumerator <Clock> enumerator = new WeakRefEnumerator <Clock>(_rootChildren);

            while (enumerator.MoveNext())
            {
                PrefixSubtreeEnumerator subtree = new PrefixSubtreeEnumerator(enumerator.Current, true);

                while (subtree.MoveNext())
                {
                    if (subtree.Current.InternalCurrentClockState != ClockState.Stopped)
                    {
                        subtree.Current.ResetCachedStateToStopped();

                        subtree.Current.RaiseCurrentStateInvalidated();
                        subtree.Current.RaiseCurrentTimeInvalidated();
                        subtree.Current.RaiseCurrentGlobalSpeedInvalidated();
                    }
                    else
                    {
                        subtree.SkipSubtree();
                    }
                }
            }
        }
示例#2
0
        // Called on the root
        internal void ComputeTreeState()
        {
            Debug.Assert(IsTimeManager);

            // Revive all children
            WeakRefEnumerator <Clock> enumerator = new WeakRefEnumerator <Clock>(_rootChildren);

            while (enumerator.MoveNext())
            {
                PrefixSubtreeEnumerator prefixEnumerator = new PrefixSubtreeEnumerator(enumerator.Current, true);
                while (prefixEnumerator.MoveNext())
                {
                    Clock current = prefixEnumerator.Current;

                    // Only traverse the "ripe" subset of the Timing tree
                    if (CurrentGlobalTime >= current.InternalNextTickNeededTime)
                    {
                        current.ApplyDesiredFrameRateToGlobalTime();
                        current.ComputeLocalState();       // Compute the state of the node
                        current.ClipNextTickByParent();    // Perform NextTick clipping, stage 1

                        // Make a note to visit for stage 2, only for ClockGroups and Roots
                        current.NeedsPostfixTraversal = (current is ClockGroup) || (current.IsRoot);
                    }
                    else
                    {
                        prefixEnumerator.SkipSubtree();
                    }
                }
            }

            // To perform a postfix walk culled by NeedsPostfixTraversal flag, we use a local recursive method
            // Note that since we called for this operation, it is probably already needed by the root clock
            ComputeTreeStateRoot();
        }
示例#3
0
        // This is only to be called on the TimeManager clock. Go through our
        // top level clocks and find the clock with the highest desired framerate.
        // DFR has to be > 0, so starting the accumulator at 0 is fine.
        internal int GetMaxDesiredFrameRate()
        {
            Debug.Assert(IsTimeManager);

            int desiredFrameRate = 0;

            // Ask all top-level clock their desired framerate
            WeakRefEnumerator <Clock> enumerator = new WeakRefEnumerator <Clock>(_rootChildren);

            while (enumerator.MoveNext())
            {
                Clock currentClock = enumerator.Current;

                if (currentClock != null && currentClock.CurrentState == ClockState.Active)
                {
                    int?currentDesiredFrameRate = currentClock.DesiredFrameRate;
                    if (currentDesiredFrameRate.HasValue)
                    {
                        desiredFrameRate = Math.Max(desiredFrameRate, currentDesiredFrameRate.Value);
                    }
                }
            }

            return(desiredFrameRate);
        }
示例#4
0
        /// <summary>
        /// Removes dead weak references from the child list of the root clock.
        /// </summary>
        internal void RootCleanChildren()
        {
            Debug.Assert(IsTimeManager, "Invalid call to RootCleanChildren for a non-root Clock");

            WeakRefEnumerator <Clock> enumerator = new WeakRefEnumerator <Clock>(_rootChildren);

            // Simply enumerating the children with the weak reference
            // enumerator is sufficient to clean up the list. Therefore, the
            // body of the loop can remain empty
            while (enumerator.MoveNext())
            {
            }

            // When the loop terminates naturally the enumerator will clean
            // up the list of any dead references. Therefore, by the time we
            // get here we are done.
        }
示例#5
0
        internal void ComputeTreeStateRoot()
        {
            Debug.Assert(IsTimeManager);
            TimeSpan?previousTickNeededTime = InternalNextTickNeededTime;

            InternalNextTickNeededTime = null;  // Reset the root's next tick needed time

            WeakRefEnumerator <Clock> enumerator = new WeakRefEnumerator <Clock>(_rootChildren);

            while (enumerator.MoveNext())
            {
                Clock current = enumerator.Current;

                if (current.NeedsPostfixTraversal)
                {
                    if (current is ClockGroup)
                    {
                        ((ClockGroup)current).ComputeTreeStatePostfix();
                    }
                    current.ApplyDesiredFrameRateToNextTick(); // Apply the effects of DFR on each root as needed
                    current.NeedsPostfixTraversal = false;     // Reset the flag
                }

                if (!InternalNextTickNeededTime.HasValue ||
                    (enumerator.Current.InternalNextTickNeededTime.HasValue &&
                     enumerator.Current.InternalNextTickNeededTime < InternalNextTickNeededTime))
                {
                    InternalNextTickNeededTime = enumerator.Current.InternalNextTickNeededTime;
                }
            }

            if (InternalNextTickNeededTime.HasValue &&
                (!previousTickNeededTime.HasValue || previousTickNeededTime > InternalNextTickNeededTime))
            {
                _timeManager.NotifyNewEarliestFutureActivity();
            }
        }