summaryrefslogtreecommitdiffstats
path: root/src/electronics/component.h
blob: d45d83558b16892d73eea60d05f115caf533657f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/***************************************************************************
 *   Copyright (C) 2003 by David Saxton                                    *
 *   [email protected]                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#ifndef COMPONENT_H
#define COMPONENT_H

#include "cnitem.h"

#include <qvaluelist.h>

class ICNDocument;
class CircuitDocument;
class ECNode;
class ECSubcircuit;
class Element;
class Node;
class Pin;

class BJT;
class Capacitance;
class CCCS;
class CCVS;
class CurrentSignal;
class CurrentSource;
class Diode;
class Inductance;
class LogicIn;
class LogicOut;
class OpAmp;
class Resistance;
class Switch;
class Transformer;
class VCCS;
class VCVS;
class VoltagePoint;
class VoltageSignal;
class VoltageSource;

typedef QValueList<ECNode*> ECNodeList;
typedef QValueList<Element*> ElementList;
typedef QValueList<Switch*> SwitchList;

typedef QValueList< QValueList<Pin*> > PinListList;

/**
Contains vital information about the elements in the component.
*/
class ElementMap
{
	public:
		ElementMap();
		
		Element * e; // The element
		Pin * n[4]; // The Pins associated with the CNodes in the element
	
		/// @see Component::setInterCircuitDependent
		PinListList interCircuitDependent;
	
		/// @see Component::setInterGroundDependent
		PinListList interGroundDependent;
};

typedef QValueList<ElementMap> ElementMapList;

/**
@short Bass class for all electrical components
@author David Saxton
*/
class Component : public CNItem
{
	Q_OBJECT
	public:
		Component( ICNDocument *icnDocument, bool newItem, const QString &id );
		virtual ~Component();
	
		ECNode* createPin( double _x, double _y, int orientation, const QString &name );
		/**
		 * Reinherit this function to disallow rotation of the component.
		 */
		virtual bool canRotate() const { return true; }
		/**
		 * Angle of orientation
		 */
		int angleDegrees() const { return m_angleDegrees; }
		/**
		 * Sets the angle (in degrees)
		 */
		void setAngleDegrees( int degrees );
		/**
		 * Whether or not the item is flipped
		 */
		bool flipped() const { return b_flipped; }
		/**
		 * Sets whether or not the item is flipped
		 */
		void setFlipped( bool flipped );
		/**
		 * After calculating nodal voltages, each component will be
		 * called to tell its nodes what the current flowing *into*
		 * the component is.
		 */
		void setNodalCurrents();
		/**
		 * @return pointer to the CircuitDocument that we're in.
		 */
		CircuitDocument * circuitDocument() const { return m_pCircuitDocument; }
		void initElements( const uint stage );
		virtual void finishedCreation();
		/**
		 * If reinherit (and use) the stepNonLogic function, then you must also
		 * reinherit this function so that it returns true. Else your component
		 * will not get called.
		 */
		virtual bool doesStepNonLogic() const { return false; }
		virtual void stepNonLogic() {};
		/**
		 * Returns the translation matrix used for painting et al
		 * @param orientation The orientation to use
		 * @param x x co-ordinate of the center of the object to be mapped
		 * @param y y co-ordinate of the center of the object to be mapped
		 * @param inverse If false, maps the unrotated item to a rotated one, else mapped->unmapped
		 */
		static QWMatrix transMatrix( int angleDegrees, bool flipped, int x, int y, bool inverse = false );
		/**
		 * @return Information about the component in an ItemData struct.
		 */
		virtual ItemData itemData() const;
		/**
		 * Restores the state of the component from the ItemData struct.
		 */
		virtual void restoreFromItemData( const ItemData &itemData );
	
		BJT *			createBJT( Pin *c, Pin *b, Pin *e, bool isNPN = true );
		BJT *			createBJT( ECNode *c, ECNode *b, ECNode *e, bool isNPN = true );
	
		Capacitance *	createCapacitance( Pin *n0, Pin *n1, double capacitance );
		Capacitance *	createCapacitance( ECNode *n0, ECNode *n1, double capacitance );
	
		CCCS *			createCCCS( Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain );
		CCCS *			createCCCS( ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain );
	
		CCVS *			createCCVS( Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain );
		CCVS *			createCCVS( ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain );
	
		CurrentSignal *	createCurrentSignal( Pin *n0, Pin *n1, double current );
		CurrentSignal *	createCurrentSignal( ECNode *n0, ECNode *n1, double current );
	
		CurrentSource *	createCurrentSource( Pin *n0, Pin *n1, double current );
		CurrentSource *	createCurrentSource( ECNode *n0, ECNode *n1, double current );
	
		Diode *			createDiode( Pin *n0, Pin *n1 );
		Diode *			createDiode( ECNode *n0, ECNode *n1 );
	
		Inductance *	createInductance( Pin *n0, Pin *n1, double inductance );
		Inductance *	createInductance( ECNode *n0, ECNode *n1, double inductance );
	
		LogicIn *		createLogicIn( Pin *node );
		LogicIn *		createLogicIn( ECNode *node );
	
		LogicOut *		createLogicOut( Pin *node, bool isHigh );
		LogicOut *		createLogicOut( ECNode *node, bool isHigh );
	
		OpAmp *			createOpAmp( Pin * nonInverting, Pin * out, Pin * inverting );
		OpAmp *			createOpAmp( ECNode * nonInverting, ECNode * out, ECNode * inverting );
	
		Resistance *	createResistance( Pin *n0, Pin *n1, double resistance );
		Resistance *	createResistance( ECNode *n0, ECNode *n1, double resistance );
	
		Switch *		createSwitch( Pin *n0, Pin *n1, bool open );
		Switch *		createSwitch( ECNode *n0, ECNode *n1, bool open );
	
		VCCS *			createVCCS( Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain );
		VCCS *			createVCCS( ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain );
	
		VCVS *			createVCVS( Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain );
		VCVS *			createVCVS( ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain );
	
		VoltagePoint *	createVoltagePoint( Pin *n0, double voltage );
		VoltagePoint *	createVoltagePoint( ECNode *n0, double voltage );
	
		VoltageSignal *	createVoltageSignal( Pin *n0, Pin *n1, double voltage );
		VoltageSignal *	createVoltageSignal( ECNode *n0, ECNode *n1, double voltage );
	
		VoltageSource *	createVoltageSource( Pin *n0, Pin *n1, double voltage );
		VoltageSource *	createVoltageSource( ECNode *n0, ECNode *n1, double voltage );
	

		ECNode* ecNodeWithID( const QString &ecNodeId  );
	
		/**
		 * Safely delete an element - in this case, calls element->componentDeleted,
		 * and removes it from the element list.
		 * @param setPinsInterIndependent whether to call
		 * setPinsInterIndependent. The call is time-consuming, and unnecessary
		 * if the pins from which the element was originally attached will be/
		 * were removed, or they will become interdependent again.
		 */
		void removeElement( Element * element, bool setPinsInterIndependent );
		/**
		 * Safely remove a switch.
		 */
		void removeSwitch( Switch * sw );
		/**
		 * Removes all elements and switches.
		 * @param setPinsInterIndependent whether to bother calling
		 * setPinsInterIndependent. This is false when calling from the
		 * destructor, or when the dependency information is the same.
		 */
		void removeElements( bool setPinsInterIndependent = false );
		/**
		 * @return the list of switches that this component uses.
		 */
		SwitchList switchList() const { return m_switchList; }
	
	signals:
		/**
		 * Emitted when an element is created.
		 */
		void elementCreated( Element * element );
		/**
		 * Emitted when an element is destroyed.
		 */
		void elementDestroyed( Element * element );
		/**
		 * Emitted when a switch. is created
		 */
		void switchCreated( Switch * sw );
		/**
		 * Emitted when a switch is destroyed.
		 */
		void switchDestroyed( Switch * sw );
	
	public slots:
		virtual void slotUpdateConfiguration();
		virtual void removeItem();
	
	protected:
		/**
		 * Convenience functionality provided for components in a port shape
		 * (such as ParallelPortComponent and SerialPortComponent).
		 */
		void drawPortShape( QPainter & p );
		virtual void itemPointsChanged();
		virtual void updateAttachedPositioning();
		virtual void initPainter( QPainter &p );
		/**
		 * Untranforms the painter from the matrix. This *must* be called after doing
		 * initPainter( QPainter &p );
		 */
		virtual void deinitPainter( QPainter &p );
		/**
		 * This creates a set of nodes with their internal IDs set to those in QStringList pins.
		 * The pins are in a DIP arrangement, and are spaced width() apart.
		 */
		void initDIP( const QStringList & pins );
		/**
		 * Creates the DIP symbol:
		 * @li constructs rectangular shape
		 * @li puts on text labels in appropriate positions from QStringList pins
		 */
		void initDIPSymbol( const QStringList & pins, int width );
		/**
		 * Create 1 pin on the left of the component, placed half way down if h1 is
		 * -1 - else at the position of h1.
		 */
		void init1PinLeft( int h1 = -1 );
		/**
		 * Create 2 pins on the left of the component, either spread out, or at the
		 * given heights.
		 */
		void init2PinLeft( int h1 = -1, int h2 = -1 );
		/**
		 * Create 3 pins on the left of the component, either spread out, or at the
		 * given heights.
		 */
		void init3PinLeft( int h1 = -1, int h2 = -1, int h3 = -1 );
		/**
		 * Create 4 pins on the left of the component, either spread out, or at the
		 * given heights.
		 */
		void init4PinLeft( int h1 = -1, int h2 = -1, int h3 = -1, int h4 = -1 );
		/**
		 * Create 1 pin on the right of the component, placed half way down if h1 is
		 * -1 - else at the position of h1.
		 */
		void init1PinRight( int h1 = -1 );
		/**
		 * Create 2 pins on the right of the component, either spread out, or at the
		 * given heights.
		 */
		void init2PinRight( int h1 = -1, int h2 = -1 );
		/**
		 * Create 3 pins on the right of the component, either spread out, or at the
		 * given heights.
		 */
		void init3PinRight( int h1 = -1, int h2 = -1, int h3 = -1 );
		/**
		 * Create 4 pins on the right of the component, either spread out, or at the
		 * given heights.
		 */
		void init4PinRight( int h1 = -1, int h2 = -1, int h3 = -1, int h4 = -1 );
		/**
		 * When we remove an element, we have to rebuild the list of inter-dependent
		 * nodes. (when adding elements, we just call setInterDependent).
		 */
		void rebuildPinInterDepedence();
	
		// Pointers to commonly used nodes
		ECNode * m_pPNode[4];
		ECNode * m_pNNode[4];
	
		QGuardedPtr<CircuitDocument> m_pCircuitDocument;
		int m_angleDegrees;
		bool b_flipped;
	
	private:
		/**
		 * Convenience function for calling both setInterCircuitDependent and
		 * setInterGroundDependent.
		 * @param it Which pins are inter-dependent needs to be recorded in case
		 * this information is later needed in rebuildPinInterDependence.
		 */
		void setInterDependent( ElementMapList::iterator it, const QValueList<Pin*> & pins );
		/**
		 * Sets all pins independent of each other.
		 */
		void setAllPinsInterIndependent();
		/**
		 * The given pins will affect the simulation of each other. Therefore, they
		 * will need to be simulated in the same circuit.
		 */
		void setInterCircuitDependent( ElementMapList::iterator it, const QValueList<Pin*> & pins );
		/**
		 * If any of the given pins are ground, then that will affect whether
		 * any of the other pins can be ground.
		 */
		void setInterGroundDependent( ElementMapList::iterator it, const QValueList<Pin*> & pins );
		/**
		 * List of ElementMaps; which contain information on the pins associated
		 * with the element as well as the dependence between the pins for that
		 * element.
		 * @see ElementMap
		 */
		ElementMapList m_elementMapList;
		/**
		 * The switches used by the component.
		 */
		SwitchList m_switchList;
		/**
		 * @return an iterator to the element in m_elementMapList
		 */
		ElementMapList::iterator handleElement( Element *e, const QValueList<Pin*> & pins );
};

#endif