File indexing completed on 2024-05-05 05:46:06

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by Fredy Yanardi                                   *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  ***************************************************************************/
0009 
0010 #include "magnitudecomparator.h"
0011 #include "libraryitem.h"
0012 #include "logic.h"
0013 #include "variant.h"
0014 
0015 #include <KLocalizedString>
0016 #include <cmath>
0017 
0018 void MagnitudeComparator_inStateChangedWithVal(void *objV, bool state) { // Enable
0019     MagnitudeComparator *objT = static_cast<MagnitudeComparator*>(objV);
0020     objT->inStateChangedWithVal(state);
0021 }
0022 
0023 Item *MagnitudeComparator::construct(ItemDocument *itemDocument, bool newItem, const char *id)
0024 {
0025     return new MagnitudeComparator(static_cast<ICNDocument *>(itemDocument), newItem, id);
0026 }
0027 
0028 LibraryItem *MagnitudeComparator::libraryItem()
0029 {
0030     return new LibraryItem(QStringList(QString("ec/magnitudecomparator")), i18n("Magnitude Comparator"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, MagnitudeComparator::construct);
0031 }
0032 
0033 MagnitudeComparator::MagnitudeComparator(ICNDocument *icnDocument, bool newItem, const char *id)
0034     : Component(icnDocument, newItem, id ? id : "magnitudecomparator")
0035 {
0036     m_name = i18n("Magnitude Comparator");
0037 
0038     createProperty("numInput", Variant::Type::Int);
0039     property("numInput")->setCaption(i18n("Number Inputs"));
0040     property("numInput")->setMinValue(1);
0041     property("numInput")->setMaxValue(8);
0042     property("numInput")->setValue(4);
0043 
0044     m_oldABLogicCount = 0;
0045     cascadingInputs = 3;
0046     outputs = 3;
0047 
0048     firstTime = true;
0049 }
0050 
0051 MagnitudeComparator::~MagnitudeComparator()
0052 {
0053 }
0054 
0055 void MagnitudeComparator::dataChanged()
0056 {
0057     initPins();
0058 }
0059 
0060 void MagnitudeComparator::inStateChangedWithVal(bool /*isHigh*/) {
0061     inStateChanged();
0062 }
0063 void MagnitudeComparator::inStateChanged()
0064 {
0065     int i;
0066 
0067     for (i = 0; i < 3; i++)
0068         m_output[i]->setHigh(false);
0069 
0070     //  for ( i = dataInt("numInput")-1; i >= 0; i-- ) {
0071     for (i = m_oldABLogicCount - 1; i >= 0; i--) {
0072         if (m_aLogic[i]->isHigh() && !m_bLogic[i]->isHigh()) {
0073             m_output[0]->setHigh(true);
0074             return;
0075         } else if (!m_aLogic[i]->isHigh() && m_bLogic[i]->isHigh()) {
0076             m_output[1]->setHigh(true);
0077             return;
0078         }
0079     }
0080 
0081     if (m_cLogic[2]->isHigh())
0082         m_output[2]->setHigh(true);
0083     else if (m_cLogic[0]->isHigh()) {
0084         if (!m_cLogic[1]->isHigh())
0085             m_output[0]->setHigh(true);
0086     } else if (m_cLogic[1]->isHigh())
0087         m_output[1]->setHigh(true);
0088     else {
0089         m_output[0]->setHigh(true);
0090         m_output[1]->setHigh(true);
0091     }
0092 }
0093 
0094 void MagnitudeComparator::initPins()
0095 {
0096     const double numInputs = dataInt("numInput");
0097     int newABLogicCount = int(numInputs);
0098 
0099     if (newABLogicCount == m_oldABLogicCount)
0100         return;
0101 
0102     QStringList leftPins;
0103     int space = 3 - newABLogicCount;
0104     for (int i = 0; i < space; i++)
0105         leftPins << "";
0106     for (int i = 0; i < newABLogicCount; i++)
0107         leftPins << QString("A%1").arg(QString::number(i));
0108     for (int i = 0; i < newABLogicCount; i++)
0109         leftPins << QString("B%1").arg(QString::number(i));
0110     for (int i = 0; i < space; i++)
0111         leftPins << "";
0112 
0113     QStringList rightPins;
0114     space = -space;
0115     for (int i = 0; i < space; i++)
0116         rightPins << "";
0117     QString inNames[] = {"I: A>B", "I: A<B", "I: A=B"};
0118     rightPins << inNames[2] << inNames[1] << inNames[0];
0119     QString outNames[] = {"O: A>B", "O: A<B", "O: A=B"};
0120     rightPins << outNames[2] << outNames[1] << outNames[0];
0121     for (int i = 0; i < space; i++)
0122         rightPins << "";
0123 
0124     QStringList pins = leftPins + rightPins;
0125 
0126     initDIPSymbol(pins, 88);
0127     initDIP(pins);
0128 
0129     ECNode *node;
0130 
0131     if (firstTime) {
0132         m_cLogic.resize(3);
0133         for (int i = 0; i < cascadingInputs; i++) {
0134             node = ecNodeWithID(inNames[i]);
0135             m_cLogic.insert(i, createLogicIn(node));
0136             //m_cLogic[i]->setCallback(this, (CallbackPtr)(&MagnitudeComparator::inStateChangedWithVal));
0137             m_cLogic[i]->setCallback2(MagnitudeComparator_inStateChangedWithVal, this);
0138         }
0139 
0140         m_output.resize(3);
0141         for (int i = 0; i < outputs; i++) {
0142             node = ecNodeWithID(outNames[i]);
0143             m_output.insert(i, createLogicOut(node, false));
0144         }
0145         firstTime = false;
0146     }
0147 
0148     if (newABLogicCount > m_oldABLogicCount) {
0149         m_aLogic.resize(newABLogicCount);
0150         for (int i = m_oldABLogicCount; i < newABLogicCount; ++i) {
0151             node = ecNodeWithID("A" + QString::number(i));
0152             m_aLogic.insert(i, createLogicIn(node));
0153             //m_aLogic[i]->setCallback(this, (CallbackPtr)(&MagnitudeComparator::inStateChangedWithVal));
0154             m_aLogic[i]->setCallback2(MagnitudeComparator_inStateChangedWithVal, this);
0155         }
0156 
0157         m_bLogic.resize(newABLogicCount);
0158         for (int i = m_oldABLogicCount; i < newABLogicCount; ++i) {
0159             node = ecNodeWithID("B" + QString::number(i));
0160             m_bLogic.insert(i, createLogicIn(node));
0161             //m_bLogic[i]->setCallback(this, (CallbackPtr)(&MagnitudeComparator::inStateChangedWithVal));
0162             m_bLogic[i]->setCallback2(MagnitudeComparator_inStateChangedWithVal, this);
0163         }
0164     } else {
0165         for (int i = newABLogicCount; i < m_oldABLogicCount; ++i) {
0166             QString id = "A" + QString::number(i);
0167             removeDisplayText(id);
0168             removeElement(m_aLogic[i], false);
0169             removeNode(id);
0170         }
0171         m_aLogic.resize(newABLogicCount);
0172         for (int i = newABLogicCount; i < m_oldABLogicCount; ++i) {
0173             QString id = "B" + QString::number(i);
0174             removeDisplayText(id);
0175             removeElement(m_bLogic[i], false);
0176             removeNode(id);
0177         }
0178         m_bLogic.resize(newABLogicCount);
0179     }
0180 
0181     m_oldABLogicCount = newABLogicCount;
0182     inStateChanged();
0183 }