/// <summary> /// Figures out everything a given logic gate should be /// connected to, and connects them appropriately. /// /// Assumption: Every wire-mesh has a unique name. /// /// Note: this currently only deals with connections to wires. /// Hence, it does not make any connections for notbubbles yet. /// </summary> /// <param name="gate">The gate to connect</param> private void connectWiresTo(LogicGate gate) { // We keep track of what wire-meshes are inputs and outputs // so we can do sanity checks before actually connecting // them to the logic gate. List <string> inputWires = new List <string>(); List <string> outputWires = new List <string>(); int maxOutputs = LogicDomain.MaxOutputs(gate.Type); // Cycle through everything connected to the gate's associated // shape and categorize their connection type accordingly foreach (Sketch.Shape connectedShape in gate.Shape.ConnectedShapes) { if (!Domain.LogicDomain.IsWire(connectedShape.Type)) { throw new Exception("Gate " + gate + " was connected to non-wire shape " + connectedShape); } Sketch.EndPoint connectingEndpoint = gate.Shape.ClosestEndpointFrom(connectedShape); if (gate.ShouldBeInput(connectingEndpoint)) { inputWires.Add(connectedShape.Name); } else { outputWires.Add(connectedShape.Name); } } // If it looks like we mixed up the output and input wires, // swap them so they're more correct (this can happen if the // gate's orientation was recognized in the wrong direction) if ((outputWires.Count > maxOutputs) && (inputWires.Count <= maxOutputs)) { swap(ref outputWires, ref inputWires); } // Make the connections. foreach (string wireName in inputWires) { WireMesh inputWire = _wireMeshes[wireName]; gate.ConnectInput(inputWire); } foreach (string wireName in outputWires) { WireMesh outputWire = _wireMeshes[wireName]; gate.ConnectOutput(outputWire); } gate.ConnectAllInputs(); gate.ConnectAllOutputs(); }
/// <summary> /// Figures out everything a given logic gate should be /// connected to, and connects them appropriately. /// /// Assumption: Every wire-mesh has a unique name. /// /// Note: this currently only deals with connections to wires. /// Hence, it does not make any connections for notbubbles yet. /// </summary> /// <param name="gate">The gate to connect</param> private void connectWiresTo(LogicGate gate) { // We keep track of what wire-meshes are inputs and outputs // so we can do sanity checks before actually connecting // them to the logic gate. List <Shape> inputWires = new List <Shape>(); List <Shape> outputWires = new List <Shape>(); int maxOutputs = _domain.NumberOutputs(gate.Type).Max; // Cycle through everything connected to the gate's associated // shape and categorize their connection type accordingly foreach (Sketch.Shape connectedShape in gate.Shape.ConnectedShapes) { // We'll take care of the not bubbles when they come up seprately if (connectedShape.Type == LogicDomain.NOTBUBBLE) { continue; } // If it's not a wire or a not bubble, something is wrong else if (!Domain.LogicDomain.IsWire(connectedShape.Type)) { throw new Exception("Gate " + gate + " was connected to non-wire, non-notbubble shape " + connectedShape); } Sketch.EndPoint connectingEndpoint = gate.Shape.ClosestEndpointFrom(connectedShape); if (gate.ShouldBeInput(connectingEndpoint)) { inputWires.Add(connectedShape); } else { outputWires.Add(connectedShape); } } // Make the connections. foreach (Shape wire in inputWires) { WireMesh inputWire = _wireMeshes[wire]; gate.ConnectInput(inputWire); } foreach (Shape wire in outputWires) { WireMesh outputWire = _wireMeshes[wire]; gate.ConnectOutput(outputWire); } gate.ConnectAllInputs(); gate.ConnectAllOutputs(); }
/// <summary> /// Connects not bubbles to gates and wires /// </summary> /// <param name="gate"></param> private void connectNotBubble(LogicGate bubble) { LogicGate parentGate = null; WireMesh wire = null; // Get the components this not bubble is connected to foreach (Shape connected in bubble.Shape.ConnectedShapes) { if (LogicDomain.IsGate(connected.Type) && parentGate == null) { parentGate = _logicGates[connected]; } else if (LogicDomain.IsWire(connected.Type)) { wire = _wireMeshes[connected]; } } // If this is not connected to a gate, connect it like a normal logic gate if (parentGate == null) { connectWiresTo(bubble); return; } // Is this bubble on the output or the input? Sketch.EndPoint connectingEndpoint = parentGate.Shape.ClosestEndpointFrom(bubble.Shape); bool isInput = parentGate.ShouldBeInput(connectingEndpoint); if (isInput) { wire.ConnectDependent(bubble); parentGate.ConnectInput(bubble, 0); } else { wire.ConnectSource(bubble, 0); parentGate.ConnectOutput(bubble, 0); } }
/// <summary> /// Creates a circuit component for every Wire or Gate shape in /// a given sketch to store in the invoking circuit parser. /// Note that it does not add labels (circuit inputs/outputs) /// or anything else that's not a wire or gate. /// /// Assumption: every shape in the sketch has a unique name. /// /// Note: we can remove this assumption by using the shape ID /// (GUIDs) as keys in CircuitParser's dictionaries. We use /// the shape names primarily because it helps with debugging, /// and that circuit elements are differentiated by their names /// later along the line so names should be unique anyway. /// </summary> /// <param name="sketch"></param> private void loadWiresAndGates(Sketch.Sketch sketch) { foreach (Sketch.Shape shape in sketch.Shapes) { if (Domain.LogicDomain.IsWire(shape.Type)) { WireMesh newWire = new WireMesh(shape); _wireMeshes.Add(newWire.Name, newWire); if (debug) { Console.WriteLine("Found wire: " + newWire.Name); } } else if (Domain.LogicDomain.IsGate(shape.Type)) { LogicGate newGate = new LogicGate(shape); _logicGates.Add(newGate.Name, newGate); if (debug) { Console.WriteLine("Found gate: " + newGate.Name); } } } }