public List <Schematic> resolve(sharptest.ModLibrary library) { if (library == null) { throw new ArgumentNullException("library"); } if (this.contents.Count == 0 || this.connections.Count == 0) { return(null); } if (!isFullyConnected()) { throw new ApplicationException("schematic is not fully connected"); } foreach (Element elm in this.contents.Values) { elm.populateAvail(library); } Schematic all = this.Clone(); Dictionary <int, Element> .Enumerator firstEnum = all.contents.GetEnumerator(); firstEnum.MoveNext(); Element first = firstEnum.Current.Value; Dictionary <int, bool> seen = new Dictionary <int, bool>(); return(resolveImpl(library, all, seen, first.circuitId)); }
public Schematic Clone() { Dictionary <Element, Element> elmMap = new Dictionary <Element, Element>(); Schematic newOb = new Schematic(); newOb.genericID = this.genericID; foreach (Element elm in this.contents.Values) { Element newElm = elm.Clone(); newOb.add(newElm); elmMap.Add(elm, newElm); } foreach (KeyValuePair <EndpointKey, EndpointKey> entry in this.connections) { EndpointKey key = entry.Key; EndpointKey value = entry.Value; EndpointKey newKey = key.epString == null ? new EndpointKey(elmMap[key.elem], key.epIdx) : new EndpointKey(elmMap[key.elem], key.epString); EndpointKey newValue = value.epString == null ? new EndpointKey(elmMap[value.elem], value.epIdx) : new EndpointKey(elmMap[value.elem], value.epString); newOb.connections.Add(newKey, newValue); } return(newOb); }
private static List <Schematic> resolveImpl(sharptest.ModLibrary library, Schematic here, Dictionary <int, bool> seen, int elmKey) { if (seen.ContainsKey(elmKey)) { return new List <Schematic> { here } } ; if (!here.contents.ContainsKey(elmKey)) { throw new ApplicationException("couldn't kind elmKey in contents"); } Element elm = here.contents[elmKey]; seen.Add(elmKey, true); try { List <Schematic> answers = new List <Schematic>(); ResolveFailure failure = new ResolveFailure(); if (elm.availObjects.Count == 0) { failure.Add(new CannotResolveElement(elm)); } foreach (signals.ICircuitConnectible avail in elm.availObjects) { Schematic newSchem = here.Clone(); Element newElem = newSchem.contents[elmKey]; newElem.availObjects.Clear(); newElem.availObjects.Add(avail); try { newSchem.resolveNeighbors(library, newElem); } catch (ResolveFailureReason fault) { failure.Add(fault); continue; } Dictionary <int, bool> recurseList = new Dictionary <int, bool>(); foreach (KeyValuePair <EndpointKey, EndpointKey> entry in newSchem.connections) { EndpointKey key = entry.Key; EndpointKey value = entry.Value; if (key.elem == newElem) { if (!seen.ContainsKey(value.elem.circuitId)) { recurseList.Add(value.elem.circuitId, true); } } else if (value.elem == newElem) { if (!seen.ContainsKey(key.elem.circuitId)) { recurseList.Add(key.elem.circuitId, true); } } } List <Schematic> possibles = new List <Schematic>(); possibles.Add(newSchem); foreach (KeyValuePair <int, bool> entry in recurseList) { List <Schematic> prevPass = possibles; possibles = new List <Schematic>(); foreach (Schematic possible in prevPass) { try { possibles.AddRange(resolveImpl(library, possible, seen, entry.Key)); } catch (ResolveFailure fail) { failure.Add(fail); } } } answers.AddRange(possibles); } if (answers.Count == 0 && failure.reasons.Count > 0) { throw failure; } return(answers); } finally { seen.Remove(elmKey); } }