File indexing completed on 2024-12-22 04:17:23
0001 /*************************************************************************** 0002 * * 0003 * copyright : (C) 2007 The University of Toronto * 0004 * netterfield@astro.utoronto.ca * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 ***************************************************************************/ 0012 0013 #include "updatemanager.h" 0014 0015 #include "primitive.h" 0016 #include "datasource.h" 0017 #include "objectstore.h" 0018 #include "measuretime.h" 0019 #include <QCoreApplication> 0020 #include <QTimer> 0021 #include <QDebug> 0022 0023 #define DEFAULT_MIN_UPDATE_PERIOD 2000 0024 0025 namespace Kst { 0026 0027 static UpdateManager *_self = 0; 0028 void UpdateManager::cleanup() { 0029 delete _self; 0030 _self = 0; 0031 } 0032 0033 0034 UpdateManager *UpdateManager::self() { 0035 if (!_self) { 0036 _self = new UpdateManager; 0037 qAddPostRoutine(cleanup); 0038 } 0039 return _self; 0040 } 0041 0042 0043 UpdateManager::UpdateManager() { 0044 _serial = 0; 0045 _minUpdatePeriod = DEFAULT_MIN_UPDATE_PERIOD; 0046 _paused = false; 0047 _store = 0; 0048 _delayedUpdateScheduled = false; 0049 _updateInProgress = false; 0050 _time.start(); 0051 } 0052 0053 0054 UpdateManager::~UpdateManager() { 0055 } 0056 0057 void UpdateManager::delayedUpdates() { 0058 _delayedUpdateScheduled = false; 0059 doUpdates(); 0060 } 0061 0062 void UpdateManager::doUpdates(bool forceImmediate) { 0063 if (_delayedUpdateScheduled && !forceImmediate) { 0064 return; 0065 } 0066 0067 if (!_store) { 0068 return; 0069 } 0070 0071 //FIXME: should we just skip updating data sources in this case? 0072 if (_paused && !forceImmediate) { 0073 return; 0074 } 0075 0076 int dT = _time.elapsed(); 0077 if (((dT<_minUpdatePeriod) || (_updateInProgress)) && (!forceImmediate)) { 0078 if (!_delayedUpdateScheduled) { 0079 _delayedUpdateScheduled = true; 0080 int deferTime = _minUpdatePeriod-dT; 0081 if (deferTime <= 0) { 0082 deferTime = 20; // if an update is already in progress, wait this long to check again. 0083 } 0084 QTimer::singleShot(deferTime, this, SLOT(delayedUpdates())); 0085 } 0086 return; 0087 } 0088 _updateInProgress = true; 0089 _time.restart(); 0090 0091 _serial++; 0092 0093 int n_updated=0, n_deferred=0, n_unchanged = 0; 0094 qint64 retval; 0095 0096 // update the datasources 0097 foreach (DataSourcePtr ds, _store->dataSourceList()) { 0098 ds->writeLock(); 0099 retval = ds->objectUpdate(_serial); 0100 ds->unlock(); 0101 if (retval == Object::Updated) n_updated++; 0102 else if (retval == Object::Deferred) n_deferred++; 0103 else if (retval == Object::NoChange) n_unchanged++; 0104 } 0105 0106 //MeasureTime t(" UpdateManager::doUpdates loop"); 0107 0108 int i_loop = retval = 0; 0109 int maxloop = _store->objectList().size(); 0110 do { 0111 n_updated = n_unchanged = n_deferred = 0; 0112 // update data objects 0113 foreach (ObjectPtr p, _store->objectList()) { 0114 p->writeLock(); 0115 retval = p->objectUpdate(_serial); 0116 p->unlock(); 0117 0118 if (retval == Object::Updated) n_updated++; 0119 else if (retval == Object::Deferred) n_deferred++; 0120 else if (retval == Object::NoChange) n_unchanged++; 0121 } 0122 maxloop = qMin(maxloop,n_deferred); 0123 i_loop++; 0124 } while ((n_deferred + n_updated > 0) && (i_loop<=maxloop)); 0125 0126 if (forceImmediate) { 0127 foreach(DataSourcePtr ds, _store->dataSourceList()) { 0128 ds->vector().readingDone(); 0129 } 0130 } 0131 0132 emit objectsUpdated(_serial); 0133 } 0134 } 0135 0136 // vim: ts=2 sw=2 et