File indexing completed on 2024-06-16 11:34:23

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"