Example #1
0
        public Layer(SavedLayer savedLayer) : this(savedLayer.Template)
        {
            var layerData = savedLayer.Data;

            // todo: verification
            var height = layerData.Cells.GetLength(0);
            var width  = layerData.Cells.GetLength(1);

            if (width != Template.Width || height != Template.Height)
            {
                throw new ArgumentException();
            }

            if (layerData.RightLinks.GetLength(0) != height || layerData.RightLinks.GetLength(1) != width)
            {
                throw new ArgumentException();
            }
            if (layerData.BottomLinks.GetLength(0) != height || layerData.BottomLinks.GetLength(1) != width)
            {
                throw new ArgumentException();
            }

            Width  = width;
            Height = height;

            _cellMatrix = new LayerCellMatrix(this);
            for (var i = 0; i < height; i++)
            {
                for (var j = 0; j < width; j++)
                {
                    _cellMatrix.UpdateCellContent(new Position(j, i), layerData.Cells[i, j]);
                    _cellMatrix.UpdateLinkContent(new Position(j, i), Side.Right, layerData.RightLinks[i, j]);
                    _cellMatrix.UpdateLinkContent(new Position(j, i), Side.Bottom, layerData.BottomLinks[i, j]);
                }
            }

            CommitChanges(false);
        }
Example #2
0
        public bool AddLink(Position from, Position to, LinkType linkType)
        {
            if (!from.IsAdjacent(to))
            {
                return(false);
            }

            var fromCell = _cellMatrix[from];
            var toCell   = _cellMatrix[to];

            if (!fromCell.IsValidCell || !toCell.IsValidCell)
            {
                return(false);
            }

            if (IsCellLocked(fromCell) && IsCellLocked(toCell))
            {
                return(false);
            }

            var side = from.GetAdjacentSide(to);

            var existingLink = fromCell.Links[side];

            switch (linkType)
            {
            case LinkType.SiliconLink:
                if (existingLink.SiliconLink != SiliconLink.None ||
                    !fromCell.HasSilicon() ||
                    !toCell.HasSilicon())
                {
                    return(false);
                }

                var(canPlace, newLinkType, targetSlc) = CheckSiliconLink(fromCell, toCell, side);
                if (canPlace)
                {
                    _cellMatrix.UpdateCellContent(to, new CellContent(toCell)
                    {
                        Silicon = targetSlc
                    });
                    _cellMatrix.UpdateLinkContent(from, side, new LinkContent(newLinkType, existingLink.HasMetalLink));
                    return(true);
                }

                return(false);

            case LinkType.MetalLink:
                if (existingLink.HasMetalLink ||
                    !fromCell.HasMetal ||
                    !toCell.HasMetal)
                {
                    return(false);
                }

                _cellMatrix.UpdateLinkContent(from, side, new LinkContent(existingLink.SiliconLink, true));
                return(true);

            default:
                throw new ArgumentException(nameof(linkType));
            }
        }