File indexing completed on 2024-12-22 04:17:53
0001 /*************************************************************************** 0002 dataobject.cpp: base class for data objects 0003 ------------------- 0004 begin : May 20, 2003 0005 copyright : (C) 2003 by C. Barth Netterfield 0006 email : netterfield@astro.utoronto.ca 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 ***************************************************************************/ 0017 0018 #include "dataobject.h" 0019 0020 #include "datacollection.h" 0021 #include "dataobjectplugin.h" 0022 #include "debug.h" 0023 0024 #include "objectstore.h" 0025 #include "relation.h" 0026 #include "sharedptr.h" 0027 #include "primitive.h" 0028 #include "settings.h" 0029 0030 #include "dataobjectscriptinterface.h" 0031 0032 #include <QApplication> 0033 #include <QDir> 0034 #include <qdebug.h> 0035 #include <qtimer.h> 0036 #include <QPluginLoader> 0037 #include <QLibraryInfo> 0038 #include <QXmlStreamReader> 0039 #include <QXmlStreamWriter> 0040 #include <limits.h> 0041 #include <assert.h> 0042 0043 //#define LOCKTRACE 0044 0045 using namespace Kst; 0046 0047 0048 QSettings& DataObject::settingsObject() 0049 { 0050 static QSettings& settingsObject = createSettings("data"); 0051 return settingsObject; 0052 } 0053 0054 QMap<QString,QString> DataObject::url_map; 0055 0056 0057 0058 0059 void DataObject::init() { 0060 initPlugins(); 0061 } 0062 0063 0064 DataObject::DataObject(ObjectStore *store) : Object() { 0065 Q_UNUSED(store); 0066 _curveHints = new CurveHintList; 0067 } 0068 0069 0070 DataObject::~DataObject() { 0071 delete _curveHints; 0072 } 0073 0074 0075 static DataObjectPluginList _pluginList; 0076 void DataObject::cleanupForExit() { 0077 _pluginList.clear(); //FIXME? 0078 } 0079 0080 0081 void DataObject::attach() { 0082 } 0083 0084 void DataObject::replaceInput(PrimitivePtr p, PrimitivePtr new_p) { 0085 if (VectorPtr v = kst_cast<Vector>(p) ) { 0086 if (VectorPtr new_v = kst_cast<Vector>(new_p)) { 0087 for (VectorMap::Iterator j = _inputVectors.begin(); j != _inputVectors.end(); ++j) { 0088 if (j.value() == v) { 0089 _inputVectors[j.key()] = new_v; 0090 } 0091 } 0092 } 0093 } else if (MatrixPtr m = kst_cast<Matrix>(p) ) { 0094 if (MatrixPtr new_m = kst_cast<Matrix>(new_p)) { 0095 for (MatrixMap::Iterator j = _inputMatrices.begin(); j != _inputMatrices.end(); ++j) { 0096 if (j.value() == m) { 0097 _inputMatrices[j.key()] = new_m; 0098 } 0099 } 0100 } 0101 } else if (StringPtr s = kst_cast<String>(p) ) { 0102 if (StringPtr new_s = kst_cast<String>(new_p)) { 0103 for (StringMap::Iterator j = _inputStrings.begin(); j != _inputStrings.end(); ++j) { 0104 if (j.value() == s) { 0105 _inputStrings[j.key()] = new_s; 0106 } 0107 } 0108 } 0109 } else if (ScalarPtr s = kst_cast<Scalar>(p) ) { 0110 if (ScalarPtr new_s = kst_cast<Scalar>(new_p)) { 0111 for (ScalarMap::Iterator j = _inputScalars.begin(); j != _inputScalars.end(); ++j) { 0112 if (j.value() == s) { 0113 _inputScalars[j.key()] = new_s; 0114 } 0115 } 0116 } 0117 } 0118 } 0119 0120 0121 VectorPtr DataObject::outputVector(const QString& vector) const { 0122 VectorMap::ConstIterator i = _outputVectors.constFind(vector); 0123 if (i != _outputVectors.constEnd()) 0124 return *i; 0125 else 0126 return 0; 0127 } 0128 0129 0130 ScalarPtr DataObject::outputScalar(const QString& scalar) const { 0131 ScalarMap::ConstIterator i = _outputScalars.constFind(scalar); 0132 if (i != _outputScalars.constEnd()) 0133 return *i; 0134 else 0135 return 0; 0136 } 0137 0138 0139 StringPtr DataObject::outputString(const QString& string) const { 0140 StringMap::ConstIterator i = _outputStrings.constFind(string); 0141 if (i != _outputStrings.constEnd()) 0142 return *i; 0143 else 0144 return 0; 0145 } 0146 0147 0148 void DataObject::setInputVector(const QString &type, VectorPtr ptr) { 0149 if (ptr) { 0150 _inputVectors[type] = ptr; 0151 } else { 0152 _inputVectors.remove(type); 0153 } 0154 } 0155 0156 0157 void DataObject::setInputScalar(const QString &type, ScalarPtr ptr) { 0158 if (ptr) { 0159 _inputScalars[type] = ptr; 0160 } else { 0161 _inputScalars.remove(type); 0162 } 0163 } 0164 0165 0166 void DataObject::setInputString(const QString &type, StringPtr ptr) { 0167 if (ptr) { 0168 _inputStrings[type] = ptr; 0169 } else { 0170 _inputStrings.remove(type); 0171 } 0172 } 0173 0174 PrimitiveList DataObject::inputPrimitives() const { 0175 PrimitiveList primitive_list; 0176 0177 int n = _inputMatrices.count(); 0178 for (int i = 0; i< n; i++) { 0179 primitive_list.append(kst_cast<Primitive>(_inputMatrices.values().at(i))); 0180 } 0181 0182 n = _inputStrings.count(); 0183 for (int i = 0; i< n; i++) { 0184 primitive_list.append(kst_cast<Primitive>(_inputStrings.values().at(i))); 0185 } 0186 0187 n = _inputScalars.count(); 0188 for (int i = 0; i< n; i++) { 0189 primitive_list.append(kst_cast<Primitive>(_inputScalars.values().at(i))); 0190 } 0191 0192 n = _inputVectors.count(); 0193 for (int i = 0; i< n; i++) { 0194 primitive_list.append(kst_cast<Primitive>(_inputVectors.values().at(i))); 0195 } 0196 0197 return primitive_list; 0198 } 0199 0200 0201 PrimitiveList DataObject::outputPrimitives(bool include_decendants) const { 0202 PrimitiveList primitive_list; 0203 0204 int n = _outputMatrices.count(); 0205 for (int i = 0; i< n; i++) { 0206 primitive_list.append(kst_cast<Primitive>(_outputMatrices.values().at(i))); 0207 if (include_decendants) { 0208 primitive_list.append(_outputMatrices.values().at(i)->outputPrimitives()); 0209 } 0210 } 0211 0212 n = _outputStrings.count(); 0213 for (int i = 0; i< n; i++) { 0214 primitive_list.append(kst_cast<Primitive>(_outputStrings.values().at(i))); 0215 if (include_decendants) { 0216 primitive_list.append(_outputStrings.values().at(i)->outputPrimitives()); 0217 } 0218 } 0219 0220 n = _outputScalars.count(); 0221 for (int i = 0; i< n; i++) { 0222 primitive_list.append(kst_cast<Primitive>(_outputScalars.values().at(i))); 0223 if (include_decendants) { 0224 primitive_list.append(_outputScalars.values().at(i)->outputPrimitives()); 0225 } 0226 } 0227 0228 n = _outputVectors.count(); 0229 for (int i = 0; i< n; i++) { 0230 primitive_list.append(kst_cast<Primitive>(_outputVectors.values().at(i))); 0231 if (include_decendants) { 0232 primitive_list.append(_outputVectors.values().at(i)->outputPrimitives()); 0233 } 0234 } 0235 0236 return primitive_list; 0237 } 0238 0239 0240 // set flags on all output primitives 0241 // used for sorting dataobjects by Document::sortedDataObjectList() 0242 void DataObject::setOutputFlags(bool flag) { 0243 PrimitiveList output_primitives = outputPrimitives(); 0244 int n = output_primitives.count(); 0245 for (int i=0; i<n; i++) { 0246 output_primitives[i]->setFlag(flag); 0247 } 0248 } 0249 0250 0251 bool DataObject::inputFlagsSet() const { 0252 PrimitiveList input_primitives = inputPrimitives(); 0253 int n = input_primitives.count(); 0254 bool all_set = true; 0255 for (int i=0; i<n; i++) { 0256 all_set &= input_primitives[i]->flagSet(); 0257 } 0258 0259 return all_set; 0260 } 0261 0262 // Scans for plugins and stores the information for them 0263 void DataObject::scanPlugins() { 0264 Debug::self()->log(tr("Scanning for data-object plugins.")); 0265 0266 _pluginList.clear(); //FIXME? 0267 0268 DataObjectPluginList tmpList; 0269 0270 Debug::self()->log(tr("Scanning for data-object plugins.")); 0271 0272 foreach (QObject *plugin, QPluginLoader::staticInstances()) { 0273 //try a cast 0274 if (DataObjectPluginInterface *basicPlugin = qobject_cast<DataObjectPluginInterface*>(plugin)) { 0275 tmpList.append(basicPlugin); 0276 } 0277 } 0278 0279 QStringList pluginPaths = pluginSearchPaths(); 0280 foreach (const QString &pluginPath, pluginPaths) { 0281 QDir d(pluginPath); 0282 foreach (const QString &fileName, d.entryList(QDir::Files)) { 0283 QPluginLoader loader(d.absoluteFilePath(fileName)); 0284 QObject *plugin = loader.instance(); 0285 if (plugin) { 0286 if (DataObjectPluginInterface *dataObjectPlugin = qobject_cast<DataObjectPluginInterface*>(plugin)) { 0287 tmpList.append(dataObjectPlugin); 0288 Debug::self()->log(QString("Plugin loaded: %1").arg(fileName)); 0289 } 0290 } else { 0291 Debug::self()->log(QString("Plugin failed to load: %1").arg(fileName)); 0292 } 0293 } 0294 } 0295 0296 // This cleans up plugins that have been uninstalled and adds in new ones. 0297 // Since it is a shared pointer it can't dangle anywhere. 0298 _pluginList.clear(); 0299 _pluginList = tmpList; 0300 } 0301 0302 0303 void DataObject::initPlugins() { 0304 if (_pluginList.isEmpty()) { 0305 scanPlugins(); 0306 } 0307 } 0308 0309 0310 QStringList DataObject::pluginList() { 0311 // Ensure state. When using kstapp MainWindow calls init. 0312 init(); 0313 0314 QStringList plugins; 0315 0316 for (DataObjectPluginList::ConstIterator it = _pluginList.constBegin(); it != _pluginList.constEnd(); ++it) { 0317 plugins += (*it)->pluginName(); 0318 } 0319 0320 return plugins; 0321 } 0322 0323 0324 QStringList DataObject::dataObjectPluginList() { 0325 // Ensure state. When using kstapp MainWindow calls init. 0326 init(); 0327 0328 QStringList plugins; 0329 0330 for (DataObjectPluginList::ConstIterator it = _pluginList.constBegin(); it != _pluginList.constEnd(); ++it) { 0331 if ((*it)->pluginType() == DataObjectPluginInterface::Generic) { 0332 plugins += (*it)->pluginName(); 0333 } 0334 } 0335 0336 plugins.sort(); 0337 return plugins; 0338 } 0339 0340 0341 QStringList DataObject::filterPluginList() { 0342 // Ensure state. When using kstapp MainWindow calls init. 0343 init(); 0344 0345 QStringList plugins; 0346 0347 for (DataObjectPluginList::ConstIterator it = _pluginList.constBegin(); it != _pluginList.constEnd(); ++it) { 0348 if ((*it)->pluginType() == DataObjectPluginInterface::Filter) { 0349 plugins += (*it)->pluginName(); 0350 } 0351 } 0352 0353 plugins.sort(); 0354 return plugins; 0355 } 0356 0357 0358 QStringList DataObject::fitsPluginList() { 0359 // Ensure state. When using kstapp MainWindow calls init. 0360 init(); 0361 0362 QStringList plugins; 0363 0364 for (DataObjectPluginList::ConstIterator it = _pluginList.constBegin(); it != _pluginList.constEnd(); ++it) { 0365 if ((*it)->pluginType() == DataObjectPluginInterface::Fit) { 0366 plugins += (*it)->pluginName(); 0367 } 0368 } 0369 0370 plugins.sort(); 0371 return plugins; 0372 } 0373 0374 0375 DataObjectConfigWidget* DataObject::pluginWidget(const QString& name) { 0376 // Ensure state. When using kstapp MainWindow calls init. 0377 init(); 0378 0379 for (DataObjectPluginList::ConstIterator it = _pluginList.constBegin(); it != _pluginList.constEnd(); ++it) { 0380 if ((*it)->pluginName() == name) { 0381 if ((*it)->hasConfigWidget()) { 0382 0383 return (*it)->configWidget(&settingsObject()); 0384 } 0385 break; 0386 } 0387 } 0388 return 0L; 0389 } 0390 0391 0392 QString DataObject::pluginDescription(const QString& name) { 0393 // Ensure state. When using kstapp MainWindow calls init. 0394 init(); 0395 0396 for (DataObjectPluginList::ConstIterator it = _pluginList.constBegin(); it != _pluginList.constEnd(); ++it) { 0397 if ((*it)->pluginName() == name) { 0398 return (*it)->pluginDescription(); 0399 } 0400 } 0401 return QString(); 0402 } 0403 0404 0405 int DataObject::pluginType(const QString& name) { 0406 // Ensure state. When using kstapp MainWindow calls init. 0407 init(); 0408 0409 for (DataObjectPluginList::ConstIterator it = _pluginList.constBegin(); it != _pluginList.constEnd(); ++it) { 0410 if ((*it)->pluginName() == name) { 0411 return (*it)->pluginType(); 0412 } 0413 } 0414 return -1; 0415 } 0416 0417 0418 DataObjectPtr DataObject::createPlugin(const QString& name, ObjectStore *store, DataObjectConfigWidget *configWidget, bool setupInputsOutputs) { 0419 // Ensure state. When using kstapp MainWindow calls init. 0420 init(); 0421 0422 for (DataObjectPluginList::ConstIterator it = _pluginList.constBegin(); it != _pluginList.constEnd(); ++it) { 0423 if ((*it)->pluginName() == name) { 0424 if (DataObjectPtr object = (*it)->create(store, configWidget, setupInputsOutputs)) { 0425 return object; 0426 } 0427 } 0428 } 0429 0430 #if 0 0431 KService::List sl = KServiceTypeTrader::self()->query("Kst Data Object"); 0432 for (KService::List::ConstIterator it = sl.constBegin(); it != sl.constEnd(); ++it) { 0433 if ((*it)->name() != name) { 0434 continue; 0435 } else if (DataObjectPtr object = createPlugin(*it)) { 0436 return object; 0437 } 0438 } 0439 #endif 0440 return 0L; 0441 } 0442 0443 0444 #if 0 0445 double *DataObject::vectorRealloced(VectorPtr v, double *memptr, int newSize) const { 0446 if (!v) { 0447 return 0L; 0448 } 0449 0450 // One would think this needs special locking, but it results in deadlock 0451 // in complicated object hierarchies such as filtered vectors. Therefore if 0452 // you call vectorRealloced() and v is not locked by you already, you'd 0453 // better lock it! 0454 return v->realloced(memptr, newSize); 0455 } 0456 #endif 0457 0458 void DataObject::load(const QXmlStreamReader &e) { 0459 qDebug() << QString("FIXME! Loading of %1 is not implemented yet.").arg(typeString()) << endl; 0460 Q_UNUSED(e) 0461 } 0462 0463 0464 void DataObject::save(QXmlStreamWriter& ts) { 0465 qDebug() << QString("FIXME! Saving of %1 is not implemented yet.").arg(typeString()) << endl; 0466 Q_UNUSED(ts) 0467 } 0468 0469 int DataObject::getUsage() const { 0470 int rc = 0; 0471 0472 for (VectorMap::ConstIterator i = _outputVectors.constBegin(); i != _outputVectors.constEnd(); ++i) { 0473 if (i.value().data()) { 0474 rc += i.value()->getUsage() - 1; 0475 } 0476 } 0477 0478 for (ScalarMap::ConstIterator i = _outputScalars.constBegin(); i != _outputScalars.constEnd(); ++i) { 0479 if (i.value().data()) { 0480 rc += i.value()->getUsage() - 1; 0481 } 0482 } 0483 0484 for (StringMap::ConstIterator i = _outputStrings.constBegin(); i != _outputStrings.constEnd(); ++i) { 0485 if (i.value().data()) { 0486 rc += i.value()->getUsage() - 1; 0487 } 0488 } 0489 0490 for (MatrixMap::ConstIterator i = _outputMatrices.constBegin(); i != _outputMatrices.constEnd(); ++i) { 0491 if (i.value().data()) { 0492 rc += i.value()->getUsage() - 1; 0493 } 0494 } 0495 0496 return Object::getUsage() + rc; 0497 } 0498 0499 0500 void DataObject::showDialog(bool isNew) { 0501 if (isNew) { 0502 QTimer::singleShot(0, this, SLOT(showNewDialog())); 0503 } else { 0504 QTimer::singleShot(0, this, SLOT(showEditDialog())); 0505 } 0506 } 0507 0508 0509 void DataObject::readLock() const { 0510 #ifdef LOCKTRACE 0511 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::readLock() by tid=" << (int)QThread::currentThread() << ": read locking myself" << endl; 0512 #endif 0513 0514 Object::readLock(); 0515 } 0516 0517 0518 void DataObject::writeLock() const { 0519 #ifdef LOCKTRACE 0520 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::writeLock() by tid=" << (int)QThread::currentThread() << ": write locking myself" << endl; 0521 #endif 0522 0523 Object::writeLock(); 0524 } 0525 0526 0527 void DataObject::unlock() const { 0528 #ifdef LOCKTRACE 0529 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlock() by tid=" << (int)QThread::currentThread() << ": unlocking myself" << endl; 0530 #endif 0531 0532 Object::unlock(); 0533 } 0534 0535 0536 void DataObject::writeLockInputsAndOutputs() const { 0537 Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); 0538 0539 #ifdef LOCKTRACE 0540 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << endl; 0541 #endif 0542 0543 QList<PrimitivePtr> inputs; 0544 QList<PrimitivePtr> outputs; 0545 0546 QList<StringPtr> sl = _inputStrings.values(); 0547 for (QList<StringPtr>::Iterator i = sl.begin(); i != sl.end(); ++i) { 0548 inputs += (*i).data(); 0549 } 0550 sl = _outputStrings.values(); 0551 for (QList<StringPtr>::Iterator i = sl.begin(); i != sl.end(); ++i) { 0552 outputs += (*i).data(); 0553 } 0554 0555 QList<ScalarPtr> sc = _inputScalars.values(); 0556 for (QList<ScalarPtr>::Iterator i = sc.begin(); i != sc.end(); ++i) { 0557 inputs += (*i).data(); 0558 } 0559 sc = _outputScalars.values(); 0560 for (QList<ScalarPtr>::Iterator i = sc.begin(); i != sc.end(); ++i) { 0561 outputs += (*i).data(); 0562 } 0563 0564 QList<VectorPtr> vl = _inputVectors.values(); 0565 for (QList<VectorPtr>::Iterator i = vl.begin(); i != vl.end(); ++i) { 0566 inputs += (*i).data(); 0567 } 0568 vl = _outputVectors.values(); 0569 for (QList<VectorPtr>::Iterator i = vl.begin(); i != vl.end(); ++i) { 0570 outputs += (*i).data(); 0571 } 0572 0573 QList<MatrixPtr> ml = _inputMatrices.values(); 0574 for (QList<MatrixPtr>::Iterator i = ml.begin(); i != ml.end(); ++i) { 0575 inputs += (*i).data(); 0576 } 0577 ml = _outputMatrices.values(); 0578 for (QList<MatrixPtr>::Iterator i = ml.begin(); i != ml.end(); ++i) { 0579 outputs += (*i).data(); 0580 } 0581 0582 qSort(inputs); 0583 qSort(outputs); 0584 0585 QList<PrimitivePtr>::ConstIterator inputIt = inputs.constBegin(); 0586 QList<PrimitivePtr>::ConstIterator outputIt = outputs.constBegin(); 0587 0588 while (inputIt != inputs.constEnd() || outputIt != outputs.constEnd()) { 0589 if (inputIt != inputs.constEnd() && (outputIt == outputs.constEnd() || (void*)(*inputIt) < (void*)(*outputIt))) { 0590 // do input 0591 if (!(*inputIt)) { 0592 qWarning() << "Input for data object " << this->Name() << " is invalid." << endl; 0593 } 0594 #ifdef LOCKTRACE 0595 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": write locking input \"" << (*inputIt)->Name() << "\" (" << (void*)((KstRWLock*)*inputIt) << ")" << endl; 0596 #endif 0597 (*inputIt)->writeLock(); 0598 ++inputIt; 0599 } else { 0600 // do output 0601 if (!(*outputIt)) { 0602 qWarning() << "Output for data object " << this->Name() << " is invalid." << endl; 0603 } 0604 #ifdef LOCKTRACE 0605 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": write locking output \"" << (*outputIt)->Name() << "\" (" << (void*)((KstRWLock*)*outputIt) << ")" << endl; 0606 #endif 0607 if ((*outputIt)->provider() != this) { 0608 Debug::self()->log(tr("(%1) DataObject::writeLockInputsAndOutputs() by tid=%2: write locking output %3 (not provider) -- this is probably an error. Please email kst@kde.org with details.").arg(this->type()).arg(reinterpret_cast<qint64>(QThread::currentThread())).arg((*outputIt)->Name()), Debug::Error); 0609 } 0610 0611 (*outputIt)->writeLock(); 0612 ++outputIt; 0613 } 0614 } 0615 } 0616 0617 0618 void DataObject::unlockInputsAndOutputs() const { 0619 #ifdef LOCKTRACE 0620 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << endl; 0621 #endif 0622 0623 for (MatrixMap::ConstIterator i = _outputMatrices.constBegin(); i != _outputMatrices.constEnd(); ++i) { 0624 if (!(*i)) { 0625 qWarning() << "Output matrix for data object " << this->Name() << " is invalid." << endl; 0626 } 0627 #ifdef LOCKTRACE 0628 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output matrix \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; 0629 #endif 0630 (*i)->unlock(); 0631 } 0632 0633 for (MatrixMap::ConstIterator i = _inputMatrices.constBegin(); i != _inputMatrices.constEnd(); ++i) { 0634 if (!(*i)) { 0635 qWarning() << "Input matrix for data object " << this->Name() << " is invalid." << endl; 0636 } 0637 #ifdef LOCKTRACE 0638 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input matrix \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; 0639 #endif 0640 (*i)->unlock(); 0641 } 0642 0643 for (VectorMap::ConstIterator i = _outputVectors.constBegin(); i != _outputVectors.constEnd(); ++i) { 0644 if (!(*i)) { 0645 qWarning() << "Output vector for data object " << this->Name() << " is invalid." << endl; 0646 } 0647 #ifdef LOCKTRACE 0648 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output vector \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; 0649 #endif 0650 (*i)->unlock(); 0651 } 0652 0653 for (VectorMap::ConstIterator i = _inputVectors.constBegin(); i != _inputVectors.constEnd(); ++i) { 0654 if (!(*i)) { 0655 qWarning() << "Input vector for data object " << this->Name() << " is invalid." << endl; 0656 } 0657 #ifdef LOCKTRACE 0658 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input vector \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; 0659 #endif 0660 (*i)->unlock(); 0661 } 0662 0663 for (ScalarMap::ConstIterator i = _outputScalars.constBegin(); i != _outputScalars.constEnd(); ++i) { 0664 if (!(*i)) { 0665 qWarning() << "Output scalar for data object " << this->Name() << " is invalid." << endl; 0666 } 0667 #ifdef LOCKTRACE 0668 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output scalar \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; 0669 #endif 0670 (*i)->unlock(); 0671 } 0672 0673 for (ScalarMap::ConstIterator i = _inputScalars.constBegin(); i != _inputScalars.constEnd(); ++i) { 0674 if (!(*i)) { 0675 qWarning() << "Input scalar for data object " << this->Name() << " is invalid." << endl; 0676 } 0677 #ifdef LOCKTRACE 0678 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input scalar \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; 0679 #endif 0680 (*i)->unlock(); 0681 } 0682 0683 for (StringMap::ConstIterator i = _outputStrings.constBegin(); i != _outputStrings.constEnd(); ++i) { 0684 if (!(*i)) { 0685 qWarning() << "Output string for data object " << this->Name() << " is invalid." << endl; 0686 } 0687 #ifdef LOCKTRACE 0688 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output string \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; 0689 #endif 0690 (*i)->unlock(); 0691 } 0692 0693 for (StringMap::ConstIterator i = _inputStrings.constBegin(); i != _inputStrings.constEnd(); ++i) { 0694 if (!(*i)) { 0695 qWarning() << "Input string for data object " << this->Name() << " is invalid." << endl; 0696 } 0697 #ifdef LOCKTRACE 0698 qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input string \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; 0699 #endif 0700 (*i)->unlock(); 0701 } 0702 } 0703 0704 0705 bool DataObject::isValid() { 0706 return true; 0707 } 0708 0709 0710 const CurveHintList* DataObject::curveHints() const { 0711 return _curveHints; 0712 } 0713 0714 0715 void DataObject::deleteDependents() { 0716 DataObjectList dataObjects = _store->getObjects<DataObject>(); 0717 foreach (const DataObjectPtr &object, dataObjects) { 0718 bool usesObject = object->uses(this); 0719 if (!usesObject) { 0720 for (VectorMap::Iterator j = _outputVectors.begin(); !usesObject && j != _outputVectors.end(); ++j) { 0721 usesObject = object->uses(j.value().data()); 0722 } 0723 for (ScalarMap::Iterator j = _outputScalars.begin(); !usesObject && j != _outputScalars.end(); ++j) { 0724 usesObject = object->uses(j.value().data()); 0725 } 0726 for (StringMap::Iterator j = _outputStrings.begin(); !usesObject && j != _outputStrings.end(); ++j) { 0727 usesObject = object->uses(j.value().data()); 0728 } 0729 for (MatrixMap::Iterator j = _outputMatrices.begin(); !usesObject && j != _outputMatrices.end(); ++j) { 0730 usesObject = object->uses(j.value().data()); 0731 } 0732 } 0733 if (usesObject) { 0734 _store->removeObject(object); 0735 } 0736 } 0737 0738 RelationList relations = _store->getObjects<Relation>(); 0739 foreach (const RelationPtr &relation, relations) { 0740 bool usesRelation = relation->uses(this); 0741 if (!usesRelation) { 0742 for (VectorMap::Iterator j = _outputVectors.begin(); !usesRelation && j != _outputVectors.end(); ++j) { 0743 usesRelation = relation->uses(j.value().data()); 0744 } 0745 for (ScalarMap::Iterator j = _outputScalars.begin(); !usesRelation && j != _outputScalars.end(); ++j) { 0746 usesRelation = relation->uses(j.value().data()); 0747 } 0748 for (StringMap::Iterator j = _outputStrings.begin(); !usesRelation && j != _outputStrings.end(); ++j) { 0749 usesRelation = relation->uses(j.value().data()); 0750 } 0751 for (MatrixMap::Iterator j = _outputMatrices.begin(); !usesRelation && j != _outputMatrices.end(); ++j) { 0752 usesRelation = relation->uses(j.value().data()); 0753 } 0754 } 0755 if (usesRelation) { 0756 _store->removeObject(relation); 0757 } 0758 } 0759 0760 foreach (const VectorPtr &vector, _outputVectors) { 0761 _store->removeObject(vector); 0762 } 0763 foreach (const MatrixPtr &matrix, _outputMatrices) { 0764 _store->removeObject(matrix); 0765 } 0766 foreach (const ScalarPtr &scalar, _outputScalars) { 0767 _store->removeObject(scalar); 0768 } 0769 foreach (const StringPtr &string, _outputStrings) { 0770 _store->removeObject(string); 0771 } 0772 } 0773 0774 0775 bool DataObject::uses(ObjectPtr p) const { 0776 PrimitiveList this_input_primitives; 0777 PrimitiveList p_output_primitives; 0778 0779 this_input_primitives = inputPrimitives(); 0780 0781 PrimitivePtr p_prim = kst_cast<Primitive>(p); 0782 DataObjectPtr p_dobj = kst_cast<DataObject>(p); 0783 0784 if (p_prim) { 0785 p_output_primitives = p_prim->outputPrimitives(); 0786 p_output_primitives << p_prim; // include the object itself. 0787 } else if (p_dobj) { 0788 p_output_primitives = p_dobj->outputPrimitives(); 0789 } else { 0790 p_output_primitives.clear(); 0791 } 0792 0793 // now check if any of this's input primitives are one of p's output primitives... 0794 int n_in = this_input_primitives.count(); 0795 for (int i_in = 0; i_in<n_in; i_in++) { 0796 PrimitivePtr p_in = this_input_primitives.at(i_in); 0797 if (p_output_primitives.contains(p_in)) { 0798 return true; 0799 } 0800 } 0801 return false; 0802 } 0803 0804 qint64 DataObject::minInputSerial() const{ 0805 qint64 minSerial = LLONG_MAX; 0806 0807 foreach (const VectorPtr &P, _inputVectors) { 0808 minSerial = qMin(minSerial, P->serial()); 0809 } 0810 foreach (const ScalarPtr &P, _inputScalars) { 0811 minSerial = qMin(minSerial, P->serial()); 0812 } 0813 foreach (const MatrixPtr &P, _inputMatrices) { 0814 minSerial = qMin(minSerial, P->serial()); 0815 } 0816 foreach (const StringPtr &P, _inputStrings) { 0817 minSerial = qMin(minSerial, P->serial()); 0818 } 0819 return minSerial; 0820 } 0821 0822 qint64 DataObject::maxInputSerialOfLastChange() const { 0823 qint64 maxSerial = NoInputs; 0824 0825 foreach (const VectorPtr &P, _inputVectors) { 0826 maxSerial = qMax(maxSerial, P->serialOfLastChange()); 0827 } 0828 foreach (const ScalarPtr &P, _inputScalars) { 0829 maxSerial = qMax(maxSerial, P->serialOfLastChange()); 0830 } 0831 foreach (const MatrixPtr &P, _inputMatrices) { 0832 maxSerial = qMax(maxSerial, P->serialOfLastChange()); 0833 } 0834 foreach (const StringPtr &P, _inputStrings) { 0835 maxSerial = qMax(maxSerial, P->serialOfLastChange()); 0836 } 0837 return maxSerial; 0838 } 0839 0840 0841 ///////////////////////////////////////////////////////////////////////////// 0842 DataObjectConfigWidget::DataObjectConfigWidget(QSettings *cfg) 0843 : QWidget(0L), _cfg(cfg) { 0844 } 0845 0846 0847 DataObjectConfigWidget::~DataObjectConfigWidget() { 0848 } 0849 0850 0851 void DataObjectConfigWidget::save() { 0852 } 0853 0854 0855 void DataObjectConfigWidget::load() { 0856 } 0857 0858 0859 void DataObjectConfigWidget::setObjectStore(ObjectStore* store) { 0860 Q_UNUSED(store); 0861 } 0862 0863 0864 void DataObjectConfigWidget::setupFromObject(Object* dataObject) { 0865 Q_UNUSED(dataObject); 0866 } 0867 0868 0869 void DataObjectConfigWidget::setVectorX(VectorPtr vector) { 0870 Q_UNUSED(vector); 0871 } 0872 0873 0874 void DataObjectConfigWidget::setVectorY(VectorPtr vector) { 0875 Q_UNUSED(vector); 0876 } 0877 0878 0879 void DataObjectConfigWidget::setupSlots(QWidget* dialog) { 0880 Q_UNUSED(dialog); 0881 } 0882 0883 0884 void DataObjectConfigWidget::setVectorsLocked(bool locked) { 0885 Q_UNUSED(locked); 0886 } 0887 0888 0889 bool DataObjectConfigWidget::configurePropertiesFromXml(ObjectStore *store, QXmlStreamAttributes& attrs) { 0890 Q_UNUSED(store); 0891 Q_UNUSED(attrs); 0892 return true; 0893 } 0894 0895 QByteArray DataObject::scriptInterface(QList<QByteArray> &c) { 0896 Q_ASSERT(c.size()); 0897 if(c[0]=="outputVectorHandle") { 0898 if (c.size()==2) { 0899 QString c1 = QString(c[1]).trimmed(); 0900 if (_outputVectors.contains(c1)) { 0901 return _outputVectors[c1]->Name().toAscii(); 0902 } else { 0903 return QByteArray("vector not found: ").append(c[1]); 0904 } 0905 } else { 0906 return "outputVectorHandle takes one arg"; 0907 } 0908 } else if(c[0]=="outputScalarHandle") { 0909 if (c.size()==2) { 0910 QString c1 = QString(c[1]).trimmed(); 0911 if (_outputScalars.contains(c1)) { 0912 return _outputScalars[c1]->Name().toAscii(); 0913 } else { 0914 return QByteArray("scalar not found: ").append(c[1]); 0915 } 0916 } else { 0917 return "outputScalarHandle takes one arg"; 0918 } 0919 } else if(c[0]=="outputMatrixHandle") { 0920 if (c.size()==2) { 0921 QString c1 = QString(c[1]).trimmed(); 0922 if (_outputMatrices.contains(c1)) { 0923 return _outputMatrices[c1]->Name().toAscii(); 0924 } else { 0925 return QByteArray("Matrix not found: ").append(c[1]); 0926 } 0927 } else { 0928 return "outputMatrixHandle takes one arg"; 0929 } 0930 } else if(c[0]=="outputStringHandle") { 0931 if (c.size()==2) { 0932 QString c1 = QString(c[1]).trimmed(); 0933 if (_outputStrings.contains(c1)) { 0934 return _outputStrings[c1]->Name().toAscii(); 0935 } else { 0936 return QByteArray("String not found: ").append(c[1]); 0937 } 0938 } else { 0939 return "outputStringHandle takes one arg"; 0940 } 0941 } 0942 0943 return "No such command..."; 0944 } 0945 0946 // vim: ts=2 sw=2 et