public static IEnumerable<DeviceInfo> GetShortInfo(string filename) { var devices = ((JsonObject)InitializeJSON(filename)).ToList(); // flattening peripheral groups var arrays = devices.Where(d => d.Value is JsonArray).ToList(); arrays.ForEach(a => devices.Remove(a)); arrays.Select(a => a.Value).Cast<JsonArray>().SelectMany(y => y).Cast<JsonObject>().ToList().ForEach(x => devices.AddRange(x)); foreach(var device in devices) { var info = new DeviceInfo(); info.Name = device.Key; dynamic devContent = device.Value; if(devContent == null) { FailDevice(device.Key); } if(!devContent.ContainsKey(TYPE_NODE)) { FailDevice(device.Key, TYPE_NODE); } var typeName = (string)devContent[TYPE_NODE]; var devType = GetDeviceTypeFromName(typeName); if(devType == null) { FailDevice(device.Key, TYPE_NODE); } info.Type = devType; if(devContent.ContainsKey(CONNECTION_NODE)) { InitializeConnections(info, devContent[CONNECTION_NODE]); } yield return info; } }
private void RegisterInParents(DeviceInfo device, IDictionary<string, IPeripheral> parents) { foreach(var parentName in device.Connections.Keys) { //TODO: nongeneric version var parent = parents.Single(x => x.Key == parentName).Value; var connections = device.Connections[parentName]; var ifaces = parent.GetType().GetInterfaces().Where(x => IsSpecializationOfRawGeneric(typeof(IPeripheralRegister<,>), x)).ToList(); var ifaceCandidates = ifaces.Where(x => x.GetGenericArguments()[0].IsAssignableFrom(device.Peripheral.GetType())).ToList(); foreach(var connection in connections) { IRegistrationPoint regPoint = null; Type formalType = null; if(connection.ContainsKey(TYPE_NODE)) { var name = (string)connection[TYPE_NODE]; formalType = GetDeviceTypeFromName(name); } Type foundIface = null; foreach(var iface in ifaceCandidates) { var iRegPoint = iface.GetGenericArguments()[1]; Type objType; if(formalType != null && iRegPoint.IsAssignableFrom(formalType)) { objType = formalType; } else { objType = iRegPoint; } object regPointObject; if(!TryInitializeCtor(objType, connection, out regPointObject)) { if(connection.Keys.Any() || !TryHandleSingleton(objType, out regPointObject)) { continue; } } regPoint = (IRegistrationPoint)regPointObject; foundIface = iface; break; //is a construable type } if(foundIface == null) { // let's try attachment through the AttachTo mechanism FailDevice(device.Name, "connection to " + parentName); } else { Dynamic.InvokeMemberAction(parent, "Register", new object[] { device.Peripheral, regPoint } ); } } } }
private static void InitializeConnections(DeviceInfo device, IDictionary<string, dynamic> connections) { if(connections == null) { FailDevice(device.Name, CONNECTION_NODE); } foreach(var container in connections.Keys) { var conDict = connections[container]; device.AddConnection(container, conDict); } }
private static void InitializeConnections(DeviceInfo device, string connection) { if(string.IsNullOrWhiteSpace(connection)) { FailDevice(device.Name, CONNECTION_NODE); } device.AddConnection(connection); }
private void InitializeGPIOsFrom(DeviceInfo device) { foreach(var nodeName in device.IrqsFrom.Keys) { var gpioReceiver = device.Peripheral as IGPIOReceiver; if(gpioReceiver == null) { FailDevice(device.Name, nodeName); } var irqs = device.IrqsFrom[nodeName]; if(irqs == null) { FailDevice(device.Name, nodeName); } foreach(var source in irqs.Keys) { var sourceIrqs = irqs[source] as List<dynamic>; if(sourceIrqs == null) { FailDevice(device.Name, nodeName + ": " + source); } IPeripheral sourcePeripheral; var fromList = deviceList.SingleOrDefault(x => x.Name == source); if(fromList != null) { sourcePeripheral = (IGPIOReceiver)fromList.Peripheral; } else if(!machine.TryGetByName<IPeripheral>(source, out sourcePeripheral)) { FailDevice(device.Name, nodeName + ": " + source); } if(sourcePeripheral is ILocalGPIOReceiver && source.Length == 2) { sourcePeripheral = ((ILocalGPIOReceiver)sourcePeripheral).GetLocalReceiver(int.Parse(source[1])); } var props = sourcePeripheral.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); var connectors = props .Where(x => typeof(GPIO).IsAssignableFrom(x.PropertyType)).ToArray(); PropertyInfo defaultConnector = null; if(connectors.Count() == 1) { defaultConnector = connectors.First(); } try { if(sourceIrqs.All(x => x is JsonArray)) { foreach(var irqEntry in sourceIrqs) { InitializeGPIO(sourcePeripheral, gpioReceiver, irqEntry.ToDynamic(), defaultConnector); } } else { InitializeGPIO(sourcePeripheral, gpioReceiver, ((JsonArray)sourceIrqs).ToDynamic(), defaultConnector); } } catch(ArgumentException) { FailDevice(device.Name, nodeName + ": " + source); } } } }
private void InitializeGPIOs(DeviceInfo device) { foreach(var nodeName in device.Irqs.Keys) { var irqs = device.Irqs[nodeName]; if(irqs == null) { FailDevice(device.Name, nodeName); } var props = device.Peripheral.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); var connectors = props .Where(x => typeof(GPIO).IsAssignableFrom(x.PropertyType)).ToArray(); PropertyInfo defaultConnector = null; if(connectors.Count() == 1) { defaultConnector = connectors.First(); } foreach(var controller in irqs.Keys) { var controllerIrqs = irqs[controller] as List<dynamic>; if(controllerIrqs == null) { FailDevice(device.Name, nodeName + ": " + controller); } var controllerElements = controller.Split('#'); if(controllerElements.Length > 2) { FailDevice(device.Name, nodeName + ": " + controller); } IGPIOReceiver receiver; var fromList = deviceList.SingleOrDefault(x => x.Name == controllerElements[0]); if(fromList != null && fromList.Peripheral is IGPIOReceiver) { receiver = (IGPIOReceiver)fromList.Peripheral; } else if(!machine.TryGetByName<IGPIOReceiver>(controllerElements[0], out receiver)) { FailDevice(device.Name, nodeName + ": " + controller); } if(receiver is ILocalGPIOReceiver && controllerElements.Length == 2) { receiver = ((ILocalGPIOReceiver)receiver).GetLocalReceiver(int.Parse(controllerElements[1])); } try { if(controllerIrqs.All(x => x is JsonArray)) { foreach(var irqEntry in controllerIrqs) { InitializeGPIO(device.Peripheral, receiver, irqEntry.ToDynamic(), defaultConnector); } } else { InitializeGPIO(device.Peripheral, receiver, ((JsonArray)controllerIrqs).ToDynamic(), defaultConnector); } } catch(ArgumentException) { FailDevice(device.Name, nodeName + ": " + controller); } } } }
/// Required/possible nodes: /// _type /// _irq/_gpio - optional /// _connection - optional? /// ctorParam /// PropertyWithSetter private DeviceInfo InitializeSingleDevice(KeyValuePair<string, dynamic> device, string groupName = null) { var info = new DeviceInfo(); info.Name = device.Key; var devContent = device.Value; if(devContent == null) { FailDevice(info.Name); } //Type if(!devContent.ContainsKey(TYPE_NODE)) { FailDevice(info.Name, TYPE_NODE); } var typeName = (string)devContent[TYPE_NODE]; var devType = GetDeviceTypeFromName(typeName); if(devType == null) { FailDevice(info.Name, TYPE_NODE); } object peripheral; //Constructor if(!TryInitializeCtor(devType, devContent, out peripheral)) { FailDevice(info.Name, "constructor_invoke"); } if(peripheral == null) { // special case when construction of the object has been deferred deferred.Add(device, groupName); return null; } devContent.Remove(TYPE_NODE); info.Peripheral = (IPeripheral)peripheral; //Properties try { InitializeProperties(info.Peripheral, devContent); } catch(InvalidOperationException e) { FailDevice(info.Name, e.Message, e.InnerException); } //GPIOs if(devContent.ContainsKey(IRQ_NODE)) { info.AddIrq(IRQ_NODE, devContent[IRQ_NODE]); devContent.Remove(IRQ_NODE); } else if(devContent.ContainsKey(GPIO_NODE)) { info.AddIrq(GPIO_NODE, devContent[GPIO_NODE]); devContent.Remove(GPIO_NODE); } //IRQs From if(devContent.ContainsKey(IRQ_FROM_NODE)) { info.AddIrqFrom(IRQ_FROM_NODE, devContent[IRQ_FROM_NODE]); devContent.Remove(IRQ_FROM_NODE); } else if(devContent.ContainsKey(GPIO_FROM_NODE)) { info.AddIrqFrom(GPIO_FROM_NODE, devContent[GPIO_FROM_NODE]); devContent.Remove(GPIO_FROM_NODE); } //Connections if(devContent.ContainsKey(CONNECTION_NODE)) { InitializeConnections(info, devContent[CONNECTION_NODE]); devContent.Remove(CONNECTION_NODE); } return info; }
private void RegisterInParents(DeviceInfo device, IDictionary <string, IPeripheral> parents) { foreach (var parentName in device.Connections.Keys) { //TODO: nongeneric version var parent = parents.Single(x => x.Key == parentName).Value; var connections = device.Connections[parentName]; var ifaces = parent.GetType().GetInterfaces().Where(x => IsSpecializationOfRawGeneric(typeof(IPeripheralRegister <,>), x)).ToList(); var ifaceCandidates = ifaces.Where(x => x.GetGenericArguments()[0].IsAssignableFrom(device.Peripheral.GetType())).ToList(); foreach (var connection in connections) { IRegistrationPoint regPoint = null; Type formalType = null; if (connection.ContainsKey(TYPE_NODE)) { var name = (string)connection[TYPE_NODE]; formalType = GetDeviceTypeFromName(name); } Type foundIface = null; foreach (var iface in ifaceCandidates) { var iRegPoint = iface.GetGenericArguments()[1]; Type objType; if (formalType != null && iRegPoint.IsAssignableFrom(formalType)) { objType = formalType; } else { objType = iRegPoint; } object regPointObject; if (!TryInitializeCtor(objType, connection, out regPointObject)) { if (connection.Keys.Any() || !TryHandleSingleton(objType, out regPointObject)) { continue; } } regPoint = (IRegistrationPoint)regPointObject; foundIface = iface; break; //is a construable type } if (foundIface == null) { // let's try attachment through the AttachTo mechanism FailDevice(device.Name, "connection to " + parentName); } else { Dynamic.InvokeMemberAction(parent, "Register", new object[] { device.Peripheral, regPoint } ); } } } }
private void InitializeGPIOs(DeviceInfo device) { foreach (var nodeName in device.Irqs.Keys) { var irqs = device.Irqs[nodeName]; if (irqs == null) { FailDevice(device.Name, nodeName); } var props = device.Peripheral.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); var connectors = props .Where(x => typeof(GPIO).IsAssignableFrom(x.PropertyType)).ToArray(); PropertyInfo defaultConnector = null; if (connectors.Count() == 1) { defaultConnector = connectors.First(); } foreach (var controller in irqs.Keys) { var controllerIrqs = irqs[controller] as List <dynamic>; if (controllerIrqs == null) { FailDevice(device.Name, nodeName + ": " + controller); } var controllerElements = controller.Split('#'); if (controllerElements.Length > 2) { FailDevice(device.Name, nodeName + ": " + controller); } IGPIOReceiver receiver; var fromList = deviceList.SingleOrDefault(x => x.Name == controllerElements[0]); if (fromList != null && fromList.Peripheral is IGPIOReceiver) { receiver = (IGPIOReceiver)fromList.Peripheral; } else if (!machine.TryGetByName <IGPIOReceiver>(controllerElements[0], out receiver)) { FailDevice(device.Name, nodeName + ": " + controller); } if (receiver is ILocalGPIOReceiver && controllerElements.Length == 2) { receiver = ((ILocalGPIOReceiver)receiver).GetLocalReceiver(int.Parse(controllerElements[1])); } try { if (controllerIrqs.All(x => x is JsonArray)) { foreach (var irqEntry in controllerIrqs) { InitializeGPIO(device.Peripheral, device.Name, receiver, irqEntry.ToDynamic(), defaultConnector); } } else { InitializeGPIO(device.Peripheral, device.Name, receiver, ((JsonArray)controllerIrqs).ToDynamic(), defaultConnector); } } catch (ArgumentException) { FailDevice(device.Name, nodeName + ": " + controller); } } } }
private void InitializeGPIOsFrom(DeviceInfo device) { foreach (var nodeName in device.IrqsFrom.Keys) { var gpioReceiver = device.Peripheral as IGPIOReceiver; if (gpioReceiver == null) { FailDevice(device.Name, nodeName); } var irqs = device.IrqsFrom[nodeName]; if (irqs == null) { FailDevice(device.Name, nodeName); } foreach (var source in irqs.Keys) { var sourceIrqs = irqs[source] as List <dynamic>; if (sourceIrqs == null) { FailDevice(device.Name, nodeName + ": " + source); } IPeripheral sourcePeripheral; var fromList = deviceList.SingleOrDefault(x => x.Name == source); if (fromList != null) { sourcePeripheral = (IGPIOReceiver)fromList.Peripheral; } else if (!machine.TryGetByName <IPeripheral>(source, out sourcePeripheral)) { FailDevice(device.Name, nodeName + ": " + source); } if (sourcePeripheral is ILocalGPIOReceiver && source.Length == 2) { sourcePeripheral = ((ILocalGPIOReceiver)sourcePeripheral).GetLocalReceiver(int.Parse(source[1])); } var props = sourcePeripheral.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); var connectors = props .Where(x => typeof(GPIO).IsAssignableFrom(x.PropertyType)).ToArray(); PropertyInfo defaultConnector = null; if (connectors.Count() == 1) { defaultConnector = connectors.First(); } try { if (sourceIrqs.All(x => x is JsonArray)) { foreach (var irqEntry in sourceIrqs) { InitializeGPIO(sourcePeripheral, device.Name, gpioReceiver, irqEntry.ToDynamic(), defaultConnector); } } else { InitializeGPIO(sourcePeripheral, device.Name, gpioReceiver, ((JsonArray)sourceIrqs).ToDynamic(), defaultConnector); } } catch (ArgumentException) { FailDevice(device.Name, nodeName + ": " + source); } } } }
/// Required/possible nodes: /// _type /// _irq/_gpio - optional /// _connection - optional? /// ctorParam /// PropertyWithSetter private DeviceInfo InitializeSingleDevice(KeyValuePair <string, dynamic> device, string groupName = null) { var info = new DeviceInfo(); info.Name = device.Key; var devContent = device.Value; if (devContent == null) { FailDevice(info.Name); } //Type if (!devContent.ContainsKey(TYPE_NODE)) { FailDevice(info.Name, TYPE_NODE); } var typeName = (string)devContent[TYPE_NODE]; var devType = GetDeviceTypeFromName(typeName); if (devType == null) { FailDevice(info.Name, TYPE_NODE); } object peripheral; //Constructor if (!TryInitializeCtor(devType, devContent, out peripheral)) { FailDevice(info.Name, "constructor_invoke"); } if (peripheral == null) { // special case when construction of the object has been deferred deferred.Add(device, groupName); return(null); } devContent.Remove(TYPE_NODE); info.Peripheral = (IPeripheral)peripheral; //Properties try { InitializeProperties(info.Peripheral, devContent); } catch (InvalidOperationException e) { FailDevice(info.Name, e.Message, e.InnerException); } //GPIOs if (devContent.ContainsKey(IRQ_NODE)) { info.AddIrq(IRQ_NODE, devContent[IRQ_NODE]); devContent.Remove(IRQ_NODE); } else if (devContent.ContainsKey(GPIO_NODE)) { info.AddIrq(GPIO_NODE, devContent[GPIO_NODE]); devContent.Remove(GPIO_NODE); } //IRQs From if (devContent.ContainsKey(IRQ_FROM_NODE)) { info.AddIrqFrom(IRQ_FROM_NODE, devContent[IRQ_FROM_NODE]); devContent.Remove(IRQ_FROM_NODE); } else if (devContent.ContainsKey(GPIO_FROM_NODE)) { info.AddIrqFrom(GPIO_FROM_NODE, devContent[GPIO_FROM_NODE]); devContent.Remove(GPIO_FROM_NODE); } //Connections if (devContent.ContainsKey(CONNECTION_NODE)) { InitializeConnections(info, devContent[CONNECTION_NODE]); devContent.Remove(CONNECTION_NODE); } return(info); }