public static VarBufWithIndex FindLatestBuf(this iRSDKHeader header, int requestedTickCount)
        {
            VarBuf maxBuf   = new VarBuf();
            int    maxIndex = -1;

            for (var i = 0; i < header.numBuf; i++)
            {
                var b = header.varBuf[i];

                if (b.tickCount == requestedTickCount)
                {
                    return new VarBufWithIndex()
                           {
                               tickCount = requestedTickCount, bufOffset = b.bufOffset, index = i
                           }
                }
                ;

                if (b.tickCount > maxBuf.tickCount)
                {
                    maxBuf = b;

                    maxIndex = i;
                }
            }

            return(new VarBufWithIndex()
            {
                tickCount = maxBuf.tickCount, bufOffset = maxBuf.bufOffset, index = maxIndex
            });
        }
    }
        SessionData ReadSessionInfo(iRSDKHeader header)
        {
            if (header.sessionInfoUpdate == sessionLastInfoUpdate)
            {
                return(lastSessionInfo);
            }

            sessionLastInfoUpdate = header.sessionInfoUpdate;
            //Trace.WriteLine("New Session data retrieved from iRacing. {0}".F(sessionLastInfoUpdate), "DEBUG");

            var t = Task.Factory.StartNew(() => {
                var sessionInfoData = new byte[header.sessionInfoLen];
                accessor.ReadArray <byte>(header.sessionInfoOffset, sessionInfoData, 0, header.sessionInfoLen);
                var sessionInfoString = System.Text.Encoding.Default.GetString(sessionInfoData);

                var length = sessionInfoString.IndexOf('\0');
                if (length == -1)
                {
                    lastSessionInfo = null;
                    return;
                }

                sessionInfoString = sessionInfoString.Substring(0, sessionInfoString.IndexOf('\0'));
                //Trace.WriteLine(sessionInfoString, "DEBUG");
                lastSessionInfo = DeserialiseSessionInfo(sessionInfoString, header.sessionInfoUpdate);
            });

            if (lastSessionInfo == null)
            {
                t.Wait();
            }

            return(lastSessionInfo);
        }
        unsafe VarHeader[] ReadVariableHeaders(iRSDKHeader header, byte *ptr)
        {
            var varHeaders = new VarHeader[header.numVars];

            ptr += header.varHeaderOffset;

            for (var i = 0; i < header.numVars; i++)
            {
                varHeaders[i] = (VarHeader)Marshal.PtrToStructure(new IntPtr(ptr), typeof(VarHeader));
                ptr          += size;
            }

            return(varHeaders);
        }
        unsafe ITelemetry ReadVariables(iRSDKHeader header, VarHeader[] varHeaders, int requestedTickCount, bool logging)
        {
            var buf = header.FindLatestBuf(requestedTickCount);

            if (buf.index == -1)
            {
                Trace.WriteLine("No data in iRacing buffers", "DEBUG");
                return(null);
            }

            var values       = ReadAllValues(accessor, buf.bufOffset, varHeaders);
            var latestHeader = accessor.AcquirePointer(ptr => ReadHeader(ptr));

            if (latestHeader.HasChangedSinceReading(buf))
            {
                Trace.WriteLineIf(logging, "Failed to read data before iRacing overwrote new sample!", "DEBUG");
                return(null);
            }

            values.Add("TickCount", buf.tickCount);
            return(values);
        }
 public static bool HasChangedSinceReading(this iRSDKHeader header, VarBufWithIndex buf)
 {
     return(header.varBuf[buf.index].tickCount != buf.tickCount);
 }