File indexing completed on 2024-12-08 08:10:20

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #ifndef PIN_H
0012 #define PIN_H
0013 
0014 #include "wire.h"
0015 
0016 #include <QList>
0017 #include <QObject>
0018 #include <QPointer>
0019 
0020 class ECNode;
0021 class Element;
0022 class Pin;
0023 class Switch;
0024 class Wire;
0025 
0026 typedef QList<Element *> ElementList;
0027 typedef QList<QPointer<Pin>> PinList;
0028 typedef QList<Switch *> SwitchList;
0029 typedef QList<QPointer<Wire>> WireList;
0030 
0031 /**
0032 @author David Saxton
0033 */
0034 class Pin : public QObject
0035 {
0036 public:
0037     /**
0038      * Priorities for ground pin. gt_always will (as expected) always assign
0039      * the given pin as ground, gt_never will never do. If no gt_always pins
0040      * exist, then the pin with the highest priority will be set as ground -
0041      * if there is at least one pin that is not of ground type gt_never. These
0042      * are only predefined recommended values, so if you choose not to use one
0043      * of these, please respect the priorities with respect to the examples, and
0044      * always specify a priority between 0 and 20.
0045      * @see groundLevel
0046      */
0047     enum GroundType {
0048         gt_always = 0,  // ground
0049         gt_high = 5,    // voltage points
0050         gt_medium = 10, // voltage sources
0051         gt_low = 15,    // current sources
0052         gt_never = 20   // everything else
0053     };
0054     Pin(ECNode *parent);
0055     ~Pin() override;
0056 
0057     ECNode *parentECNode() const
0058     {
0059         return m_pECNode;
0060     }
0061     /**
0062      * This function returns the pins that are directly connected to this pins:
0063      * either at the ends of connected wires, or via switches.
0064      */
0065     PinList localConnectedPins() const;
0066     /**
0067      * Adds/removes the given pin to the list of ones that this pin is/isn't
0068      * connected to via a switch.
0069      */
0070     void setSwitchConnected(Pin *pin, bool isConnected);
0071     /**
0072      * After calculating the nodal voltages in the circuit, this function should
0073      * be called to tell the pin what its voltage is.
0074      */
0075     void setVoltage(double v)
0076     {
0077         m_voltage = v;
0078     }
0079     /**
0080      * Returns the voltage as set by setVoltage.
0081      */
0082     double voltage() const
0083     {
0084         return m_voltage;
0085     }
0086     /**
0087      * After calculating nodal voltages, each component will be called to tell
0088      * its pins what the current flowing *into* the component is. This sets it
0089      * to zero in preparation to merging the current.
0090      */
0091     void resetCurrent()
0092     {
0093         m_current = 0.0;
0094     }
0095     /**
0096      * Adds the given current to that already flowing into the pin.
0097      * @see setCurrent
0098      */
0099     void mergeCurrent(double i)
0100     {
0101         m_current += i;
0102     }
0103     /**
0104      * Returns the current as set by mergeCurrent.
0105      */
0106     double current() const
0107     {
0108         return m_current;
0109     }
0110     /**
0111      * In many cases (such as if this pin is a ground pin), the current
0112      * flowing into the pin has not been calculated, and so the value
0113      * returned by current() cannot be trusted.
0114      */
0115     void setCurrentKnown(bool isKnown)
0116     {
0117         m_bCurrentIsKnown = isKnown;
0118     }
0119     /**
0120      * Tell thie Pin that none of the currents from the switches have yet
0121      * been merged.
0122      */
0123     void setSwitchCurrentsUnknown(); // { m_switchList.erase(nullptr); m_unknownSwitchCurrents = m_switchList; }
0124     /**
0125      * This returns the value given by setCurrentKnown AND'd with whether
0126      * we know the current from each switch attached to this pin.
0127      * @see setCurrentKnown
0128      */
0129     bool currentIsKnown() const
0130     {
0131         return m_bCurrentIsKnown && m_unknownSwitchCurrents.isEmpty();
0132     }
0133     /**
0134      * Tells the Pin that the current from the given switch has been merged.
0135      */
0136     void setSwitchCurrentKnown(Switch *sw)
0137     {
0138         m_unknownSwitchCurrents.removeAll(sw);
0139     }
0140     /**
0141      * Tries to calculate the Pin current from the input / output wires.
0142      * @return whether was successful.
0143      */
0144     bool calculateCurrentFromWires();
0145     /**
0146      * Sets the "ground type" - i.e. the priority that this pin has for being
0147      * ground over other pins in the circuit. Lower gt = higher priority. It's
0148      * recommended to use Pin::GroundType.
0149      */
0150     void setGroundType(int gt)
0151     {
0152         m_groundType = gt;
0153     }
0154     /**
0155      * Returns the priority for ground.
0156      */
0157     int groundType() const
0158     {
0159         return m_groundType;
0160     }
0161     /**
0162      * Adds a dependent pin - one whose voltages will (or might) affect the
0163      * voltage of this pin. This is set by Component.
0164      */
0165     void addCircuitDependentPin(Pin *pin);
0166     /**
0167      * Adds a dependent pin - one whose voltages will (or might) affect the
0168      * voltage of this pin. This is set by Component.
0169      */
0170     void addGroundDependentPin(Pin *pin);
0171     /**
0172      * Removes all Circuit and Ground dependent pins.
0173      */
0174     void removeDependentPins();
0175     /**
0176      * Returns the ids of the pins whose voltages will affect this pin.
0177      * @see void setDependentPins( QStringList ids )
0178      */
0179     PinList circuitDependentPins() const
0180     {
0181         return m_circuitDependentPins;
0182     }
0183     /**
0184      * Returns the ids of the pins whose voltages will affect this pin.
0185      * @see void setDependentPins( QStringList ids )
0186      */
0187     PinList groundDependentPins() const
0188     {
0189         return m_groundDependentPins;
0190     }
0191     /**
0192      * Use this function to set the pin identifier for equations,
0193      * which should be done every time new pins are registered.
0194      */
0195     void setEqId(int id)
0196     {
0197         m_eqId = id;
0198     }
0199     /**
0200      * The equation identifier.
0201      * @see setEqId
0202      */
0203     int eqId() const
0204     {
0205         return m_eqId;
0206     }
0207     /**
0208      * Returns a list of elements that will affect this pin (e.g. if this
0209      * pin is part of a resistor, then that list will contain a pointer to a
0210      * Resistance element)
0211      */
0212     ElementList elements() const
0213     {
0214         return m_elementList;
0215     }
0216     /**
0217      * Adds an element to the list of those that will affect this pin.
0218      */
0219     void addElement(Element *e);
0220     /**
0221      * Removes an element from the list of those that will affect this pin.
0222      */
0223     void removeElement(Element *e);
0224     /**
0225      * Adds an switch to the list of those that will affect this pin.
0226      */
0227     void addSwitch(Switch *e);
0228     /**
0229      * Removes an switch from the list of those that will affect this pin.
0230      */
0231     void removeSwitch(Switch *e);
0232 
0233     void addInputWire(Wire *wire);
0234     void addOutputWire(Wire *wire);
0235     void removeWire(Wire *wire);
0236     WireList inputWireList() const
0237     {
0238         return m_inputWireList;
0239     }
0240     WireList outputWireList() const
0241     {
0242         return m_outputWireList;
0243     }
0244     int numWires() const
0245     {
0246         return m_inputWireList.size() + m_outputWireList.size();
0247     }
0248 
0249 protected:
0250     double m_voltage;
0251     double m_current;
0252 
0253     int m_eqId;
0254     int m_groundType;
0255 
0256     bool m_bCurrentIsKnown;
0257 
0258     PinList m_circuitDependentPins;
0259     PinList m_groundDependentPins;
0260     PinList m_switchConnectedPins;
0261 
0262     ElementList m_elementList;
0263 
0264     WireList m_inputWireList;
0265     WireList m_outputWireList;
0266     ECNode *m_pECNode;
0267 
0268     SwitchList m_switchList;
0269     SwitchList m_unknownSwitchCurrents;
0270 };
0271 
0272 #endif