private void PollThread()
        {
            var sleepTime = TimeSpan.FromMilliseconds(0.5);

            while (!cancel)
            {
                if (!Connected)
                {
                    // Do less while waiting for the controller to come back online.
                    Thread.Sleep(250);
                    continue;
                }
                var state = new XInput.StateEx();
                if (0 != XInput.XInputGetStateEx(controllerIndex, ref state))
                {
                    Connected = false;
                    OnDisconnect?.ThreadSafeInvoke();
                    continue;
                }
                var gp = state.Gamepad;
                if (gp.bLeftTrigger != lastState.bLeftTrigger ||
                    gp.bRightTrigger != lastState.bRightTrigger ||
                    gp.sThumbLX != lastState.sThumbLX ||
                    gp.sThumbLY != lastState.sThumbLY ||
                    gp.sThumbRX != lastState.sThumbRX ||
                    gp.sThumbRY != lastState.sThumbRY ||
                    gp.wButtons != lastState.wButtons)
                {
                    lastState = gp;
                    OnStateChanged.ThreadSafeInvoke(lastState);
                }
                Thread.Sleep(sleepTime);
            }
        }
        //static List<RefCount<Controller>> Controllers = null;
        /// <summary>
        /// Returns an list of controller capabilities.
        /// </summary>
        /// <returns></returns>
        public static List <Controller> EnumerateControllers()
        {
            var ret = new List <Controller>();

            for (uint i = 0; i < XInput.XUSER_MAX_COUNT; i++)
            {
                var caps = new XInput.Capabilities();
                if (0 == XInput.XInputGetCapabilities(i, 1, ref caps))
                {
                    ret.Add(new Controller(i, caps));
                }
            }
            return(ret);
        }
        public ControllerMonitor(Controller c)
        {
            var state = new XInput.StateEx();

            if (0 != XInput.XInputGetStateEx(c.Index, ref state))
            {
                throw new Exception($"Controller {c.Index} is not connected");
            }
            lastState       = state.Gamepad;
            cancel          = false;
            controllerIndex = c.Index;
            Connected       = true;
            thread          = new Thread(PollThread)
            {
                Name = $"Controller {c.Index} poll thread"
            };
            thread.Start();
        }