File indexing completed on 2024-05-05 05:46:03
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 "demultiplexer.h" 0012 0013 #include "libraryitem.h" 0014 #include "logic.h" 0015 0016 #include <KLocalizedString> 0017 0018 #include <cmath> 0019 0020 Item *Demultiplexer::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0021 { 0022 return new Demultiplexer(static_cast<ICNDocument *>(itemDocument), newItem, id); 0023 } 0024 0025 LibraryItem *Demultiplexer::libraryItem() 0026 { 0027 return new LibraryItem(QStringList(QString("ec/demultiplexer")), i18n("Demultiplexer"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, Demultiplexer::construct); 0028 } 0029 0030 void Demultiplexer_inStateChanged(void *objV, bool newState) { 0031 Demultiplexer *objT = static_cast<Demultiplexer*>(objV); 0032 objT->inStateChanged(newState); 0033 } 0034 0035 Demultiplexer::Demultiplexer(ICNDocument *icnDocument, bool newItem, const char *id) 0036 : Component(icnDocument, newItem, id ? id : "demultiplexer") 0037 { 0038 m_name = i18n("Demultiplexer"); 0039 0040 m_input = 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 Demultiplexer::~Demultiplexer() 0056 { 0057 } 0058 0059 void Demultiplexer::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 Demultiplexer::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 for (int i = 0; i < m_xLogic.size(); ++i) 0091 m_xLogic[i]->setHigh((int(pos) == i) && m_input->isHigh()); 0092 } 0093 0094 void Demultiplexer::initPins(unsigned newAddressSize) 0095 { 0096 unsigned oldAddressSize = m_aLogic.size(); 0097 unsigned long long oldXLogicCount = m_xLogic.size(); 0098 unsigned long long newXLogicCount = 1 << newAddressSize; 0099 0100 if (newXLogicCount == oldXLogicCount) 0101 return; 0102 0103 QStringList pins; 0104 0105 for (unsigned i = 0; i < newAddressSize; ++i) 0106 pins += "A" + QString::number(i); 0107 for (unsigned i = newAddressSize; i < (newXLogicCount + (newXLogicCount % 2)) / 2; ++i) 0108 pins += ""; 0109 pins += "X"; 0110 for (unsigned i = (newXLogicCount + (newXLogicCount % 2)) / 2 + 1; i < newXLogicCount; ++i) 0111 pins += ""; 0112 for (int i = newXLogicCount - 1; i >= 0; --i) 0113 pins += "X" + QString::number(i); 0114 0115 initDIPSymbol(pins, 64); 0116 initDIP(pins); 0117 0118 ECNode *node; 0119 0120 if (!m_input) { 0121 node = ecNodeWithID("X"); 0122 m_input = createLogicIn(node); 0123 //m_input->setCallback(this, (CallbackPtr)(&Demultiplexer::inStateChanged)); 0124 m_input->setCallback2(Demultiplexer_inStateChanged, this); 0125 } 0126 0127 if (newXLogicCount > oldXLogicCount) { 0128 m_xLogic.resize(newXLogicCount); 0129 for (unsigned i = oldXLogicCount; i < newXLogicCount; ++i) { 0130 node = ecNodeWithID("X" + QString::number(i)); 0131 m_xLogic.insert(i, createLogicOut(node, false)); 0132 } 0133 0134 m_aLogic.resize(newAddressSize); 0135 for (unsigned i = oldAddressSize; i < newAddressSize; ++i) { 0136 node = ecNodeWithID("A" + QString::number(i)); 0137 m_aLogic.insert(i, createLogicIn(node)); 0138 //m_aLogic[i]->setCallback(this, (CallbackPtr)(&Demultiplexer::inStateChanged)); 0139 m_aLogic[i]->setCallback2(Demultiplexer_inStateChanged, this); 0140 } 0141 } else { 0142 for (unsigned i = newXLogicCount; i < oldXLogicCount; ++i) { 0143 QString id = "X" + QString::number(i); 0144 removeDisplayText(id); 0145 removeElement(m_xLogic[i], false); 0146 removeNode(id); 0147 } 0148 m_xLogic.resize(newXLogicCount); 0149 0150 for (unsigned i = newAddressSize; i < oldAddressSize; ++i) { 0151 QString id = "A" + QString::number(i); 0152 removeDisplayText(id); 0153 removeElement(m_aLogic[i], false); 0154 removeNode(id); 0155 } 0156 m_aLogic.resize(newAddressSize); 0157 } 0158 }