Ejemplo n.º 1
0
        /// <summary>
        /// Connects a circuit component as the input/source of the
        /// invoking wire.
        /// </summary>
        /// <param name="component">The component to connect</param>
        /// <returns>A Parse Error if an error arises, otherwise null</returns>
        public void ConnectSource(CircuitComponent component, int index)
        {
            // If we already made this connection, we're done!
            if (_sourceComponent == component)
            {
                return;
            }

            // Make the connection.
            _sourceComponent = component;
            _sourceIndex     = index;

            // Make sure the circuit component also has this connection
            if (component is LogicGate)
            {
                ((LogicGate)component).ConnectOutput(this);
            }
            else if (component is CircuitInput)
            {
                ((CircuitInput)component).Connect(this);
            }
            else if (component is CircuitOutput)
            {
                ((CircuitOutput)component).Connect(this);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Default constructor for making a new,
 /// unconnected wire-mesh associated with a
 /// given shape.
 /// </summary>
 /// <param name="shape">The shape associated
 /// with the new wire</param>
 public WireMesh(Sketch.Shape shape)
     : base(shape)
 {
     _sourceComponent     = null;
     _dependentComponents = new List <CircuitComponent>();
     loadEndpoints();
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Connects a circuit component as an output/dependent of the
        /// invoking wire.
        /// </summary>
        /// <param name="component">The component to connect</param>
        public void ConnectDependent(CircuitComponent component)
        {
            // If we already made this connection, we're done!
            if (!_dependentComponents.Contains(component))
            {
                _dependentComponents.Add(component);
            }
            else
            {
                return;
            }

            if (Source != null)
            {
                component.ConnectInput(Source, SourceIndex);
            }

            // Make sure the circuit component also has this connection
            if (component is LogicGate)
            {
                ((LogicGate)component).ConnectInput(this);
            }
            else if (component is CircuitOutput)
            {
                ((CircuitOutput)component).Connect(this);
            }
            else if (component is CircuitInput)
            {
                ((CircuitInput)component).Connect(this);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Default constructor for making a new,
        /// unconnected wire-mesh associated with a
        /// given shape.
        /// </summary>
        /// <param name="shape">The shape associated
        /// with the new wire</param>
        public WireMesh(Sketch.Shape shape)
        {
            _associatedShape     = shape;
            _sourceComponent     = null;
            _dependentComponents = new List <CircuitComponent>();

            loadEndpoints();
        }
Ejemplo n.º 5
0
 public bool HasOutput(CircuitComponent component, int index)
 {
     if (OutputComponents.Count >= index + 1)
     {
         if (OutputComponents[index].Contains(component))
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Returns true if this circuit component has the given component and index connected as an input
 /// </summary>
 /// <param name="component"></param>
 /// <param name="index"></param>
 /// <returns></returns>
 public bool HasInput(CircuitComponent component, int index)
 {
     if (_inputComponents.ContainsKey(component))
     {
         if (_inputComponents[component].Contains(index))
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Add connections between the given component and its inputs to the dictionary of circuit connections.
 /// (computes the input/output indices, then passes that info to connect(...) which actually adds the
 /// connection to the dictionary).
 /// </summary>
 /// <param name="connections">Existing dictionary of connctions.</param>
 /// <param name="component">Element whose inputs we add</param>
 /// <returns>The dictionary with the new connections added</returns>
 private Dictionary <Shape, Dictionary <int, Tuple <Shape, int> > > recordConnections(
     Dictionary <Shape, Dictionary <int, Tuple <Shape, int> > > connections,
     CircuitComponent component)
 {
     // Find the inputs to this component using the component's input wires.
     foreach (int destindex in component.InputComponents.Keys)
     {
         connections = recordConnection(connections, component.InputComponents[destindex].Item1.Shape,
                                        component.InputComponents[destindex].Item2, component.Shape, destindex);
     }
     return(connections);
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Connects a given circuit component as an input to the
        /// invoking logic gate.
        /// </summary>
        /// <param name="wire">The component to connect</param>
        public void ConnectInput(CircuitComponent component, int sourceindex)
        {
            // If we already made this connection, we're done!
            if (!_inputComponents.ContainsKey(component))
            {
                _inputComponents[component] = new List <int>();
            }

            // Make the connection.
            _inputComponents[component].Add(sourceindex);

            // Ensure that the given component also has this connection.
            component.ConnectOutput(this, sourceindex);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Gets the endpoints in this wiremeesh which are connected to the specified circuit component.
        /// </summary>
        /// <param name="otherShape">The circuit component we're looking for connections to</param>
        /// <returns>A list of the endpoints in this shape connected to the specified component</returns>
        public List <Sketch.EndPoint> ConnectedEndpoints(CircuitComponent otherShape)
        {
            List <Sketch.EndPoint> connectedEndpoints = new List <Sketch.EndPoint>();

            foreach (Sketch.EndPoint endpoint in Endpoints)
            {
                if (endpoint.ConnectedShape == otherShape.Shape)
                {
                    connectedEndpoints.Add(endpoint);
                }
            }

            return(connectedEndpoints);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Connects a given circuit component as an input to the
        /// invoking logic gate.
        /// </summary>
        /// <param name="wire">The component to connect</param>
        public void ConnectInput(CircuitComponent component, int index)
        {
            // If we already made this connection, we're done!
            if (_inputComponents.ContainsKey(component))
            {
                return;
            }

            // Make the connection.
            _inputComponents.Add(component, index);

            // Ensure that the given component also has this connection.
            component.ConnectOutput(this, index);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Connects all the circuit components (logic gates,
        /// circuit inputs, and circuit outputs) that share
        /// a wire-mesh to each other
        /// </summary>
        private void connectComponentsToComponents()
        {
            foreach (WireMesh wireMesh in _wireMeshes.Values)
            {
                if (!wireMesh.HasSource)
                {
                    continue;
                }

                CircuitComponent wireInput = wireMesh.Source;
                foreach (CircuitComponent wireOutput in wireMesh.Dependents)
                {
                    wireInput.ConnectOutput(wireOutput, wireMesh.SourceIndex);
                }
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Connects a circuit component to the output of the
        /// invoking logic gate. In other words, the output of
        /// the invoking logic gate becomes directly tied with
        /// an input or value of a given circuit component.
        /// </summary>
        /// <param name="wire">The component to connect</param>
        public void ConnectOutput(CircuitComponent component, int index)
        {
            while (_outputComponents.Count < index + 1)
            {
                _outputComponents.Add(new List <CircuitComponent>());
            }

            // If we already made this connection, we're done!
            if (_outputComponents[index].Contains(component))
            {
                return;
            }

            // Make the connection.
            _outputComponents[index].Add(component);

            // Ensure that the given component also has this connection.
            component.ConnectInput(this, index);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Connects a circuit component as an output/dependent of the
        /// invoking wire.
        /// </summary>
        /// <param name="component">The component to connect</param>
        public void ConnectDependent(CircuitComponent component)
        {
            // If we already made this connection, we're done!
            if (_dependentComponents.Contains(component))
            {
                return;
            }

            // Make the connection.
            _dependentComponents.Add(component);

            // Make sure the circuit component also has this connection
            if (component is LogicGate)
            {
                ((LogicGate)component).ConnectInput(this);
            }
            else if (component is CircuitOutput)
            {
                ((CircuitOutput)component).Connect(this);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Sorts inputs by where they are on screen, constructs the input dictionary
        /// </summary>
        public void OrderInputs()
        {
            // Get all the endpoints
            List <Sketch.EndPoint> connectedEndpoints = InputEndpoints;
            Dictionary <Sketch.EndPoint, CircuitComponent> endpointsToNotBubbles = new Dictionary <Sketch.EndPoint, CircuitComponent>();

            // Take care of any not bubbles
            foreach (CircuitComponent connected in _inputComponents.Keys)
            {
                if (Domain.LogicDomain.IsGate(connected.Type) && connected.Shape.ConnectedShapes.Contains(Shape) && connected.InputEndpoints.Count > 0)
                {
                    connectedEndpoints.Add(connected.InputEndpoints[0]);
                    endpointsToNotBubbles[connected.InputEndpoints[0]] = connected;
                }
            }

            // Sort all these endpoints
            connectedEndpoints.Sort(EndpointSort);

            // Make the input dictionary
            _inputDictionary.Clear();
            for (int index = 0; index < connectedEndpoints.Count; index++)
            {
                if (EndpointsToWires.ContainsKey(connectedEndpoints[index]))
                {
                    WireMesh wire = EndpointsToWires[connectedEndpoints[index]];
                    if (wire.HasSource)
                    {
                        _inputDictionary[index] = new Tuple <CircuitComponent, int>(wire.Source, wire.SourceIndex);
                    }
                }
                else
                {
                    CircuitComponent notBubble = endpointsToNotBubbles[connectedEndpoints[index]];
                    _inputDictionary[index] = new Tuple <CircuitComponent, int>(notBubble, 0);
                }
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Checks whether the circuit is valid, returns a bool indicating this.
        /// Adds any errors it comes across to the _parseErrors list.
        ///
        /// Looks for:
        ///    * Each wire has one source and at least one output
        ///    * No wire outputs to an input and no output is a wire's input
        ///    * Each gate has an allowable number of inputs and outputs
        ///    * Each circuit element and wire have reciprocal connections
        ///    * Each input and output are connected to something
        /// </summary>
        /// <returns>A bool, which is true if the circuit is valid</returns>
        private bool CheckCircuit()
        {
            // Assume the circuit is fine, decide otherwise later.
            bool valid = true;

            #region Check Wire Connections
            // Each wire should have one input and at least one output
            foreach (WireMesh mesh in _wireMeshes.Values)
            {
                // Do the connections exist?
                if (!mesh.HasSource)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The wire " + mesh.Name + " is missing a source.",
                                                    "This wire does not have a source.  Try dragging its red endpoints to connect it to something.", mesh.Shape));
                }

                /*
                 * // This is actually ok right now, outputs can be drawn in the middle of wires to give intermediary values.
                 * else if (mesh.Source is CircuitOutput)
                 * {
                 *  valid = false;
                 *  _parseErrors.Add(new ParseError("The wire " + mesh.Name + "'s source is an output, " + mesh.Source.Name + ".",
                 *      "This wire's source is an output, " + mesh.Source.Name + ".", mesh.Shape));
                 * }
                 */
                if (mesh.Dependents.Count < 1)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The wire " + mesh.Name + " has no dependents.",
                                                    "Nothing uses this wire's value! Please connect it to something by dragging its endpoints.", mesh.Shape));
                }
                foreach (CircuitComponent connected in mesh.Dependents)
                {
                    if (connected is CircuitInput)
                    {
                        valid = false;
                        _parseErrors.Add(new ParseError("The wire " + mesh.Name + " is giving a value to the input" + connected.Name + ".",
                                                        "This wire is giving a value to the input" + connected.Name + ".", mesh.Shape));
                    }
                }
            }
            #endregion

            #region Check Gate Connections
            // Each gate should have the correct number of inputs and outputs
            foreach (LogicGate gate in LogicGates)
            {
                // Get the minimum and maximum input and output numbers
                Utilities.IntRange inputs  = _domain.NumberInputs(gate.Type);
                Utilities.IntRange outputs = _domain.NumberOutputs(gate.Type);

                // Check input numbers
                if (gate.InputComponents.Count < inputs.Min)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The gate " + gate.Name + " is missing some inputs.  It needs at least " + inputs.Min + " but has " + gate.InputComponents.Count + ".",
                                                    "This gate is missing some inputs.  It needs at least " + inputs.Min + " but has " + gate.InputComponents.Count + ".", gate.Shape));
                }
                else if (gate.InputComponents.Count > inputs.Max)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The gate " + gate.Name + " has too many inputs.  It needs at most " + inputs.Max + " but has " + gate.InputComponents.Count + ".",
                                                    "This gate has too many inputs.  It needs at most " + inputs.Max + " but has " + gate.InputComponents.Count + ".", gate.Shape));
                }

                // Check input connections
                foreach (int index in gate.InputComponents.Keys)
                {
                    CircuitComponent component = gate.InputComponents[index].Item1;
                    if (!component.HasOutput(gate, gate.InputComponents[index].Item2))
                    {
                        valid = false;
                        _parseErrors.Add(new ParseError("The gate " + gate.Name + " is connected to the component " + component.Name + ", but that component is not connected to the gate!",
                                                        "The gate " + gate.Name + " is connected to the component " + component.Name + ", but that component is not connected to the gate!", component.Shape));
                    }
                }

                // Check output numbers
                if (gate.OutputComponents.Count < outputs.Min)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The gate " + gate.Name + " is missing some outputs.  It needs at least " + outputs.Min + " but has " + gate.OutputComponents.Count + ".",
                                                    "This gate is missing some outputs.  It needs at least " + outputs.Min + " but has " + gate.OutputComponents.Count + ".", gate.Shape));
                }
                else if (gate.OutputComponents.Count > outputs.Max)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The gate " + gate.Name + " has too many outputs.  It needs at most " + outputs.Max + " but has " + gate.OutputComponents.Count + ".",
                                                    "This gate has too many outputs.  It needs at most " + outputs.Max + " but has " + gate.OutputComponents.Count + ".", gate.Shape));
                }

                // Check output connections
                foreach (WireMesh wire in gate.OutputWires)
                {
                    if (wire.Source != gate)
                    {
                        valid = false;
                        _parseErrors.Add(new ParseError("The gate " + gate.Name + " is connected to the wire " + wire.Name + ", but that wire is not connected to the gate!",
                                                        "The gate " + gate.Name + " is connected to the wire " + wire.Name + ", but that wire is not connected to the gate!", wire.Shape));
                    }
                }

                // Check output connections
                for (int i = 0; i < gate.OutputComponents.Count; i++)
                {
                    foreach (CircuitComponent component in gate.OutputComponents[i])
                    {
                        if (!component.HasInput(gate, i))
                        {
                            valid = false;
                            _parseErrors.Add(new ParseError("The gate " + gate.Name + " is connected to the component " + component.Name + ", but that component is not connected to the gate!",
                                                            "The gate " + gate.Name + " is connected to the component " + component.Name + ", but that component is not connected to the gate!", component.Shape));
                        }
                    }
                }
            }
            #endregion

            #region Check Input/Output connections
            // Each input should be connected correctly
            foreach (CircuitInput input in _circuitInputs.Values)
            {
                if (input.OutputWires.Count == 0)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The input " + input.Name + " is not connected to anything.",
                                                    "This input (" + input.Name + ") is not connected to anything.", input.Shape));
                }
                else
                {
                    foreach (WireMesh wire in input.OutputWires)
                    {
                        if (wire.Source != input)
                        {
                            valid = false;
                            _parseErrors.Add(new ParseError("The input " + input.Name + " is connected to the wire " + wire.Name + ", but that wire does not get it's value from the input!",
                                                            "This input (" + input.Name + ") is connected to the wire " + wire.Name + ", but that wire does not get it's value from thr input!", input.Shape));
                        }
                    }
                }
                if (input.InputWires.Count > 0)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The input " + input.Name + " connected as an output.",
                                                    "This input (" + input.Name + ") is connected as an output.", input.Shape));
                }
            }

            // Each output should be connected correctly
            foreach (CircuitOutput output in _circuitOutputs.Values)
            {
                if (output.InputWires.Count == 0)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The output " + output.Name + " is not getting a value from anything.",
                                                    "This output (" + output.Name + ") is not getting a value from anything.", output.Shape));
                }
                else if (output.InputWires.Count > 1)
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The output " + output.Name + " gets a value from more than one wire.",
                                                    "This output (" + output.Name + ") gets a value from more than one wire.", output.Shape));
                }
                else if (!output.SourceWire.Dependents.Contains(output))
                {
                    valid = false;
                    _parseErrors.Add(new ParseError("The output " + output.Name + " is connected to the wire " + output.SourceWire.Name + ", but that wire does not give it's value to the output!",
                                                    "This output (" + output.Name + ") is connected to the wire " + output.SourceWire.Name + ", but that wire does not give it's value to the output!", output.Shape));
                }
                foreach (WireMesh wire in output.OutputWires)
                {
                    if (wire.Source != output)
                    {
                        valid = false;
                        _parseErrors.Add(new ParseError("The output " + output.Name + " is connected to the wire " + wire.Name + ", but that wire does not get it's value from the output!",
                                                        "This output (" + output.Name + ") is connected to the wire " + wire.Name + ", but that wire does not get it's value from the output!", output.Shape));
                    }
                }
            }
            #endregion

            return(valid);
        }