public async Task Execute <TMessage>(IDeviceDefinition <TMessage> definition, Func <int, TMessage> messageFactory = null) { async Task HandleStream(IDeviceAdapter device) { if (device.TryOpen(out var stream)) { using (stream ?? throw new ApplicationException()) { var streamDevice = new StreamDevice <TMessage>(device, definition, _token);//stream, streamDevice.MessageReceived += (s, e) => Console.WriteLine(e); // streamDevice.DeviceStatus += (s, e) => Console.WriteLine($"Status: {e}"); streamDevice.MessageReceivedError += (s, e) => { Console.Error.WriteLine(e.Exception.Message); e.ErrorHandling = ErrorHandling.Ignore; }; streamDevice.MessageTrasmitterError += (s, e) => { Console.Error.WriteLine(e.Exception.Message); e.ErrorHandling = ErrorHandling.Ignore; }; Task?uiTasks = null; if (messageFactory != null && streamDevice is IDeviceTransmitter <TMessage> transmitter) { uiTasks = UserInteractionAsync(transmitter, messageFactory); } await Task.WhenAll( Task.Run(() => { Console.WriteLine("Enter to exit"); Console.ReadLine(); _tokenSource.Cancel(); Console.WriteLine("Done!"); }, _tokenSource.Token), uiTasks ?? Task.FromResult(0), streamDevice.Runner ); } } throw new ApplicationException($"{device} Not found"); } if (usbHid.CanGetDevice(definition)) { var device = GetHidDevice(definition); await HandleStream(device); } else if (serial.CanGetDevice(definition)) { var device = GetSerialPort(definition); await HandleStream(device); } }
public StreamDevice( IDeviceAdapter adapter, IDeviceDefinition device, CancellationToken token = default, int minimumTrasmissionDelay = 1000 //TODO should this default be overideable from the devicedefinition or it's attributes? ) { _tokenSource = CancellationTokenSource.CreateLinkedTokenSource(token); _token = _tokenSource.Token; _adapter = adapter; _device = device; _minimumTrasmissionDelay = minimumTrasmissionDelay; Task?messageReceiver = null; Task?messageTransmitter = null; Task?deviceInitializer = null; var mre = new AsyncManualResetEvent(); if (_device is IDeviceDefinitionInitialize) { mre.Reset(); deviceInitializer = Initializer(mre); } else { //Assumed to start in set state but just be sure anyway mre.Set(); } if (_device is IDeviceDefinitionReceiver <TMessage> receiver) { _decoder = receiver.Decoder; _segmentDefintion = receiver.SegmentDefintion; messageReceiver = Receiver(mre); } if (_device is IDeviceDefinitionTransmitter <TMessage> transmitter) { _encoder = transmitter.Encoder; messageTransmitter = Transmitter(mre); } Runner = Task.WhenAll( deviceInitializer ?? Task.FromResult(0), messageReceiver ?? Task.FromResult(0), messageTransmitter ?? Task.FromResult(0) ); }
/// <summary> /// populate DeviceDefinition object with config strings from mednafen config /// </summary> /// <param name="deviceDef"></param> public static void PopulateConfig(IDeviceDefinition deviceDef) { // get all config strings from the mednafen config file that match the 'CommandStart' property of deviceDef List <string> cfgs = File.ReadAllLines(Paths.GetPaths().mednafenExe + @"\mednafen-09x.cfg").Where(a => a.Contains(deviceDef.CommandStart)).ToList(); // iterate through each mapping and set the config string for (int i = 0; i < deviceDef.MapList.Count; i++) { string cName = deviceDef.MapList[i].MednafenCommand; // look up the config command in the string list string lookup = (from a in cfgs where a.Contains(cName + " ") select a).FirstOrDefault(); if (lookup == null || lookup == "" || lookup == " ") { // command wasnt found continue; } // if there is no config set for this command - continue if (!lookup.Contains(" ")) { continue; } // command was found - get just the config details string[] arr = lookup.Split(' '); // build the new string without the command StringBuilder sb = new StringBuilder(); for (int c = 1; c < arr.Length; c++) { sb.Append(arr[c]); sb.Append(" "); } string cfg = sb.ToString().TrimEnd(); // update deviceDef with the config deviceDef.MapList[i].Config = cfg; } }
/// <summary> /// populate DeviceDefinition object with config strings from mednafen config /// </summary> /// <param name="deviceDef"></param> public static void PopulateConfig(IDeviceDefinition deviceDef) { // get all config strings from the mednafen config file that match the 'CommandStart' property of deviceDef List <string> cfgs = File.ReadAllLines(Paths.GetPaths().mednafenExe + @"\mednafen.cfg").Where(a => a.Contains(deviceDef.CommandStart)).ToList(); // iterate through each mapping and set the config string for (int i = 0; i < deviceDef.MapList.Count; i++) { string cName = deviceDef.MapList[i].MednafenCommand; // look up the config command in the string list string lookup = (from a in cfgs where a.Contains(cName + " ") select a).FirstOrDefault(); if (lookup == null || lookup == "" || lookup == " ") { // command wasnt found continue; } // if there is no config set for this command - continue if (!lookup.Contains(" ")) { continue; } // command was found - get just the config details string[] arr = lookup.Split(' '); if (arr.Length < 3) { // command is not set continue; } // get the string again without the command string justBindings = lookup.Replace(cName, "").TrimStart(); arr = justBindings.Split(' '); // our array should now have the full config command - skip the first index (mednafen command) // and iterate through - each 'block' // denotes the position within the string // i.e. if logic functions are involved int location = 0; int lastLength = 0; // calculate the blocks lengths int blockPri = 0; int blockSec = 0; int blockTer = 0; int blockIndex = 0; bool isFin = false; for (int cou = 0; cou < arr.Length; cou++) { if (isFin) { break; } switch (blockIndex) { case 0: if (arr[cou] == "||" || arr[cou] == "&&" || arr[cou] == "&!") { // this is a logic operator blockIndex++; } blockPri++; break; case 1: if (arr[cou] == "||" || arr[cou] == "&&" || arr[cou] == "&!") { // this is a logic operator blockIndex++; } blockSec++; break; case 2: if (arr[cou] == "||" || arr[cou] == "&&" || arr[cou] == "&!") { // this is a logic operator blockIndex++; } blockTer++; break; default: // we dont support more than 3 isFin = true; break; } } // now process each block if (blockPri > 2) { string[] blockPriArr = arr.Take(blockPri).ToArray(); deviceDef.MapList[i].Primary = ProcessBlock(blockPriArr); } if (blockSec > 2) { string[] blockSecArr = arr.Skip(blockPri).Take(blockSec).ToArray(); deviceDef.MapList[i].Secondary = ProcessBlock(blockSecArr); } if (blockTer > 2) { string[] blockTerArr = arr.Skip(blockPri + blockSec).Take(blockTer).ToArray(); deviceDef.MapList[i].Tertiary = ProcessBlock(blockTerArr); } // update deviceDef with the full config string deviceDef.MapList[i].Config = justBindings; } // iterate through the custom objects if (deviceDef.CustomOptions != null) { for (int i = 0; i < deviceDef.CustomOptions.Count(); i++) { string cName = deviceDef.CustomOptions[i].MednafenCommand; // look up the config command in the string list string lookup = (from a in cfgs where a.Contains(cName + " ") select a).FirstOrDefault(); if (lookup == null || lookup == "" || lookup == " ") { // command wasnt found continue; } // if there is no config set for this command - continue if (!lookup.Contains(" ")) { continue; } // command was found - get just the config details string[] arr = lookup.Split(' '); // [0] should be the command, [1] the value deviceDef.CustomOptions[i].Config = arr[1].Trim(); } } }