示例#1
0
        public void RemoveBack(long consumed)
        {
            while (consumed > 0)
            {
                Segment?endSegment = _endSegment;
                if (endSegment == null)
                {
                    ThrowHelper.ThrowArgumentOutOfRange(nameof(consumed));
                }

                int length = endSegment.End - endSegment.Start;
                if (length > consumed)
                {
                    endSegment.RemoveBack((int)consumed);
                    consumed = 0;
                }
                else
                {
                    _endSegment = endSegment.Previous;
                    _endSegment?.SetNext(null);

                    ReturnSegment(endSegment);

                    consumed -= length;
                }
            }

            if (_endSegment == null)
            {
                _startSegment = null;
            }
        }
示例#2
0
        public void Remove(long consumed)
        {
            while (consumed > 0)
            {
                Segment?startSegment = _startSegment;
                if (startSegment == null)
                {
                    ThrowHelper.ThrowArgumentOutOfRange(nameof(consumed));
                }

                int length = startSegment.End - startSegment.Start;
                if (length > consumed)
                {
                    startSegment.Remove((int)consumed);
                    consumed = 0;
                }
                else
                {
                    _startSegment = startSegment.Next;

                    ReturnSegment(startSegment);

                    consumed -= length;
                }
            }

            if (_startSegment == null)
            {
                _endSegment = null;
            }
        }
示例#3
0
        /// <summary>Initializes the queue.</summary>
        public SingleProducerSingleConsumerQueue()
        {
            // Validate constants in ctor rather than in an explicit cctor that would cause perf degradation
            Debug.Assert(InitialSegmentSize > 0, "Initial segment size must be > 0.");
            Debug.Assert((InitialSegmentSize & (InitialSegmentSize - 1)) == 0, "Initial segment size must be a power of 2");
            Debug.Assert(InitialSegmentSize <= MaxSegmentSize, "Initial segment size should be <= maximum.");
            Debug.Assert(MaxSegmentSize < int.MaxValue / 2, "Max segment size * 2 must be < Int32.MaxValue, or else overflow could occur.");

            // Initialize the queue
            _head = _tail = new Segment(InitialSegmentSize);
        }
示例#4
0
 /// <summary>Gets an enumerable for the collection.</summary>
 /// <remarks>WARNING: This should only be used for debugging purposes.  It is not safe to be used concurrently.</remarks>
 public IEnumerator <T> GetEnumerator()
 {
     for (Segment?segment = _head; segment != null; segment = segment._next)
     {
         for (int pt = segment._state._first;
              pt != segment._state._last;
              pt = (pt + 1) & (segment._array.Length - 1))
         {
             yield return(segment._array[pt]);
         }
     }
 }
示例#5
0
        // Plays the given segments on the players.
        private async Task PlaySegmentsAsync(Segment?segmentForPlayerA, Segment?segmentForPlayerB)
        {
            // Draw a highlight around the players that are playing a segment.
            UpdatePlayerHighlights(segmentForPlayerA.HasValue, segmentForPlayerB.HasValue);

            // Start playing the segments.
            var tasks = new[] { segmentForPlayerA?.PlayAsync(PlayerA), segmentForPlayerB?.PlayAsync(PlayerB) };

            // Wait for the segments to finish.
            await Task.WhenAll(tasks.Where(t => t is not null).ToArray());

            // Remove the highlight drawn around the playing players.
            UpdatePlayerHighlights(false, false);
        }
示例#6
0
        // https://stackoverflow.com/a/565282/3333753
        static public bool Intersects(this Segment segmentA, Segment segmentB, out Segment?intersection)
        {
            Vector2 vectorA = segmentA.Vector;
            Vector2 vectorB = segmentB.Vector;

            Vector2 p0Diff = segmentB.P0 - segmentA.P0;
            float   b      = p0Diff.Cross(vectorB);

            float abCross = vectorA.Cross(vectorB);

            // Check if segments are parallel
            if (abCross.EqualsZero())
            {
                // Check if segments are colinear
                if (b.EqualsZero())
                {
                    float         aaDot = Vector2.Dot(vectorA, vectorA);
                    float         baDot = Vector2.Dot(vectorB, vectorA);
                    float         t0    = Vector2.Dot(p0Diff, vectorA) / aaDot;
                    float         t1    = t0 + baDot / aaDot;
                    Range <float> t01   = baDot >= 0 ? new Range <float>(t0, t1) : new Range <float>(t1, t0);

                    // Check if segments are overlapping
                    if (RangeUtils.Intersects(t01, new Range <float>(0, 1)))
                    {
                        intersection = new Segment(segmentA.P0 + t01.Min * vectorA, segmentA.P0 + t01.Max * vectorA);
                        return(true);
                    }
                }
            }
            else
            {
                float a = p0Diff.Cross(vectorA);

                float t = a / abCross;
                float u = b / abCross;

                // Check if intersect at one point
                if (t >= 0 && t <= 1 && u >= 0 && u <= 1)
                {
                    Vector2 intersectionPoint = segmentA.P0 + t * vectorA;
                    intersection = new Segment(intersectionPoint, intersectionPoint);
                    return(true);
                }
            }

            intersection = null;
            return(false);
        }
示例#7
0
        private void AddSegment(int sizeHint)
        {
            Segment?previousEnd = _endSegment;

            _endSegment = SequencePool.RentSegment();
            _endSegment.SetBuffer(SequencePool.RentByteBuffer(sizeHint));
            if (_startSegment == null)
            {
                _startSegment = _endSegment;
            }
            else
            {
                previousEnd !.SetNext(_endSegment);
            }
        }
        public void Discard(int length)
        {
            Debug.Assert(length >= 0);
            Debug.Assert(length <= _activeLength);

            _activeLength -= length;

            bool monitorEntered = false;

            try
            {
                do
                {
                    int left = _segmentLength - _activeOffset;

                    if (length < left)
                    {
                        _activeOffset += length;
                        return;
                    }

                    _activeOffset = 0;

                    if (!monitorEntered)
                    {
                        Monitor.Enter(this, ref monitorEntered);
                    }

                    _first = _first !.Next;

                    if (_first == null)
                    {
                        Debug.Assert(length == 0);
                        _last = null;
                        return;
                    }

                    length -= left;
                }while (length != 0);
            }
            finally
            {
                if (monitorEntered)
                {
                    Monitor.Exit(this);
                }
            }
        }
        private void EnsureSegmentAvailableSlow()
        {
            var seg = new Segment(this, _segmentLength);

            if (_last != null)
            {
                _last.Next = seg;
            }
            else
            {
                _first = seg;
            }

            _last = seg;
            _availableFirst ??= seg;
            _availableLength += _segmentLength;
        }
示例#10
0
        public void Clear()
        {
            var segment = _startSegment;

            while (segment != null)
            {
                var next = segment.Next;

                ReturnSegment(segment);

                segment = next;
            }

            // Return Sequence
            _startSegment = null;
            _endSegment   = null;
        }
示例#11
0
    /// <summary>
    /// Найти самый длинный отрезок
    /// </summary>
    /// <param name="space">Набор точек</param>
    /// <returns>Отрезок</returns>
    public static Segment?MaxSegment(this IEnumerable <Point> space)
    {
        Segment?result = null;

        for (var i = 0; i < space.Count(); ++i)
        {
            for (var j = i + 1; j < space.Count(); ++j)
            {
                var segment = new Segment(space.ElementAt(i), space.ElementAt(j));
                if (result == null || segment.Distance > result.Value.Distance)
                {
                    result = segment;
                }
            }
        }
        return(result);
    }
    private static void _AddLine(int lineKey, Segment newSegment, Dictionary <int, List <Segment> > segmentKeyToSegments)
    {
        // Get the list of segments for the given key (X for vertical lines, Y for horizontal lines)
        List <Segment> segments;

        if (!segmentKeyToSegments.TryGetValue(lineKey, out segments))
        {
            segments = new List <Segment>();
            segmentKeyToSegments[lineKey] = segments;
        }
        int isegmentInsert = 0, isegmentMergeFirst = -1, ilineSegmentLast = -1;

        // Find all existing segments that should be merged with the new one
        while (isegmentInsert < segments.Count && segments[isegmentInsert].Start <= newSegment.End)
        {
            Segment?intersectedSegment = newSegment.Intersect(segments[isegmentInsert]);
            if (intersectedSegment != null)
            {
                // If they overlap, merge them together, keeping track of all the existing
                // segments which were merged
                newSegment = newSegment.Union(segments[isegmentInsert]);
                if (isegmentMergeFirst == -1)
                {
                    isegmentMergeFirst = isegmentInsert;
                }
                ilineSegmentLast = isegmentInsert;
            }
            isegmentInsert++;
        }
        if (isegmentMergeFirst == -1)
        {
            // If there was no merge, just insert the new segment
            segments.Insert(isegmentInsert, newSegment);
        }
        else
        {
            // If more than one segment was merged, remove all but one
            if (ilineSegmentLast > isegmentMergeFirst)
            {
                segments.RemoveRange(isegmentMergeFirst + 1, ilineSegmentLast - isegmentMergeFirst);
            }
            // Copy the new, merged segment back to the first original segment's slot
            segments[isegmentMergeFirst] = newSegment;
        }
    }
示例#13
0
        public void ConsumeTo(SequencePosition consumed)
        {
            var segment = (Segment)consumed.GetObject();
            var index   = consumed.GetInteger();

            if (segment == _endSegment && index == _endIndex)
            {
                // keep the last page; burn anything else
                _startSegment !.RecycleBefore(segment);
                _startSegment = _endSegment;
                _startIndex   = _endIndex = 0;
            }
            else
            {
                // discard any pages that we no longer need
                _startSegment !.RecycleBefore(segment);
                _startSegment = segment;
                _startIndex   = index;
            }
        }
        private void AddFreeSegment(Segment segment)
        {
            lock (this)
            {
                _availableLength += _segmentLength;

                if (_last != null)
                {
                    _last.Next = segment;
                }
                else
                {
                    _first = segment;
                }

                _last = segment;

                if (_availableFirst == null)
                {
                    _availableFirst = segment;
                }
            }
        }
示例#15
0
        private void FixSegments(int pathIndex)
        {
            // TODO żeby nie była upośledzona
            Path path = Paths[pathIndex];

            for (int i = 0; i < path.Segments.Count - 1; i++)
            {
                while (i < path.Segments.Count - 1 && DirectionUtils.Parallel(path.Segments[i].Direction, path.Segments[i + 1].Direction))
                {
                    Segment?merged = path.Segments[i].Merge(path.Segments[i + 1]);
                    path.Segments.RemoveAt(i);
                    path.Segments.RemoveAt(i);
                    if (merged != null)
                    {
                        path.Segments.Insert(i, merged.Value);
                    }
                    else
                    {
                        i = Math.Max(i - 1, 0);
                    }
                }
            }
        }
 public CountedBuffer(int segmentLength)
 {
     _first           = _last = _availableFirst = new Segment(this, segmentLength);
     _segmentLength   = segmentLength;
     _availableLength = segmentLength;
 }
示例#17
0
        public static List <Path> FilterSelection(IEnumerable <Path> paths, bool invert = false)
        {
            var selValue = !invert;
            var outPaths = new List <Path>();

            foreach (var path in paths)
            {
                var segments = path.Segments;

                IEnumerable <Segment> iter;
                if (!path.IsOpen && segments.First().OnCurve.IsSelected == selValue)
                {
                    var segmentsList = segments.ToList();

                    int index;
                    for (index = segmentsList.Count - 1; index >= 0; --index)
                    {
                        if (segmentsList[index].OnCurve.IsSelected != selValue)
                        {
                            break;
                        }
                    }
                    if (index <= 0)
                    {
                        // All selected, bring on the original path
                        outPaths.Add(path);
                        continue;
                    }
                    else
                    {
                        iter = Sequence.IterAt(segmentsList, index);
                    }
                }
                else
                {
                    iter = segments;
                }

                Path    outPath      = null;
                Segment?prev         = null;
                var     prevSelected = false;
                foreach (var segment in iter)
                {
                    var selected = segment.OnCurve.IsSelected == selValue;
                    if (selected)
                    {
                        if (prevSelected)
                        {
                            if (invert)
                            {
                                // XXX: bad
                                segment.Points.ForEach(point => point.Parent = outPath);
                            }
                            outPath._points.AddRange(segment.Points);
                        }
                        else
                        {
                            Point point;
                            outPath = new Path();
                            if (invert)
                            {
                                point = segment.OnCurve;
                                // XXX: bad. we're making assumptions about caller.
                                // here we are reparenting because we know original paths will be trashed
                                // (Outline.DeleteSelection) where !invert does a no copy work.
                                // I don't like this, and the delete apis returning a list of paths tbh....
                                outPath.Parent = path.Parent;
                                point.Parent   = outPath;
                            }
                            else
                            {
                                point = segment.OnCurve.Clone();
                            }
                            point.IsSmooth = false;
                            point.Type     = PointType.Move;
                            outPath._points.Add(point);
                        }
                    }
                    else
                    {
                        if (prevSelected)
                        {
                            if (invert)
                            {
                                prev.Value.OnCurve.IsSmooth = false;
                            }
                            // We got a path, export it and move on
                            outPaths.Add(outPath);
                            outPath = null;
                        }
                    }
                    prev         = segment;
                    prevSelected = selected;
                }
                if (prevSelected)
                {
                    outPaths.Add(outPath);
                }
            }

            return(outPaths);
        }
示例#18
0
        /// <summary>
        /// Given a road and a new position to add to the road,
        ///     gets or creates a vertex to add to the road.
        /// The vertex will always already be added to the vertex BVH.
        /// If the returned vertex is null, it shouldn't be added to the road.
        /// If "EndRoad" is true, the road should not continue on.
        /// </summary>
        private VertexFindResults FindOrMakeVertex(Road r, Vector2 nextPos)
        {
            Vertex lastPoint = r.Points[r.Points.Count - 1];

            //Reject if the segment length is too short or its position is outside the city limits.
            if (lastPoint.Pos.DistSqr(nextPos) <= (SegmentMinLength * SegmentMinLength) ||
                !IsInBounds(nextPos))
            {
                return(VertexFindResults.Reject());
            }

            //If the next position is near another vertex, use that vertex and end the road there.
            foreach (Vertex v in Vertices.GetAllNearbyPos(nextPos))
            {
                //Don't let the road loop back onto itself.
                if (v.RoadsConnectedTo.Contains(r))
                {
                    continue;
                }

                //Don't create a segment that already exists.
                if (v.VertsConnectedTo.Contains(lastPoint))
                {
                    return(VertexFindResults.Reject());
                }

                v.ConnectTo(lastPoint);

                return(VertexFindResults.Accept(v, true));
            }


            Rect segBnds = new Rect().BoundByPoints(nextPos, lastPoint.Pos);

            //If the segment intersects another segment, turn it into an intersection and continue.
            List <Segment> segs = Segments.GetAllNearbyBnds(segBnds).ToList();
            float          t1   = float.NaN,
                           t2   = float.NaN;
            Segment?hitSeg      = null;

            //Get any intersected segments.
            //If we intersect with a previous part of this road, reject.
            for (int i = 0; i < segs.Count; ++i)
            {
                float temp1     = float.NaN,
                      temp2     = float.NaN;
                bool intersects = GeneratorUtils.SegmentsIntersect(lastPoint.Pos, nextPos,
                                                                   segs[i].P1.Pos, segs[i].P2.Pos,
                                                                   ref temp1, ref temp2);
                if (segs[i].Owner == r ||
                    segs[i].P1.RoadsConnectedTo.Contains(r) ||
                    segs[i].P2.RoadsConnectedTo.Contains(r))
                {
                    if (intersects)
                    {
                        return(VertexFindResults.Reject());
                    }
                }
                else if (intersects)
                {
                    t1     = temp1;
                    t2     = temp2;
                    hitSeg = segs[i];
                }
            }
            if (hitSeg.HasValue)
            {
                //Split up the road that the segment is a part of
                //    by adding a new vertex at the intersection.
                Vertex vtx = new Vertex(hitSeg.Value.P1.Pos +
                                        ((hitSeg.Value.P2.Pos - hitSeg.Value.P1.Pos) * t2));
                vtx.ConnectTo(lastPoint);
                Vertices.Add(vtx);
                SplitSegment(vtx, hitSeg.Value);

                return(VertexFindResults.Accept(vtx, false));
            }


            //This segment isn't special in any way.
            Vertex vert = new Vertex(nextPos);

            vert.ConnectTo(lastPoint);
            Vertices.Add(vert);
            return(VertexFindResults.Accept(vert, false));
        }