public void Run()
        {
            MouseInput();

            if (UndoEvt.IsEmpty() && RedoEvt.IsEmpty())
            {
                return;
            }
            Counters(undo: !UndoEvt.IsEmpty(), redo: !RedoEvt.IsEmpty(), false);
            _preventHistoryInsert = true;
            if (!_preventSelectionSet)
            {
                (var history, var id) = Globals <PersistentUndoRedoState> .Value;
                SelectionEntry entry = history[id];
                if (entry.Valid())
                {
                    Selection.objects = entry.IsGuids
                        ? entry.Guids.Select(AssetDatabase.GUIDToAssetPath).Select(AssetDatabase.LoadAssetAtPath <Object>).Where(obj => obj).ToArray()
                        : entry.SceneObjects;
                }
            }

            _preventSelectionSet = false;

            UndoEvt.AllDestroy();
            RedoEvt.AllDestroy();
        }
        static void Counters(bool undo, bool redo, bool insertToHistory)
        {
            var state = Globals <PersistentUndoRedoState> .Value;

            World.NewEntityWith(out RequestRepaintEvt _);

            const int MinId = 0;

            if (insertToHistory)
            {
                var entry = new SelectionEntry();

                var count = state.History.Count - 1 - state.Id;
                if (count > 0)
                {
                    state.History.RemoveRange(state.Id + 1, count);
                }

                state.History.Add(entry);
                state.Id = MaxId();

                if (Selection.assetGUIDs.Length > 0)
                {
                    entry.IsGuids = true;
                    entry.Guids   = Selection.assetGUIDs;
                }
                else
                {
                    entry.SceneObjects = Selection.objects;
                }
            }

            if (undo)
            {
                // loop to skip invalid
                while (true)
                {
                    state.Id -= 1;
                    if (state.Id < MinId)
                    {
                        break;
                    }
                    if (state.History[state.Id].Valid())
                    {
                        break;
                    }
                }
            }

            if (redo)
            {
                // loop to skip invalid
                while (true)
                {
                    state.Id += 1;
                    if (state.Id > MaxId())
                    {
                        break;
                    }
                    if (state.History[state.Id].Valid())
                    {
                        break;
                    }
                }
            }

            state.Id = Mathf.Clamp(state.Id, MinId, MaxId());

            var undoRedoState = Globals <UndoRedoState> .Value;

            undoRedoState.UndoEnabled = state.Id != MinId;
            undoRedoState.RedoEnabled = state.Id != MaxId();

            int MaxId() => Mathf.Max(0, state.History.Count - 1);
        }