Ejemplo n.º 1
0
        /// <summary>
        /// The meat of the recompute engine, updating hit test and the
        /// cached frames.
        /// </summary>
        private void ThreadUnsafeRunFrames(int start, int count)
        {
            var       steps         = new frameinfo[count];
            var       collisionlist = new List <LinkedList <int> >(count);
            frameinfo current       = _frames[start - 1];
            int       framecount    = _frames.Count;
            var       bones         = _track.Bones;

            using (changesync.AcquireWrite())
            {
                // we use the savedcells buffer exactly so runframes can
                // be completely consistent with the track state at the
                // time of running

                // we could also get a lock on the track grid, but that would
                // block user input on the track until we finish running.
                _savedcells.Clear();
            }
            using (var sync = changesync.AcquireRead())
            {
                _hittest.MarkFirstInvalid(start);
                for (int i = 0; i < count; i++)
                {
                    int currentframe = start + i;
                    var collisions   = new LinkedList <int>();
                    var oldtrigid    = current.TriggerLineID;
                    var zoom         =
                        current.Rider = current.Rider.Simulate(
                            _savedcells,
                            bones,
                            ref current.TriggerLineID,
                            collisions,
                            frameid: currentframe);
                    if (current.TriggerLineID != oldtrigid)
                    {
                        current.TriggerHitFrame = currentframe;
                    }
                    if (current.TriggerLineID != -1)
                    {
                        var std = (StandardLine)_track.LineLookup[current.TriggerLineID];
                        Debug.Assert(std.Trigger != null, "Trigger line proc on line with no trigger");
                        var delta = currentframe - current.TriggerHitFrame;
                        if (!std.Trigger.Activate(delta, ref current.Zoom))
                        {
                            current.TriggerLineID   = -1;
                            current.TriggerHitFrame = -1;
                        }
                    }
                    steps[i] = current;
                    collisionlist.Add(collisions);

                    // 10 seconds of frames,
                    // couldnt hurt to check?
                    if ((i + 1) % 400 == 0)
                    {
                        sync.ReleaseWaiting();
                    }
                }
                _hittest.AddFrames(collisionlist);
            }
            if (start + count > framecount)
            {
                _frames.EnsureCapacity(start + count);
                _frames.UnsafeSetCount(start + count);
            }
            for (int i = 0; i < steps.Length; i++)
            {
                _frames.unsafe_array[start + i] = steps[i];
            }
            FrameInvalidated?.Invoke(this, start);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// The meat of the recompute engine, updating hit test and the
        /// cached frames.
        /// </summary>
        public void ThreadUnsafeRunFrames(int start, int count)
        {
            var       steps         = new frameinfo[count];
            var       collisionlist = new List <LinkedList <int> >(count);
            frameinfo current       = _frames[start - 1];
            int       framecount    = _frames.Count;
            var       bones         = _track.Bones;

            using (changesync.AcquireWrite())
            {
                // we use the savedcells buffer exactly so runframes can
                // be completely consistent with the track state at the
                // time of running

                // we could also get a lock on the track grid, but that would
                // block user input on the track until we finish running.
                _savedcells.Clear();
            }
            using (var sync = changesync.AcquireRead())
            {
                _hittest.MarkFirstInvalid(start);
                GameTrigger[] triggers = new GameTrigger[GameTrigger.TriggerTypes];
                for (int i = 0; i < count; i++)
                {
                    int currentframe = start + i;
                    var collisions   = new LinkedList <int>();
                    current.Rider = current.Rider.Simulate(
                        _savedcells,
                        bones,
                        collisions,
                        frameid: currentframe);
                    if (GetTriggersForFrame(triggers, currentframe))
                    {
                        var zoomtrigger = triggers[(int)TriggerType.Zoom];
                        if (zoomtrigger != null)
                        {
                            var delta = currentframe - zoomtrigger.Start;
                            zoomtrigger.ActivateZoom(delta, ref current.Zoom);
                        }

                        var bgtrigger = triggers[(int)TriggerType.BGChange];
                        if (bgtrigger != null)
                        {
                            var delta = currentframe - bgtrigger.Start;
                            Constants.StaticTriggerBGColor = _frames[start - 1].BGColor;
                            bgtrigger.ActivateBG(delta, currentframe, ref Constants.StaticTriggerBGColor, ref Constants.TriggerBGColor, ref current.BGColor);
                        }

                        var linetrigger = triggers[(int)TriggerType.LineColor];
                        if (linetrigger != null)
                        {
                            var delta = currentframe - linetrigger.Start;
                            Constants.StaticTriggerLineColorChange = _frames[start - 1].LineColor;
                            linetrigger.ActivateLine(delta, ref Constants.StaticTriggerLineColorChange, ref Constants.TriggerLineColorChange, currentframe, ref current.LineColor);
                        }
                    }
                    steps[i] = current;
                    collisionlist.Add(collisions);

                    // 10 seconds of frames,
                    // couldnt hurt to check?
                    if ((i + 1) % 400 == 0)
                    {
                        sync.ReleaseWaiting();
                    }
                }
                _hittest.AddFrames(collisionlist);
            }
            if (start + count > framecount)
            {
                _frames.EnsureCapacity(start + count);
                _frames.UnsafeSetCount(start + count);
            }
            for (int i = 0; i < steps.Length; i++)
            {
                _frames.unsafe_array[start + i] = steps[i];
            }
            FrameInvalidated?.Invoke(this, start);
        }