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(); } }
private rF2VehScoringInfo getVehicleInfo(rF2State shared) { for (int i = 0; i < shared.mNumVehicles; ++i) { var vehicle = shared.mVehicles[i]; if (vehicle.mIsPlayer == 1) { return(vehicle); } } throw new Exception("no vehicle for player!"); }
public override Object ReadGameData(Boolean forSpotter) { lock (this) { var rF2StateMarshalled = new rF2State(); if (!initialised) { if (!this.InitialiseInternal()) { throw new GameDataReadException("Failed to initialise shared memory"); } } try { 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); rF2StateMarshalled = (rF2State)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(rF2State)); handle.Free(); RF2StructWrapper structWrapper = new RF2StructWrapper(); structWrapper.ticksWhenRead = DateTime.Now.Ticks; structWrapper.state = rF2StateMarshalled; if (!forSpotter && dumpToFile && this.dataToDump != null) { this.dataToDump.Add(structWrapper); } return(structWrapper); } else { Console.WriteLine("Timed out waiting on rFactor 2 Shared Memory mutex."); return(null); } } catch (Exception ex) { Console.WriteLine("rFactor 2 Shared Memory connection failed."); this.Disconnect(); throw new GameDataReadException(ex.Message, ex); } } }