summaryrefslogtreecommitdiffstats
path: root/src/electronics/wire.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/electronics/wire.cpp')
-rw-r--r--src/electronics/wire.cpp146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/electronics/wire.cpp b/src/electronics/wire.cpp
new file mode 100644
index 0000000..619295d
--- /dev/null
+++ b/src/electronics/wire.cpp
@@ -0,0 +1,146 @@
+/***************************************************************************
+ * Copyright (C) 2005 by David Saxton *
+ * david@bluehaze.org *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "pin.h"
+#include "wire.h"
+#include <assert.h>
+
+Wire::Wire( Pin * startPin, Pin * endPin )
+{
+ assert(startPin);
+ assert(endPin);
+
+ m_pStartPin = startPin;
+ m_pEndPin = endPin;
+ m_current = 0.;
+ m_bCurrentIsKnown = false;
+
+ m_pStartPin->addOutputWire(this);
+ m_pEndPin->addInputWire(this);
+}
+
+
+Wire::~Wire()
+{
+}
+
+
+bool Wire::calculateCurrent()
+{
+ if ( m_pStartPin->currentIsKnown() && m_pStartPin->numWires() < 2 )
+ {
+ m_current = m_pStartPin->current();
+ m_bCurrentIsKnown = true;
+ return true;
+ }
+
+ if ( m_pEndPin->currentIsKnown() && m_pEndPin->numWires() < 2 )
+ {
+ m_current = -m_pEndPin->current();
+ m_bCurrentIsKnown = true;
+ return true;
+ }
+
+ if ( m_pStartPin->currentIsKnown() )
+ {
+ double i = m_pStartPin->current();
+ bool ok = true;
+ const WireList outlist = m_pStartPin->outputWireList();
+ WireList::const_iterator end = outlist.end();
+ for ( WireList::const_iterator it = outlist.begin(); it != end && ok; ++it )
+ {
+ if ( *it && (Wire*)*it != this )
+ {
+ if ( (*it)->currentIsKnown() )
+ i -= (*it)->current();
+
+ else
+ ok = false;
+ }
+ }
+ const WireList inlist = m_pStartPin->inputWireList();
+ end = inlist.end();
+ for ( WireList::const_iterator it = inlist.begin(); it != end && ok; ++it )
+ {
+ if ( *it && (Wire*)*it != this )
+ {
+ if ( (*it)->currentIsKnown() )
+ i += (*it)->current();
+
+ else
+ ok = false;
+ }
+ }
+
+ if (ok)
+ {
+ m_current = i;
+ m_bCurrentIsKnown = true;
+ return true;
+ }
+ }
+
+ if ( m_pEndPin->currentIsKnown() )
+ {
+ double i = -m_pEndPin->current();
+ bool ok = true;
+ const WireList outlist = m_pEndPin->outputWireList();
+ WireList::const_iterator end = outlist.end();
+ for ( WireList::const_iterator it = outlist.begin(); it != end && ok; ++it )
+ {
+ if ( *it && (Wire*)*it != this )
+ {
+ if ( (*it)->currentIsKnown() )
+ i += (*it)->current();
+
+ else
+ ok = false;
+ }
+ }
+ const WireList inlist = m_pEndPin->inputWireList();
+ end = inlist.end();
+ for ( WireList::const_iterator it = inlist.begin(); it != end && ok; ++it )
+ {
+ if ( *it && (Wire*)*it != this )
+ {
+ if ( (*it)->currentIsKnown() )
+ i -= (*it)->current();
+
+ else
+ ok = false;
+ }
+ }
+
+ if (ok)
+ {
+ m_current = i;
+ m_bCurrentIsKnown = true;
+ return true;
+ }
+ }
+
+ m_bCurrentIsKnown = false;
+ return false;
+}
+
+
+double Wire::voltage() const
+{
+ return ( m_pStartPin->voltage() + m_pEndPin->voltage() )/2;
+}
+
+
+void Wire::setCurrentKnown( bool known )
+{
+ m_bCurrentIsKnown = known;
+ if (!known)
+ m_current = 0.;
+}
+