demultiplexer.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2004-2005 by David Saxton                               *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "demultiplexer.h"
00012 
00013 #include "logic.h"
00014 #include "libraryitem.h"
00015 
00016 #include <kiconloader.h>
00017 #include <klocale.h>
00018 
00019 #include <cmath>
00020 
00021 Item* Demultiplexer::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00022 {
00023         return new Demultiplexer( (ICNDocument*)itemDocument, newItem, id );
00024 }
00025 
00026 LibraryItem* Demultiplexer::libraryItem()
00027 {
00028         return new LibraryItem(
00029                 "ec/demultiplexer",
00030                 i18n("Demultiplexer"),
00031                 i18n("Integrated Circuits"),
00032                 "ic1.png",
00033                 LibraryItem::lit_component,
00034                 Demultiplexer::construct
00035                         );
00036 }
00037 
00038 Demultiplexer::Demultiplexer( ICNDocument *icnDocument, bool newItem, const char *id )
00039         : Component( icnDocument, newItem, id ? id : "demultiplexer" )
00040 {
00041         m_name = i18n("Demultiplexer");
00042         m_desc = i18n("Seperates the input data stream into components. The value of the input is passed to the \"X\" output selected by the binary number given by the \"A\" inputs.");
00043         
00044         m_input = 0;
00045         
00046         createProperty( "addressSize", Variant::Type::Int );
00047         property("addressSize")->setCaption( i18n("Address Size") );
00048         property("addressSize")->setMinValue(1);
00049         property("addressSize")->setMaxValue(8);
00050         property("addressSize")->setValue(1);
00051         
00052         // For backwards compatibility
00053         createProperty( "numInput", Variant::Type::Int );
00054         property("numInput")->setMinValue(-1);
00055         property("numInput")->setValue(-1);
00056         property("numInput")->setHidden(true);
00057 }
00058 
00059 Demultiplexer::~Demultiplexer()
00060 {
00061 }
00062 
00063 
00064 void Demultiplexer::dataChanged()
00065 {
00066         if ( hasProperty("numInput") && dataInt("numInput") != -1 )
00067         {
00068                 int addressSize = int( std::ceil( std::log( (double)dataInt("numInput") ) / std::log(2.0) ) );
00069                 property("numInput")->setValue(-1);
00070                 
00071                 if ( addressSize < 1 )
00072                         addressSize = 1;
00073                 else if ( addressSize > 8 )
00074                         addressSize = 8;
00075                 
00076                 // This function will get called again when we set the value of numInput
00077                 property("addressSize")->setValue(addressSize);
00078                 return;
00079         }
00080         
00081         if ( hasProperty("numInput") )
00082         {
00083                 m_variantData["numInput"]->deleteLater();
00084                 m_variantData.remove("numInput");
00085         }
00086         
00087         initPins( unsigned(dataInt("addressSize")) );
00088 }
00089 
00090 
00091 void Demultiplexer::inStateChanged( bool /*state*/ )
00092 {
00093         unsigned long long pos = 0;
00094         for ( unsigned i = 0; i < m_aLogic.size(); ++i )
00095         {
00096                 if ( m_aLogic[i]->isHigh() )
00097                         pos += 1 << i;
00098         }
00099         for ( unsigned i = 0; i < m_xLogic.size(); ++i )
00100                 m_xLogic[i]->setHigh( (pos == i) && m_input->isHigh() );
00101 }
00102 
00103 
00104 void Demultiplexer::initPins( unsigned newAddressSize )
00105 {
00106         unsigned oldAddressSize = m_aLogic.size();
00107         unsigned long long oldXLogicCount = m_xLogic.size();
00108         unsigned long long newXLogicCount = 1 << newAddressSize;
00109         
00110         if ( newXLogicCount == oldXLogicCount )
00111                 return;
00112         
00113         QStringList pins;
00114         
00115         for ( unsigned i=0; i<newAddressSize; ++i )
00116                 pins += "A"+QString::number(i);
00117         for ( unsigned i=newAddressSize; i<(newXLogicCount+(newXLogicCount%2))/2; ++i )
00118                 pins += "";
00119         pins += "X";
00120         for ( unsigned i=(newXLogicCount+(newXLogicCount%2))/2+1; i<newXLogicCount; ++i )
00121                 pins += "";
00122         for ( int i=newXLogicCount-1; i>=0; --i )
00123                 pins += "X"+QString::number(i);
00124         
00125         initDIPSymbol( pins, 64 );
00126         initDIP(pins);
00127         
00128         ECNode *node;
00129         
00130         if (!m_input)
00131         {
00132                 node =  ecNodeWithID("X");
00133                 m_input = createLogicIn(node);
00134                 m_input->setCallback( this, (CallbackPtr)(&Demultiplexer::inStateChanged) );
00135         }
00136         
00137         if ( newXLogicCount > oldXLogicCount )
00138         {
00139                 m_xLogic.resize(newXLogicCount);
00140                 for ( unsigned i = oldXLogicCount; i < newXLogicCount; ++i )
00141                 {
00142                         node = ecNodeWithID("X"+QString::number(i));
00143                         m_xLogic.insert( i, createLogicOut(node,false) );
00144                 }
00145                 
00146                 m_aLogic.resize(newAddressSize);
00147                 for ( unsigned i = oldAddressSize; i < newAddressSize; ++i )
00148                 {
00149                         node = ecNodeWithID("A"+QString::number(i));
00150                         m_aLogic.insert( i, createLogicIn(node) );
00151                         m_aLogic[i]->setCallback( this, (CallbackPtr)(&Demultiplexer::inStateChanged) );
00152                 }
00153         }
00154         else
00155         {
00156                 for ( unsigned i = newXLogicCount; i < oldXLogicCount; ++i )
00157                 {
00158                         QString id = "X"+QString::number(i);
00159                         removeDisplayText(id);
00160                         removeElement( m_xLogic[i], false );
00161                         removeNode(id);
00162                 }
00163                 m_xLogic.resize(newXLogicCount);
00164                 
00165                 for ( unsigned i = newAddressSize; i < oldAddressSize; ++i )
00166                 {
00167                         QString id = "A"+QString::number(i);
00168                         removeDisplayText(id);
00169                         removeElement( m_aLogic[i], false );
00170                         removeNode(id);
00171                 }
00172                 m_aLogic.resize(newAddressSize);
00173         }
00174 }
00175 

Generated on Tue May 8 17:05:29 2007 for KTechLab by  doxygen 1.5.1