bool KstDataObject::duplicateDependents(QMap<KstDataObjectPtr, KstDataObjectPtr> &duplicatedMap) { // // work with a copy of the data object list // KST::dataObjectList.lock().readLock(); KstDataObjectList dol = KST::dataObjectList; KST::dataObjectList.lock().unlock(); for (KstDataObjectList::Iterator i = dol.begin(); i != dol.end(); ++i) { if ((*i)->uses(KstObjectPtr(this))) { if (duplicatedMap.contains(*i)) { (duplicatedMap[*i])->replaceDependency(KstDataObjectPtr(this), duplicatedMap.value(KstDataObjectPtr(this))); } else { KstDataObjectPtr newObject = (*i)->makeDuplicate(duplicatedMap); KST::dataObjectList.lock().writeLock(); KST::dataObjectList.append(newObject); KST::dataObjectList.lock().unlock(); (duplicatedMap[*i])->replaceDependency(KstDataObjectPtr(this), duplicatedMap.value(KstDataObjectPtr(this))); (*i)->duplicateDependents(duplicatedMap); } } } return true; }
bool KST::duplicateDependents(KstVectorPtr vectorFor, KstDataObjectDataObjectMap& duplicatedMap, QMap<KstVectorPtr, KstVectorPtr> &duplicatedVectors) { // work with a copy of the data object list KST::dataObjectList.lock().readLock(); KstDataObjectList dol = QDeepCopy<KstDataObjectList>(KST::dataObjectList); KST::dataObjectList.lock().readUnlock(); for (KstDataObjectList::Iterator i = dol.begin(); i != dol.end(); ++i) { if ((*i)->uses(vectorFor)) { if (duplicatedMap.contains(*i)) { (duplicatedMap[*i])->replaceDependency(vectorFor, duplicatedVectors[vectorFor]); } else { KstDataObjectPtr newObject = (*i)->makeDuplicate(duplicatedMap); newObject->replaceDependency(vectorFor, duplicatedVectors[vectorFor]); if (newObject) { KST::dataObjectList.lock().writeLock(); KST::dataObjectList.append(newObject.data()); KST::dataObjectList.lock().writeUnlock(); (*i)->duplicateDependents(duplicatedMap); } } } } return true; }
bool KST::deleteDependents(KstVectorPtr vectorFor) { KST::dataObjectList.lock().readLock(); KstDataObjectList dol = QDeepCopy<KstDataObjectList>(KST::dataObjectList); KST::dataObjectList.lock().readUnlock(); for (KstDataObjectList::Iterator i = dol.begin(); i != dol.end(); ++i) { bool user = (*i)->uses(vectorFor); if (user) { KstDataObjectPtr dop = *i; KST::dataObjectList.lock().writeLock(); KST::dataObjectList.remove(dop); KST::dataObjectList.lock().writeUnlock(); dop->deleteDependents(); } } return true; }
bool KstDataObject::deleteDependents() { KstDataObjectList dol; KstDataObjectList::iterator i; KST::dataObjectList.lock().readLock(); dol = KST::dataObjectList; KST::dataObjectList.lock().unlock(); for (i = dol.begin(); i != dol.end(); ++i) { bool user = (*i)->uses(KstObjectPtr(this)); if (!user) { for (KstVectorMap::Iterator j = _outputVectors.begin(); !user && j != _outputVectors.end(); ++j) { user = (*i)->uses(KstObjectPtr((*j).data())); } for (KstScalarMap::Iterator j = _outputScalars.begin(); !user && j != _outputScalars.end(); ++j) { user = (*i)->uses(KstObjectPtr((*j).data())); } for (KstStringMap::Iterator j = _outputStrings.begin(); !user && j != _outputStrings.end(); ++j) { user = (*i)->uses(KstObjectPtr((*j).data())); } } if (user) { KstDataObjectPtr dop = *i; KST::dataObjectList.lock().writeLock(); KST::dataObjectList.erase(i); KST::dataObjectList.lock().unlock(); dop->deleteDependents(); } } return true; }
bool UpdateThread::doUpdates(bool force, bool *gotData) { KstObject::UpdateType U = KstObject::NO_CHANGE; _updatedCurves.clear(); // HACK if (gotData) { *gotData = false; } #if UPDATEDEBUG > 0 if (force) { qDebug() << "Forced update!" << endl; } #endif _updateCounter++; if (_updateCounter < 1) { _updateCounter = 1; // check for wrap around } #if UPDATEDEBUG > 2 qDebug() << "UPDATE: counter=" << _updateCounter << endl; #endif { // Must make a copy to avoid deadlock KstBaseCurveList cl; KstDataObjectList dol; kstObjectSplitList<KstDataObject, KstBaseCurve>(KST::dataObjectList, cl, dol); qSort(cl); qSort(dol); // Update all curves for (uint i = 0; i < cl.count(); ++i) { KstBaseCurvePtr bcp = cl[i]; bcp->writeLock(); assert(bcp.data()); #if UPDATEDEBUG > 1 qDebug() << "updating curve: " << (void*)bcp << " - " << bcp->tagName() << endl; #endif KstObject::UpdateType ut = bcp->update(_updateCounter); bcp->unlock(); if (ut == KstObject::UPDATE) { // HACK _updatedCurves.append(bcp); } if (U != KstObject::UPDATE) { U = ut; if (U == KstObject::UPDATE) { #if UPDATEDEBUG > 0 qDebug() << "Curve " << bcp->tagName() << " said UPDATE" << endl; #endif } } if (_done || (_paused && !force)) { #if UPDATEDEBUG > 1 qDebug() << "5 Returning from scan with U=" << (int)U << endl; #endif return U == KstObject::UPDATE; } } // Update all data objects for (uint i = 0; i < dol.count(); ++i) { KstDataObjectPtr dp = dol[i]; dp->writeLock(); assert(dp.data()); #if UPDATEDEBUG > 1 qDebug() << "updating data object: " << (void*)dp << " - " << dp->tagName() << endl; #endif dp->update(_updateCounter); dp->unlock(); if (_done || (_paused && !force)) { #if UPDATEDEBUG > 1 qDebug() << "5 Returning from scan with U=" << (int)U << endl; #endif return U == KstObject::UPDATE; } } } // Update the files if (!_paused) { // don't update even if paused && force KST::dataSourceList.lock().readLock(); unsigned cnt = KST::dataSourceList.count(); for (uint i = 0; i < cnt; ++i) { KstDataSourcePtr dsp = KST::dataSourceList[i]; dsp->writeLock(); dsp->update(_updateCounter); dsp->unlock(); if (_done) { KST::dataSourceList.lock().unlock(); return false; } } KST::dataSourceList.lock().unlock(); } if (KstScalar::scalarsDirty()) { KstScalar::clearScalarsDirty(); // Must do this first and take a risk of // falling slightly behind KST::scalarList.lock().readLock(); KstScalarList sl = Q3DeepCopy<KstScalarList>(KST::scalarList.list()); // avoid deadlock on exit KST::scalarList.lock().unlock(); for (KstScalarList::ConstIterator i = sl.begin(); i != sl.end(); ++i) { KstScalarPtr sp = *i; sp->writeLock(); KstObject::UpdateType ut = sp->update(_updateCounter); sp->unlock(); if (ut == KstObject::UPDATE) { U = KstObject::UPDATE; } if (_done) { return false; } } } if (U == KstObject::UPDATE) { qDebug() << "Update plots" << endl; if (gotData) { // FIXME: do we need to consider all the other exit points? *gotData = true; } } #if UPDATEDEBUG > 1 qDebug() << "6 Returning from scan with U=" << (int)U << endl; #endif return U == KstObject::UPDATE; }