private void readGameData()
        {
            try
            {
                // Note: if it is critical for client minimize wait time, same strategy as plugin uses can be employed.
                // Pass 0 timeout and skip update if someone holds the lock.
                if (this.fileAccessMutex.WaitOne(5000))
                {
                    try
                    {
                        bool buf1Current = false;
                        // Try buffer 1:
                        using (var sharedMemoryStreamView = this.memoryMappedFile1.CreateViewStream())
                        {
                            var sharedMemoryStream = new BinaryReader(sharedMemoryStreamView);
                            this.sharedMemoryReadBuffer = sharedMemoryStream.ReadBytes(this.SHARED_MEMORY_HEADER_SIZE_BYTES);

                            // Marhsal header
                            var headerHandle = GCHandle.Alloc(this.sharedMemoryReadBuffer, GCHandleType.Pinned);
                            var header       = (rF2StateHeader)Marshal.PtrToStructure(headerHandle.AddrOfPinnedObject(), typeof(rF2StateHeader));
                            headerHandle.Free();

                            if (header.mCurrentRead == 1)
                            {
                                sharedMemoryStream.BaseStream.Position = 0;
                                this.sharedMemoryReadBuffer            = sharedMemoryStream.ReadBytes(this.SHARED_MEMORY_SIZE_BYTES);
                                buf1Current = true;
                            }
                        }

                        // Read buffer 2
                        if (!buf1Current)
                        {
                            using (var sharedMemoryStreamView = this.memoryMappedFile2.CreateViewStream())
                            {
                                var sharedMemoryStream = new BinaryReader(sharedMemoryStreamView);
                                this.sharedMemoryReadBuffer = sharedMemoryStream.ReadBytes(this.SHARED_MEMORY_SIZE_BYTES);
                            }
                        }
                    }
                    finally
                    {
                        this.fileAccessMutex.ReleaseMutex();
                    }

                    // Marshal rF2State
                    var handle = GCHandle.Alloc(this.sharedMemoryReadBuffer, GCHandleType.Pinned);
                    this.currrF2State = (rF2State)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(rF2State));
                    this.carData      = currrF2State.mVehicles[0];
                    this.wheel        = currrF2State.mWheels[0];
                    handle.Free();
                }
            }
            catch (Exception)
            {
                disconnect();
            }
        }
 public RubberTemperature(rF2Wheel wheel)
 {
     if (wheel.mTireInnerLayerTemperature != null)
     {
         Left   = wheel.mTireInnerLayerTemperature[0];
         Right  = wheel.mTireInnerLayerTemperature[1];
         Middle = wheel.mTireInnerLayerTemperature[2];
     }
 }
 public CarcassTemperature(rF2Wheel wheel)
 {
     Value = wheel.mTireCarcassTemperature;
 }