File indexing completed on 2025-04-13 11:19:26
0001 /*************************************************************************** 0002 * Copyright (C) 2006 David Saxton <david@bluehaze.org> * 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 "componentmodellibrary.h" 0011 0012 #include <QFile> 0013 #include <QStandardPaths> 0014 #include <QElapsedTimer> 0015 0016 #include <cassert> 0017 0018 #include <ktechlab_debug.h> 0019 0020 // A prime number slightly larger than the number of models for any particular type 0021 // const int maxComponentModels = 101; 0022 0023 // BEGIN class ComponentModel 0024 ComponentModel::ComponentModel() 0025 { 0026 } 0027 0028 ComponentModel::~ComponentModel() 0029 { 0030 } 0031 0032 double ComponentModel::property(const QString &name) const 0033 { 0034 return m_property[name]; 0035 } 0036 0037 void ComponentModel::setProperty(const QString &name, double value) 0038 { 0039 m_property[name] = value; 0040 } 0041 // END class ComponentModel 0042 0043 // BEGIN class ComponentModelLibrary 0044 ComponentModelLibrary *ComponentModelLibrary::m_pSelf = nullptr; 0045 0046 // static 0047 ComponentModelLibrary *ComponentModelLibrary::self() 0048 { 0049 if (!m_pSelf) 0050 m_pSelf = new ComponentModelLibrary; 0051 0052 return m_pSelf; 0053 } 0054 0055 ComponentModelLibrary::ComponentModelLibrary() 0056 { 0057 loadModels(); 0058 } 0059 0060 ComponentModelLibrary::~ComponentModelLibrary() 0061 { 0062 } 0063 0064 void ComponentModelLibrary::loadModels() 0065 { 0066 QElapsedTimer ct; 0067 ct.start(); 0068 0069 QStringList files; 0070 files << "transistors_lib.txt"; 0071 0072 // Used to check that maxComponentModels isn't too small 0073 typedef QMap<ModelType, int> IntMap; 0074 IntMap modelCount; 0075 0076 QStringList::iterator end = files.end(); 0077 for (QStringList::iterator it = files.begin(); it != end; ++it) { 0078 QString fileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, "models/" + *it); 0079 if (fileName.isEmpty()) { 0080 qCWarning(KTL_LOG) << "Could not find library file \"" << *it << "\"."; 0081 continue; 0082 } 0083 0084 QFile file(fileName); 0085 if (!file.open(QIODevice::ReadOnly)) { 0086 qCWarning(KTL_LOG) << "Could not open library file \"" << fileName << "\" for reading."; 0087 continue; 0088 } 0089 0090 QString id; 0091 QString typeString; 0092 ComponentModel *model = nullptr; 0093 0094 QTextStream stream(&file); 0095 while (!stream.atEnd()) { 0096 QString line = stream.readLine(); 0097 0098 if (line.isEmpty()) 0099 continue; 0100 0101 if (line == "[/]") { 0102 // End of previous model 0103 0104 assert(model); 0105 0106 ModelType type = None; 0107 if (typeString == "NPN") 0108 type = NPN; 0109 else if (typeString == "PNP") 0110 type = PNP; 0111 else 0112 qCCritical(KTL_LOG) << "Unknown type \"" << typeString << "\"."; 0113 0114 if (m_componentModelIDs[type].contains(id)) 0115 qCCritical(KTL_LOG) << "Already have model with id=\"" << id << "\" for type=\"" << typeString << "\"."; 0116 0117 if (!m_componentModels.contains(type)) { 0118 m_componentModels[type] = ComponentModelDict(/* maxComponentModels */); 0119 // m_componentModels[type].setAutoDelete( true ); // 2018.08.14 - not needed 0120 } 0121 0122 m_componentModels[type].insert(id, *model); 0123 m_componentModelIDs[type] << id; 0124 0125 /* if ( int(modelCount[type] * 1.2) > maxComponentModels ) // 2018.08.14 - not needed 0126 { 0127 qCWarning(KTL_LOG) << "There are "<<modelCount[type]<<" models for component type \""<<typeString<<"\". Consider enlarging the dictionary."; 0128 } */ 0129 0130 // Reset the model 0131 model = nullptr; 0132 id = QString(); 0133 typeString = QString(); 0134 0135 modelCount[type]++; 0136 } else if (line.startsWith("[")) { 0137 // Already handled the case with "[/]", so must be beginning of 0138 // new model 0139 0140 // Check that their isn't a previous model that hasn't saved 0141 assert(!model); 0142 0143 model = new ComponentModel; 0144 id = line.mid(1, line.length() - 2); // extract the text between the square brackets 0145 } else { 0146 // Setting a property of the model 0147 assert(model); 0148 0149 int pos = line.indexOf('='); 0150 assert(pos != -1); 0151 0152 QString name = line.left(pos); 0153 QString value = line.mid(pos + 1); 0154 0155 if (name == "Description") 0156 model->setDescription(value); 0157 else if (name == "Type") 0158 typeString = value; 0159 else { 0160 bool ok; 0161 double realValue = value.toDouble(&ok); 0162 0163 if (!ok) 0164 qCCritical(KTL_LOG) << "Could not convert \"" << value << "\" to a real number (for property \"" << name << "\"."; 0165 else 0166 model->setProperty(name, realValue); 0167 } 0168 } 0169 } 0170 } 0171 0172 qCDebug(KTL_LOG) << "It took " << ct.elapsed() << " milliseconds to read in the component models."; 0173 } 0174 // END class ComponentModelLibrary 0175 0176 #include "moc_componentmodellibrary.cpp"