public FlightMonitor()
 {
     monitoringThread = new Thread(new ThreadStart(MonitoringWorker));
     Queue            = new BlockingCollection <FSUIPCSnapshot>();
     Interests        = new List <SnapshotInterest>();
     lastQueued       = null;
 }
        /// <summary>
        /// Returns an FSUIPCSnapshot instance with the current state of the sim
        ///
        ///
        /// </summary>
        /// <param name="connectCooldown">Time between reconnect tries to Simulator, in miliseconds.
        /// Defaults to 30000.</param>
        /// <returns></returns>
        public static FSUIPCSnapshot Pool(int connectCooldown = 30000)
        {
            // TODO: do not block the current thread on this
            //       application may receive a OS taskkill command.
            //       Maybe expose connected = true?
            while (!connected)
            {
                try
                {
                    FSUIPCConnection.Open();

                    connected = true;
                }
                catch (FSUIPCException crap)
                {
                    switch (crap.FSUIPCErrorCode)
                    {
                    case FSUIPCError.FSUIPC_ERR_OPEN:
                        connected = true;
                        break;

                    case FSUIPCError.FSUIPC_ERR_NOFS:
                        Thread.Sleep(connectCooldown);
                        break;

                    default:
                        throw new ApplicationException(
                                  "Unexpected exception trying FSUIPC.Open(). Check inner exception.",
                                  crap);
                    }
                }
            }

            try
            {
                FSUIPCConnection.Process();
            }
            catch (Exception crap)
            {
                // TODO: catch ONLY relevant execeptions
                //       connected = false;
                throw new ApplicationException("Provider.Pool() failed with:", crap);
            }

            if (connected)
            {
                FSUIPCSnapshot data = new FSUIPCSnapshot(true);

                // FSUIPC will return data even if the user is in scenario screen
                // or any other screen really.
                // TODO: actually filter invalid locations
                return(data.Position.SequenceEqual(new double[] { 0, 0 }) ? null : data);
            }

            return(null);
        }
        private void MonitoringWorker()
        {
            while (running)
            {
                FSUIPCSnapshot contender = FSUIPCSnapshot.Pool();

                foreach (SnapshotInterest s in Interests)
                {
                    if (lastQueued == null || s(lastQueued, contender))
                    {
                        Queue.Add(lastQueued = contender);
                    }
                }

                Thread.Sleep(1);
            }
        }