internal IEnumerable <Connection> UpdateConnections(ILayoutAccess layout) { List <Pin> newInputs = new List <Pin>(); List <PinOut> newOutputs = new List <PinOut>(); foreach (Component comp in layout.Components) { if (comp is Pin) { newInputs.Add((Pin)comp); } else if (comp is PinOut) { newOutputs.Add((PinOut)comp); } } newInputs.Sort((p0, p1) => Location.YComparer.Compare(p0.GetLocation(layout), p1.GetLocation(layout))); newOutputs.Sort((p0, p1) => Location.YComparer.Compare(p0.GetLocation(layout), p1.GetLocation(layout))); List <Connection> conns = new List <Connection>(); foreach (Pin p in newInputs) { conns.Add(new Connection(true)); } foreach (PinOut p in newOutputs) { conns.Add(new Connection(false)); } inputs = newInputs; outputs = newOutputs; this.Connections = conns; return(conns); }
public void LayoutChanged(ILayoutAccess layout) { List <LayoutNode> newNodes = new List <LayoutNode>(); IEnumerable <LocationSet> curSetNodes = getCurrentLocationSets(layout); List <LayoutNode> changedNodes = determineNodes(curSetNodes, newNodes); Dictionary <Location, LayoutNode> locNodes = new Dictionary <Location, LayoutNode>(); foreach (LayoutNode n in newNodes) { foreach (Location loc in n.locs) { locNodes[loc] = n; } } this.curNodes = newNodes; this.locNodes = locNodes; if (Debug) { if (changedNodes.Count == 0) { Console.Error.WriteLine("no changes"); } else { Console.Error.WriteLine("changes:"); foreach (LayoutNode n in changedNodes) { Console.Error.WriteLine(" {0}: {1}->{2}", n.id, n.prev, n.locs); } } } }
public void Execute(Action <ILayoutAccess> action) { Transaction xn = new Transaction(); ILayoutAccess lo = xn.RequestWriteAccess(Layout); using (xn.Start()) { action(lo); } }
public GesturePoke(LayoutCanvasModel layoutModel, ComponentInstance poking) { this.layoutModel = layoutModel; this.poking = poking; Transaction xn = new Transaction(); ILayoutAccess layout = xn.RequestReadAccess(layoutModel.Layout); using (xn.Start()) { pokingLocation = poking.Component.GetLocation(layout); } }
public GestureTranslate(LayoutCanvasModel layoutCanvas, ComponentInstance moving) { this.layoutCanvas = layoutCanvas; this.moving = moving; Transaction xn = new Transaction(); ILayoutAccess layout = xn.RequestReadAccess(layoutCanvas.Layout); using (xn.Start()) { this.movingLocation = moving.Component.GetLocation(layout); } }
private IGesture GetGesture(IPointerEvent evnt, bool considerPoke) { if (layoutCanvas.WiringPoints == null) { return(null); } Location eLoc = new Location(evnt.X, evnt.Y); Location snapLoc = Constants.SnapToGrid(eLoc); if (layoutCanvas.WiringPoints.Contains(snapLoc)) { int d2 = eLoc.GetDistance2(snapLoc); if (d2 < 16 * 16) { return(new GestureWire(layoutCanvas, snapLoc)); } } Instance found = null; Transaction xn = new Transaction(); ILayoutAccess lo = xn.RequestReadAccess(layoutCanvas.Layout); using (xn.Start()) { foreach (Component component in lo.Components) { Location iloc = component.GetLocation(lo); if (component.Contains(eLoc.X - iloc.X, eLoc.Y - iloc.Y)) { found = layoutCanvas.LayoutSim.GetInstance(lo, component); } } } ComponentInstance foundComp = found as ComponentInstance; if (foundComp != null) { if (considerPoke && foundComp.Component is Pokeable) { return(new GesturePoke(layoutCanvas, foundComp)); } else { return(new GestureTranslate(layoutCanvas, foundComp)); } } else { return(new GesturePan(layoutCanvas)); } }
public Value GetValueAt(ILayoutAccess layout, ISimulationAccess sim, Location loc) { layout.CheckReadAccess(); sim.CheckReadAccess(); LayoutNode sup = layout.FindNode(loc); if (nodeMap.ContainsKey(sup)) { return(sim.Get(nodeMap[sup])); } else { return(Value.X); } }
private IEnumerable <LocationSet> getCurrentLocationSets(ILayoutAccess layout) { HashSet <Location> locs = new HashSet <Location>(); foreach (WireSegment w in layout.Wires) { locs.Add(w.End0); locs.Add(w.End1); } foreach (Component c in layout.Components) { Location cloc = c.GetLocation(layout); foreach (ConnectionPoint p in c.Connections) { locs.Add(cloc.Translate(p.Dx, p.Dy)); } } UnionFind <Location> allNodes = new UnionFind <Location>(locs); foreach (WireSegment w in layout.Wires) { UnionFindNode <Location> e0 = allNodes[w.End0]; UnionFindNode <Location> e1 = allNodes[w.End1]; e0.Unite(e1); } IEnumerable <UnionFindNode <Location> > roots = allNodes.Roots; List <LocationSet> result = new List <LocationSet>(); foreach (UnionFindNode <Location> root in roots) { IEnumerable <UnionFindNode <Location> > rootMembers = root.GetSetMembers(); List <Location> setMembers = new List <Location>(); foreach (UnionFindNode <Location> n in rootMembers) { setMembers.Add(n.Value); } result.Add(new LocationSet(setMembers)); } return(result); }
public void Update() { Dictionary <Location, PointData> pts = new Dictionary <Location, PointData>(); Transaction xn = new Transaction(); ILayoutAccess lo = xn.RequestReadAccess(layout); using (xn.Start()) { foreach (WireSegment wire in lo.Wires) { GetPointData(pts, wire.End0).AddWireEnding(wire); GetPointData(pts, wire.End1).AddWireEnding(wire); foreach (Location loc in wire.GetLocationsOnWire(Constants.GRID_SIZE, false)) { GetPointData(pts, loc).AddWireContaining(wire); } } foreach (Component component in lo.Components) { Location iloc = component.GetLocation(lo); int i = -1; foreach (ConnectionPoint port in component.Connections) { i++; Location loc = iloc.Translate(port.Dx, port.Dy); GetPointData(pts, loc).AddPort(component, i); } } } List <Location> newSolders = new List <Location>(); foreach (KeyValuePair <Location, PointData> entry in pts) { if (entry.Value.IsSolderPoint()) { newSolders.Add(entry.Key); } } wiringPoints = pts; solderPoints = newSolders; }
private void RenewPortLinks(ILayoutAccess subLayout, ISimulationAccess sim) { IEnumerator <Port> ports = this.Ports.GetEnumerator(); IEnumerator <Component> pins = subLayout.Pins.GetEnumerator(); while (ports.MoveNext() && pins.MoveNext()) { Port compPort = ports.Current; Component pin = pins.Current; Instance pinInstance = subSimulation.GetInstance(subLayout, pin); if (pinInstance != null) { Port pinPort = null; foreach (Port tempPinPort in pinInstance.Ports) { pinPort = tempPinPort; break; } List <Link> toRemove = new List <Link>(2); foreach (Node nbr in pinPort.Neighbors) { if (nbr is Port && nbr != compPort) { toRemove.Add(new Link(pinPort, nbr)); } } foreach (Node nbr in compPort.Neighbors) { if (nbr is Port && nbr != pinPort) { toRemove.Add(new Link(compPort, nbr)); } } foreach (Link outLink in toRemove) { sim.RemoveLink(outLink); } sim.AddLink(new Link(compPort, pinPort)); } } }
protected override void HandleEventHook(InstanceEvent evnt, IInstanceState state) { SimulationModel simModel = null; if (evnt is SimulationInstanceEvent) { simModel = ((SimulationInstanceEvent)evnt).SimulationModel; } if (evnt.Type == InstanceEvent.Types.InstanceAdded) { Transaction xn = new Transaction(); ILayoutAccess subLayout = xn.RequestReadAccess(subLayoutModel); ISimulationAccess sim = xn.RequestWriteAccess(simModel); using (xn.Start()) { subSimulation = new LayoutSimulation(simModel, subLayoutModel); subSimulation.SetActivated(true); RenewPortLinks(subLayout, sim); } } else if (evnt.Type == InstanceEvent.Types.InstancePortsChanged) { if (simModel == null) { simModel = subSimulation.SimulationModel; } if (subLayoutModel == null || simModel == null) { return; } Transaction xn = new Transaction(); ILayoutAccess subLayout = xn.RequestReadAccess(subLayoutModel); ISimulationAccess sim = xn.RequestWriteAccess(simModel); using (xn.Start()) { RenewPortLinks(subLayout, sim); } } else if (evnt.Type == InstanceEvent.Types.InstanceRemoved) { subSimulation.SetActivated(false); } }
public static void CheckForSplits(ILayoutAccess lo, LayoutWiringPoints wireData, IEnumerable <Component> toCheck) { Dictionary <WireSegment, List <Location> > breaks = new Dictionary <WireSegment, List <Location> >(); foreach (Component comp in toCheck) { foreach (ConnectionPoint p in comp.Connections) { Location pLoc = comp.GetLocation(lo).Translate(p.Dx, p.Dy); foreach (WireSegment w in wireData.GetWiresContaining(pLoc)) { List <Location> wLocs; bool found = breaks.TryGetValue(w, out wLocs); if (!found) { wLocs = new List <Location>(); breaks[w] = wLocs; } wLocs.Add(pLoc); } } } foreach (WireSegment w in breaks.Keys) { lo.RemoveWire(w); List <Location> result = breaks[w]; result.Add(w.End0); result.Add(w.End1); result.Sort(Location.XComparer); Location p0 = result[0]; foreach (Location p1 in result) { if (p0 != p1) { lo.AddWire(p0, p1); p0 = p1; } } } }
private static void AddWireSegment(ILayoutAccess lo, LayoutWiringPoints wiringData, WireSegment proposedSeg) { Location loc0 = proposedSeg.End0; Location loc1 = proposedSeg.End1; Dictionary <WireSegment, Location?> intersects = new Dictionary <WireSegment, Location?>(); List <Location> breaks = new List <Location>(); foreach (WireSegment w in wiringData.GetWiresContaining(loc0)) { intersects[w] = intersects.ContainsKey(w) ? (Location?)null : loc0; } foreach (WireSegment w in wiringData.GetWiresContaining(loc1)) { intersects[w] = intersects.ContainsKey(w) ? (Location?)null : loc1; } foreach (Location loc in proposedSeg.GetLocationsOnWire(Constants.GRID_SIZE, false)) { foreach (WireSegment w in wiringData.GetWiresEndingAt(loc)) { intersects[w] = intersects.ContainsKey(w) ? (Location?)null : loc; } if (wiringData.IsPortAt(loc)) { breaks.Add(loc); } } List <WireSegment> toRemove = new List <WireSegment>(); List <WireSegment> toAdd = new List <WireSegment>(); List <Location> endpoints = new List <Location>(); endpoints.Add(loc0); endpoints.Add(loc1); foreach (WireSegment w in intersects.Keys) { Location?intersect = intersects[w]; if (!intersect.HasValue) // segment crosses both endpoints - delete subsegment { toRemove.Add(w); } else if (w.IsCollinear(proposedSeg, Constants.GRID_SIZE)) { toRemove.Add(w); endpoints.Add(w.End0); endpoints.Add(w.End1); } else // segment crosses over this one - maybe we should split it { Location at = intersect.Value; breaks.Add(at); if (at != w.End0 && at != w.End1) { toRemove.Add(w); toAdd.Add(new WireSegment(w.End0, at)); toAdd.Add(new WireSegment(at, w.End1)); } } } endpoints.Sort(Location.XComparer); breaks.Add(endpoints[0]); breaks.Add(endpoints[endpoints.Count - 1]); breaks.Sort(Location.XComparer); Location cur = breaks[0]; foreach (Location loc in breaks) { if (cur != loc) { toAdd.Add(new WireSegment(cur, loc)); cur = loc; } } foreach (WireSegment seg in toRemove) { lo.RemoveWire(seg); } foreach (WireSegment seg in toAdd) { lo.AddWire(seg.End0, seg.End1); } }
public static void CheckForMerges(ILayoutAccess lo, LayoutWiringPoints wireData, IEnumerable <Location> toCheck) { HashSet <Location> done = new HashSet <Location>(); HashSet <WireSegment> toMerge = new HashSet <WireSegment>(); List <WireSegment> w0s = new List <WireSegment>(); List <WireSegment> w1s = new List <WireSegment>(); foreach (Location loc in toCheck) { if (!done.Contains(loc) && !wireData.IsPortAt(loc)) { done.Add(loc); WireSegment w0 = null; WireSegment w1 = null; bool moreFound = false; foreach (WireSegment w in wireData.GetWiresEndingAt(loc)) { if (w0 == null) { w0 = w; } else if (w1 == null) { w1 = w; } else { moreFound = true; break; } } if (!moreFound && w1 != null && w0.IsCollinear(w1, Constants.GRID_SIZE)) { w0s.Add(w0); w1s.Add(w1); toMerge.Add(w0); toMerge.Add(w1); } } } UnionFind <WireSegment> uf = new UnionFind <WireSegment>(toMerge); for (int i = 0; i < w0s.Count; i++) { uf[w0s[i]].Unite(uf[w1s[i]]); } foreach (UnionFindNode <WireSegment> root in uf.Roots) { List <Location> locs = new List <Location>(); foreach (UnionFindNode <WireSegment> member in root.GetSetMembers()) { WireSegment w = member.Value; lo.RemoveWire(w); locs.Add(w.End0); locs.Add(w.End1); } locs.Sort(Location.XComparer); lo.AddWire(locs[0], locs[locs.Count - 1]); } }
private void Configure(ILayoutAccess layout) { activated = true; Transaction xn = new Transaction(); ISimulationAccess sim = xn.RequestWriteAccess(simModel); if (layout == null) { layout = xn.RequestReadAccess(this.LayoutModel); } using (xn.Start()) { foreach (LayoutNode node in layout.Nodes) { if (!nodeMap.ContainsKey(node)) { nodeMap[node] = new Node(); } } foreach (Component comp in layout.Components) { if (!instanceMap.ContainsKey(comp)) { Instance instance = comp.CreateInstance(); instanceMap[comp] = instance; sim.AddInstance(instance); } } if (Debug) { Console.WriteLine("Circuit edited"); } foreach (Component comp in layout.Components) { Location compLoc = comp.GetLocation(layout); String cstr = null; Instance instance = instanceMap[comp]; IEnumerator <ConnectionPoint> conns = comp.Connections.GetEnumerator(); IEnumerator <Port> ports = instance.Ports.GetEnumerator(); int i = -1; while (conns.MoveNext() && ports.MoveNext()) { i++; ConnectionPoint conn = conns.Current; Port port = ports.Current; Location connLoc = compLoc.Translate(conn.Dx, conn.Dy); if (Debug) { if (i == 0) { cstr = String.Format("{0}[{1}]", comp.GetType().Name, compLoc.ToString()); } else { cstr = String.Format("{0," + cstr.Length + "}", ""); } Console.WriteLine(" {0}.{1}: {2} [{3}]", cstr, i, layout.FindNode(connLoc), connLoc); } LinkPortTo(sim, port, nodeMap[layout.FindNode(connLoc)]); } } } }
public Instance GetInstance(ILayoutAccess layout, Component component) { layout.CheckReadAccess(); return(instanceMap[component]); }
protected override void PaintModel(IPaintbrush pb) { repainter.NotifyRepainted(); LayoutModel layoutModel = this.Layout; LayoutSimulation layoutSim = this.LayoutSim; if (layoutModel == null) { return; } if (layoutSim.LayoutModel != layoutModel) { Console.Error.WriteLine("layoutSim and layoutModel do not match"); return; } ComponentPainter ip = new ComponentPainter(pb, null); bool noHidden = hidden.Count == 0; Transaction xn = new Transaction(); ISimulationAccess sim = xn.RequestReadAccess(layoutSim.SimulationModel); ILayoutAccess layout = xn.RequestReadAccess(layoutModel); using (xn.Start()) { using (IPaintbrush pbSub = pb.Create()) { pbSub.StrokeWidth = Constants.WIRE_WIDTH; foreach (WireSegment wire in layout.Wires) { Value val0 = layoutSim.GetValueAt(layout, sim, wire.End0); pbSub.Color = Constants.GetColorFor(val0); pbSub.StrokeLine(wire.End0.X, wire.End0.Y, wire.End1.X, wire.End1.Y); } } InstanceState state = new InstanceState(sim, null); ip.InstanceState = state; foreach (Component component in layout.Components) { if (noHidden || !hidden.Contains(component)) { Location loc = component.GetLocation(layout); using (IPaintbrush pbSub = pb.Create()) { pbSub.TranslateCoordinates(loc.X, loc.Y); ip.Paintbrush = pbSub; state.Instance = layoutSim.GetInstance(layout, component); component.Paint(ip); } } } using (IPaintbrush pbSub = pb.Create()) { foreach (Location loc in WiringPoints.SolderPoints) { Value val = layoutSim.GetValueAt(layout, sim, loc); pbSub.Color = Constants.GetColorFor(val); if (noHidden || WiringPoints.IsSolderPoint(loc, hidden)) { pbSub.FillCircle(loc.X, loc.Y, Constants.SOLDER_RADIUS); } } } } }
public LayoutModifiedArgs(ILayoutAccess access) { this.access = access; }