public void EnumerateDevices(UnrealTargetConstraint Constraint, Func <ITargetDevice, bool> Predicate) { lock (LockObject) { List <ITargetDevice> Selection = new List <ITargetDevice>(); // randomize the order of all devices that are of this platform var MatchingProvisionedDevices = AvailableDevices.Where(D => Constraint.Check(D)).ToList(); var MatchingUnprovisionedDevices = UnprovisionedDevices.Where(D => D.Platform == Constraint.Platform && Constraint.IsIdentity()).ToList(); bool OutOfDevices = false; bool ContinuePredicate = true; do { // Go through all our provisioned devices to see if these fulfill the predicates // requirements ITargetDevice NextDevice = MatchingProvisionedDevices.FirstOrDefault(); while (NextDevice != null && ContinuePredicate) { Log.Verbose("Checking {0} against predicate", NextDevice.Name); MatchingProvisionedDevices.Remove(NextDevice); ContinuePredicate = Predicate(NextDevice); NextDevice = MatchingProvisionedDevices.FirstOrDefault(); } if (ContinuePredicate) { // add more devices if possible OutOfDevices = MatchingUnprovisionedDevices.Count() == 0; DeviceDefinition NextDeviceDef = MatchingUnprovisionedDevices.FirstOrDefault(); if (NextDeviceDef != null) { Log.Verbose("Provisioning device {0} for the pool", NextDeviceDef.Name); // try to create a device. This can fail, but if so we'll just end up back here // on the next iteration ITargetDevice NewDevice = CreateAndRegisterDeviceFromDefinition(NextDeviceDef); MatchingUnprovisionedDevices.Remove(NextDeviceDef); UnprovisionedDevices.Remove(NextDeviceDef); if (NewDevice != null) { MatchingProvisionedDevices.Add(NewDevice); Log.Verbose("Added device {0} to pool", NewDevice.Name); } else { Log.Info("Failed to provision {0}", NextDeviceDef.Name); // track this if (FailedProvisions.Contains(NextDeviceDef) == false) { FailedProvisions.Add(NextDeviceDef); } } } else { Log.Info("Pool ran out of devices of type {0}!", Constraint); OutOfDevices = true; } } } while (OutOfDevices == false && ContinuePredicate); } }
/// <summary> /// Returns the number of available devices of the provided type. This includes unprovisioned devices but not reserved ones /// Note: unprovisioned devices are currently only returned when device is not constrained /// </summary> public int GetTotalDeviceCount(UnrealTargetConstraint Constraint, Func <ITargetDevice, bool> Validate = null) { lock (LockObject) { return(AvailableDevices.Union(ReservedDevices).Where(D => Validate == null ? Constraint.Check(D) : Validate(D)).Count() + UnprovisionedDevices.Where(D => D.Platform == Constraint.Platform && Constraint.IsIdentity()).Count()); } }