File indexing completed on 2024-12-01 05:12:43
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