private void Update()
        {
            updateScheduled = false;
            var map = Find.CurrentMap;

            if (listening && map == null || Find.MapUI.designatorManager.SelectedDesignator != owningDesignator)
            {
                StopListening();
            }
            if (!listening)
            {
                return;
            }
            RegisterForNextUpdate();
            var dragger = Find.MapUI.designatorManager.Dragger;

            if (!SelectionInProgress && dragger.Dragging)
            {
                OnSelectionStarted();
            }
            else if (SelectionInProgress && !dragger.Dragging)
            {
                OnSelectionEnded();
            }
            if (SelectionInProgress)
            {
                var mouseCell   = UI.MouseCell();
                var currentCell = ClampPositionToMapRect(map, mouseCell);
                var currentRect = CellRect.FromLimits(SelectionStartCell, currentCell);
                if (currentRect != SelectedArea)
                {
                    SelectedArea = currentRect;
                    OnSelectedAreaChanged();
                }

                SelectionUpdate?.Invoke(SelectedArea);
            }
        }
        private void SelectionUpdate(SelectionUpdate selUpdate)
        {
            // ram drawing
            if (!RAMSelectionManager.Instance.HasMappings)
            {
                RAMSelectionManager.Instance.UpdateMapping();
            }

            Graphics graphicsObj = Graphics.FromImage(TileBitmap);

            switch (selUpdate.Action)
            {
            case (SelectionUpdateAction.AddCurrentSelectionToUserSelection):
            {
                foreach (Tile t in TileSelectionManager.Instance.GetUserSelection(selUpdate.UserSelectionType, m_view.TileRegex))
                {
                    if (IdentifierManager.Instance.IsMatch(t.Location, IdentifierManager.RegexTypes.CLB))
                    {
                        Tile intTile = FPGATypes.GetInterconnectTile(t);
                        DrawTile(intTile, graphicsObj, true, true);
                    }
                    DrawTile(t, graphicsObj, true, true);
                }
                break;
            }

            case (SelectionUpdateAction.AddToSelection):
            case (SelectionUpdateAction.AddToUserSelection):
            {
                Tile t = FPGA.FPGA.Instance.GetTile(selUpdate.AffecetedTileKey);
                DrawTile(t, graphicsObj, true, true);
                break;
            }

            case (SelectionUpdateAction.ClearAllUserSelections):
            {
                foreach (Tile t in TileSelectionManager.Instance.GetAllUserSelectedTiles())
                {
                    if (IdentifierManager.Instance.IsMatch(t.Location, IdentifierManager.RegexTypes.CLB))
                    {
                        Tile intTile = FPGATypes.GetInterconnectTile(t);
                        DrawTile(intTile, graphicsObj, true, false);
                    }
                    DrawTile(t, graphicsObj, true, false);
                }
                break;
            }

            case (SelectionUpdateAction.ClearSelection):
            {
                foreach (Tile tile in TileSelectionManager.Instance.GetSelectedTiles().Where(t => m_view.TileRegex.IsMatch(t.Location)))
                {
                    if (IdentifierManager.Instance.IsMatch(tile.Location, IdentifierManager.RegexTypes.CLB))
                    {
                        Tile intTile = FPGATypes.GetInterconnectTile(tile);
                        DrawTile(intTile, graphicsObj, false, true);
                    }
                    DrawTile(tile, graphicsObj, false, true);
                }
                break;
            }

            case (SelectionUpdateAction.ClearUserSelection):
            {
                foreach (Tile t in TileSelectionManager.Instance.GetAllUserSelectedTiles(selUpdate.UserSelectionType))
                {
                    if (IdentifierManager.Instance.IsMatch(t.Location, IdentifierManager.RegexTypes.CLB))
                    {
                        Tile intTile = FPGATypes.GetInterconnectTile(t);
                        DrawTile(intTile, graphicsObj, true, false);
                    }
                    DrawTile(t, graphicsObj, true, false);
                }
                break;
            }

            case (SelectionUpdateAction.RemoveFromSelection):
            {
                Tile t = FPGA.FPGA.Instance.GetTile(selUpdate.AffecetedTileKey);
                if (IdentifierManager.Instance.IsMatch(t.Location, IdentifierManager.RegexTypes.CLB))
                {
                    Tile intTile = FPGATypes.GetInterconnectTile(t);
                    DrawTile(intTile, graphicsObj, false, true);
                }
                DrawTile(t, graphicsObj, false, true);
                break;
            }

            case (SelectionUpdateAction.InversionComplete):
            {
                foreach (Tile t in FPGA.FPGA.Instance.GetAllTiles())
                {
                    DrawTile(t, graphicsObj, true, true);
                }
                break;
            }

            default:
            {
                throw new ArgumentException("Unexpected UpdateAction: " + selUpdate.Action);
            }
            }
        }