Exemplo n.º 1
0
 /// <summary>
 /// Iterates over all elements in <paramref name="tsList"/> in the reverse order and calls
 /// <paramref name="handler"/>
 /// </summary>
 /// <typeparam name="T">Type to store in list</typeparam>
 /// <param name="tsList">A thread-safe list</param>
 /// <param name="handler">Called for each element</param>
 public static void IterateReverse <T>(this ThreadSafe.IList <T> tsList, IterateDelegate <T> handler)
 {
     tsList.Iterate(0, -1, true, handler);
 }
Exemplo n.º 2
0
        /// <summary>
        /// Calculate area prioritizing vertically
        /// </summary>
        /// <param name="block"></param>
        /// <param name="vert"></param>
        /// <param name="hori"></param>
        public GroupData CalcAreaVert(Block block, Direction vert, Direction hori)
        {
            Block     place       = block;
            Block     current     = null;
            Block     cornerBlock = null;
            GroupData data        = new GroupData();

            int height        = 0;
            int currentHeight = 0;
            int width         = boundary.width + 1;
            int currentWidth  = 0;

            switch (hori)
            {
            case Direction.left:
                IterateHori = SameLeft;
                break;

            case Direction.right:
                IterateHori = SameRight;
                break;

            default:
                return(data);
            }

            switch (vert)
            {
            case Direction.up:
                IterateVert = SameUp;
                break;

            case Direction.down:
                IterateVert = SameDown;
                break;

            default:
                return(data);
            }

            //Iterate prioritizing vertical
            while (place != null && place.IsGrouped() == false)
            {
                currentWidth = 0;
                current      = place;

                //Check if current block is null,.IsGrouped(), or passed the width
                while (current != null && current.IsGrouped() == false && currentWidth < width)
                {
                    //This currently priorites vertical rectangles
                    if (currentWidth >= 2)
                    {
                        cornerBlock = current;
                    }

                    current = IterateHori(current);

                    currentWidth++;
                }

                //Iterate vertically
                place = IterateVert(place);

                if (currentWidth >= 2)
                {
                    height++;
                    //Set height to shortest height
                    if (width > currentWidth)
                    {
                        width = currentWidth;
                    }
                }
                else
                {
                    return(data);
                }


                currentHeight++;
            }

            if (width == boundary.width + 1 || width <= 1 || height <= 1)
            {
                return(data);
            }

            data.width  = width;
            data.height = height;

            width  = width - 1;
            height = height - 1;

            int x = block.X;
            int y = block.Y;

            //Corners will be opposite of the direction the data points (up and left means block is bottom right corner
            if (vert.Equals(Direction.up) && hori.Equals(Direction.left))
            {
                data.topLeft     = board.GetBlock(x - width, y + height);
                data.topRight    = board.GetBlock(x, y + height);
                data.bottomLeft  = board.GetBlock(x - width, y);
                data.bottomRight = block;
            }
            else if (vert.Equals(Direction.up) && hori.Equals(Direction.right))
            {
                data.topLeft     = board.GetBlock(x, y + height);
                data.topRight    = board.GetBlock(x + width, y + height);
                data.bottomLeft  = block;
                data.bottomRight = board.GetBlock(x + width, y);
            }
            else if (vert.Equals(Direction.down) && hori.Equals(Direction.left))
            {
                data.topLeft     = board.GetBlock(x - width, y);
                data.topRight    = block;
                data.bottomLeft  = board.GetBlock(x - width, y - height);
                data.bottomRight = board.GetBlock(x, y - height);
            }
            else if (vert.Equals(Direction.down) && hori.Equals(Direction.right))
            {
                data.topLeft     = block;
                data.topRight    = board.GetBlock(x + width, y);
                data.bottomLeft  = board.GetBlock(x, y - height);
                data.bottomRight = board.GetBlock(x + width, y - height);
            }

            return(data);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Iterates over elements in <paramref name="tsList"/> and calls <paramref name="handler"/>
 /// </summary>
 /// <typeparam name="T">Type to store in list</typeparam>
 /// <param name="tsList">A thread-safe list</param>
 /// <param name="handler">Called for each element</param>
 /// <param name="startIndex">Start index</param>
 /// <param name="endIndex">End index. <c>-1</c> means <see cref="ThreadSafe.IList{T}.Count_NoLock"/></param>
 /// <param name="reverseOrder"><c>true</c> if we should iterate in the reverse order</param>
 public static void Iterate <T>(this ThreadSafe.IList <T> tsList, int startIndex, int endIndex, bool reverseOrder, IterateDelegate <T> handler)
 {
     tsList.ExecuteLocked <object, object>(null, (tsList2, arg) => {
         if (reverseOrder)
         {
             int i = (endIndex < 0 ? tsList2.Count_NoLock : endIndex) - 1;
             for (; i >= startIndex; i--)
             {
                 if (!handler(tsList2, i, tsList2.Get_NoLock(i)))
                 {
                     break;
                 }
             }
         }
         else
         {
             // Count property can change so check it each time in the loop
             for (int i = startIndex; i < (endIndex < 0 ? tsList2.Count_NoLock : endIndex); i++)
             {
                 if (!handler(tsList2, i, tsList2.Get_NoLock(i)))
                 {
                     break;
                 }
             }
         }
         return(null);
     });
 }
Exemplo n.º 4
0
        public void Expand(Direction dir)
        {
            Block other1 = null;
            Block other2 = null;

            switch (dir)
            {
            case Direction.up:
                other1 = data.topLeft.SameAdjacent(Direction.up);
                other2 = data.topRight.SameAdjacent(Direction.up);

                if (other1 == null || other2 == null)
                {
                    return;
                }

                data.topLeft  = other1;
                data.topRight = other2;

                //Iterate from topLeft to topRight (right)
                OnIterate = IterateRight;
                OnExpand  = IncrementHeight;
                break;

            case Direction.right:
                other1 = data.topRight.SameAdjacent(Direction.right);
                other2 = data.bottomRight.SameAdjacent(Direction.right);

                if (other1 == null || other2 == null)
                {
                    return;
                }

                data.topRight    = other1;
                data.bottomRight = other2;

                //Iterate from topRight to bottomRight (down)
                OnIterate = IterateDown;
                OnExpand  = IncrementWidth;
                break;

            case Direction.down:
                other1 = data.bottomLeft.SameAdjacent(Direction.down);
                other2 = data.bottomRight.SameAdjacent(Direction.down);

                if (other1 == null || other2 == null)
                {
                    return;
                }

                data.bottomLeft  = other1;
                data.bottomRight = other2;

                //Iterate from bottomLeft to bottomRight (right)
                OnIterate = IterateRight;
                OnExpand  = IncrementHeight;
                break;

            case Direction.left:
                other1 = data.topLeft.SameAdjacent(Direction.left);
                other2 = data.bottomLeft.SameAdjacent(Direction.left);

                if (other1 == null || other2 == null)
                {
                    return;
                }

                data.topLeft    = other1;
                data.bottomLeft = other2;

                //Iterate from topLeft to bottomLeft (down)
                OnIterate = IterateDown;
                OnExpand  = IncrementWidth;
                break;

            default:
                return;
            }

            //Get blocks adjacent to the corners
            other2.groupable.SetGroup(this);

            blocks.Add(other2);
            while (!other1.Equals(other2) && other1 != null)
            {
                blocks.Add(other1);
                other1.groupable.SetGroup(this);
                other1 = OnIterate(other1);
            }

            OnExpand();

            OnIterate = null;
            OnExpand  = null;
        }