File indexing completed on 2024-05-05 05:46:07
0001 /*************************************************************************** 0002 * Copyright (C) 2004-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 #include "multiplexer.h" 0012 0013 #include "libraryitem.h" 0014 #include "logic.h" 0015 0016 #include <KLocalizedString> 0017 0018 #include <cmath> 0019 0020 void Multiplexer_inStateChanged(void *objV, bool state) { 0021 Multiplexer *objT = static_cast<Multiplexer*>(objV); 0022 objT->inStateChanged(state); 0023 } 0024 0025 Item *Multiplexer::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0026 { 0027 return new Multiplexer(static_cast<ICNDocument *>(itemDocument), newItem, id); 0028 } 0029 0030 LibraryItem *Multiplexer::libraryItem() 0031 { 0032 return new LibraryItem(QStringList(QString("ec/multiplexer")), i18n("Multiplexer"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, Multiplexer::construct); 0033 } 0034 0035 Multiplexer::Multiplexer(ICNDocument *icnDocument, bool newItem, const char *id) 0036 : Component(icnDocument, newItem, id ? id : "multiplexer") 0037 { 0038 m_name = i18n("Multiplexer"); 0039 0040 m_output = nullptr; 0041 0042 createProperty("addressSize", Variant::Type::Int); 0043 property("addressSize")->setCaption(i18n("Address Size")); 0044 property("addressSize")->setMinValue(1); 0045 property("addressSize")->setMaxValue(8); 0046 property("addressSize")->setValue(1); 0047 0048 // For backwards compatibility 0049 createProperty("numInput", Variant::Type::Int); 0050 property("numInput")->setMinValue(-1); 0051 property("numInput")->setValue(-1); 0052 property("numInput")->setHidden(true); 0053 } 0054 0055 Multiplexer::~Multiplexer() 0056 { 0057 } 0058 0059 void Multiplexer::dataChanged() 0060 { 0061 if (hasProperty("numInput") && dataInt("numInput") != -1) { 0062 int addressSize = int(std::ceil(std::log(double(dataInt("numInput"))) / std::log(2.0))); 0063 property("numInput")->setValue(-1); 0064 0065 if (addressSize < 1) 0066 addressSize = 1; 0067 else if (addressSize > 8) 0068 addressSize = 8; 0069 0070 // This function will get called again when we set the value of numInput 0071 property("addressSize")->setValue(addressSize); 0072 return; 0073 } 0074 0075 if (hasProperty("numInput")) { 0076 m_variantData["numInput"]->deleteLater(); 0077 m_variantData.remove("numInput"); 0078 } 0079 0080 initPins(unsigned(dataInt("addressSize"))); 0081 } 0082 0083 void Multiplexer::inStateChanged(bool /*state*/) 0084 { 0085 unsigned long long pos = 0; 0086 for (int i = 0; i < m_aLogic.size(); ++i) { 0087 if (m_aLogic[i]->isHigh()) 0088 pos += 1 << i; 0089 } 0090 m_output->setHigh(m_xLogic[pos]->isHigh()); 0091 } 0092 0093 void Multiplexer::initPins(unsigned newAddressSize) 0094 { 0095 unsigned oldAddressSize = m_aLogic.size(); 0096 unsigned long long oldXLogicCount = m_xLogic.size(); 0097 unsigned long long newXLogicCount = 1 << newAddressSize; 0098 0099 if (newXLogicCount == oldXLogicCount) 0100 return; 0101 0102 QStringList pins; 0103 0104 const int length = newAddressSize + newXLogicCount; 0105 0106 for (unsigned i = 0; i < newAddressSize; ++i) 0107 pins += "A" + QString::number(i); 0108 for (unsigned i = 0; i < newXLogicCount; ++i) 0109 pins += "X" + QString::number(i); 0110 for (int i = 0; i < (length - (length % 2)) / 2; ++i) 0111 pins += ""; 0112 pins += "X"; 0113 for (int i = 0; i < ((length + (length % 2)) / 2) - 1; ++i) 0114 pins += ""; 0115 0116 initDIPSymbol(pins, 64); 0117 initDIP(pins); 0118 0119 ECNode *node; 0120 0121 if (!m_output) { 0122 node = ecNodeWithID("X"); 0123 m_output = createLogicOut(node, false); 0124 } 0125 0126 if (newXLogicCount > oldXLogicCount) { 0127 m_xLogic.resize(newXLogicCount); 0128 for (unsigned i = oldXLogicCount; i < newXLogicCount; ++i) { 0129 node = ecNodeWithID("X" + QString::number(i)); 0130 m_xLogic.insert(i, createLogicIn(node)); 0131 //m_xLogic[i]->setCallback(this, (CallbackPtr)(&Multiplexer::inStateChanged)); 0132 m_xLogic[i]->setCallback2(Multiplexer_inStateChanged, this); 0133 } 0134 0135 m_aLogic.resize(newAddressSize); 0136 for (unsigned i = oldAddressSize; i < newAddressSize; ++i) { 0137 node = ecNodeWithID("A" + QString::number(i)); 0138 m_aLogic.insert(i, createLogicIn(node)); 0139 //m_aLogic[i]->setCallback(this, (CallbackPtr)(&Multiplexer::inStateChanged)); 0140 m_aLogic[i]->setCallback2(Multiplexer_inStateChanged, this); 0141 } 0142 } else { 0143 for (unsigned i = newXLogicCount; i < oldXLogicCount; ++i) { 0144 QString id = "X" + QString::number(i); 0145 removeDisplayText(id); 0146 removeElement(m_xLogic[i], false); 0147 removeNode(id); 0148 } 0149 m_xLogic.resize(newXLogicCount); 0150 0151 for (unsigned i = newAddressSize; i < oldAddressSize; ++i) { 0152 QString id = "A" + QString::number(i); 0153 removeDisplayText(id); 0154 removeElement(m_aLogic[i], false); 0155 removeNode(id); 0156 } 0157 m_aLogic.resize(newAddressSize); 0158 } 0159 }