[Kst] branches/work/kst/portto4/kst/src

Barth Netterfield netterfield at astro.utoronto.ca
Mon Apr 23 22:21:50 UTC 2012


SVN commit 1291312 by netterfield:

BUG: 297568
When saving data objects, sort them first so that they are not saved
before things they depend on.  This will not fix old kst files where 
the data objects are out of order, but it will prevent bad kst files
from being created in the future.


 M  +2 -0      libkst/matrix.cpp  
 M  +6 -0      libkst/primitive.h  
 M  +1 -0      libkst/scalar.cpp  
 M  +1 -0      libkst/string_kst.cpp  
 M  +2 -0      libkst/vector.cpp  
 M  +50 -1     libkstapp/document.cpp  
 M  +4 -1      libkstapp/document.h  
 M  +0 -1      libkstmath/basicpluginfactory.cpp  
 M  +22 -0     libkstmath/dataobject.cpp  
 M  +5 -0      libkstmath/dataobject.h  
 M  +1 -5      libkstmath/equation.cpp  
 M  +4 -0      plugins/filters/despike/filterdespike.cpp  


--- branches/work/kst/portto4/kst/src/libkst/matrix.cpp #1291311:1291312
@@ -47,6 +47,8 @@
   _strings.clear();
   _vectors.clear();
 
+  setFlag(true);
+
   createScalars(store);
 
 }
--- branches/work/kst/portto4/kst/src/libkst/primitive.h #1291311:1291312
@@ -57,6 +57,9 @@
 
     virtual PrimitiveMap metas() const = 0;
 
+    // used for sorting dataobjects by Document::sortedDataObjectList()
+    virtual bool flagSet() const { return _flag; }
+    virtual void setFlag(bool f) { _flag = f;}
 
   protected:
     Primitive(ObjectStore *store, Object* provider = 0L);
@@ -77,6 +80,9 @@
      * FIXME: pretty sure this is wrong: it shouldn't be a qpointer... not sure
      * what should be going on here! */
     QPointer<Object> _provider;
+
+  private:
+    bool _flag; // used for sorting dataobjects by Document::sortedDataObjectList()
 };
 
 typedef SharedPtr<Primitive> PrimitivePtr;
--- branches/work/kst/portto4/kst/src/libkst/scalar.cpp #1291311:1291312
@@ -34,6 +34,7 @@
 Scalar::Scalar(ObjectStore *store)
     : Primitive(store, 0L), _value(0.0), _orphan(false), _displayable(true), _editable(false) {
 
+  setFlag(true);
   _initializeShortName();
 }
 
--- branches/work/kst/portto4/kst/src/libkst/string_kst.cpp #1291311:1291312
@@ -32,6 +32,7 @@
     : Primitive(store, 0L), _orphan(false), _editable(false) {
 
   _value.clear();
+  setFlag(true);
   _initializeShortName();
 
 }
--- branches/work/kst/portto4/kst/src/libkst/vector.cpp #1291311:1291312
@@ -74,6 +74,8 @@
   _strings.clear();
 
   CreateScalars(store);
+  setFlag(true);
+
   blank();
 
 }
--- branches/work/kst/portto4/kst/src/libkstapp/document.cpp #1291311:1291312
@@ -56,7 +56,54 @@
   return _fileName;
 }
 
+/** return a list of data objects where all dependencies appear earlier in the list */
+ObjectList<DataObject> Document::sortedDataObjectList() {
+  ObjectList<DataObject> sorted;
+  ObjectList<DataObject> raw = objectStore()->getObjects<DataObject>();
+  sorted.clear();
 
+
+  // set the flag for all primitives: not strictly necessary
+  // since it should have been done in the constructor, but...
+  PrimitiveList all_primitives = objectStore()->getObjects<Primitive>();
+  int n = all_primitives.size();
+  for (int i=0; i<n; i++) {
+    all_primitives[i]->setFlag(true);
+  }
+
+  // now unset the flags of all output primitives to indicate their parents haven't been
+  // put in the sorted list yet
+  n = raw.size();
+  for (int i=0; i<n; i++) {
+    raw[i]->setOutputFlags(false);
+  }
+
+  // now place into the sorted list all data objects whose inputs haven't got parents
+  // or whose inputs have parents which are already in the sorted list.
+  // do this at most n^2 times, which is worse than worse case.
+  int i=0;
+  while (!raw.isEmpty() && (++i < n*n)) {
+    DataObjectPtr D = raw.takeFirst();
+    if (D->inputFlagsSet()) {
+      D->setOutputFlags(true);
+      sorted.append(D);
+    } else {
+      raw.append(D); // try again later
+    }
+  }
+
+  if (i== n*n) {
+    qDebug() << "Warning: loop detected, File will not be able to be loaded correctly!";
+    while (!raw.isEmpty()) {
+      DataObjectPtr D = raw.takeFirst();
+      sorted.append(D);
+    }
+  }
+
+  return sorted;
+}
+
+
 bool Document::save(const QString& to) {
 
   QString file = !to.isEmpty() ? to : _fileName;
@@ -105,9 +152,11 @@
   xml.writeEndElement();
 
   xml.writeStartElement("objects");
-  foreach (DataObjectPtr s, objectStore()->getObjects<DataObject>()) {
+  ObjectList<DataObject> dataObjects = sortedDataObjectList();
+  foreach (DataObjectPtr s, dataObjects) {
     s->save(xml);
   }
+  dataObjects.clear();
   xml.writeEndElement();
 
   xml.writeStartElement("relations");
--- branches/work/kst/portto4/kst/src/libkstapp/document.h #1291311:1291312
@@ -17,7 +17,7 @@
 #include <QString>
 
 #include "coredocument.h"
-
+#include "dataobject.h"
 namespace Kst {
 
 class MainWindow;
@@ -40,6 +40,9 @@
     bool open(const QString& file);
     bool save(const QString& to = QString());
 
+    ObjectList<DataObject> sortedDataObjectList();
+
+
     bool isChanged() const;
     void setChanged(bool changed);
     bool isOpen() const;
--- branches/work/kst/portto4/kst/src/libkstmath/basicpluginfactory.cpp #1291311:1291312
@@ -61,7 +61,6 @@
         }
 
         dataObject = kst_cast<BasicPlugin>(DataObject::createPlugin(pluginName, store, configWidget, false));
-
         QString expectedEnd;
         while (!(xml.isEndElement() && (xml.name().toString() == BasicPlugin::staticTypeTag))) {
           if (xml.isStartElement() && xml.name().toString() == "inputvector") {
--- branches/work/kst/portto4/kst/src/libkstmath/dataobject.cpp #1291311:1291312
@@ -174,6 +174,28 @@
 }
 
 
+// set flags on all output primitives
+// used for sorting dataobjects by Document::sortedDataObjectList()
+void DataObject::setOutputFlags(bool flag) {
+  PrimitiveList output_primitives = outputPrimitives();
+  int n = output_primitives.count();
+  for (int i=0; i<n; i++) {
+    output_primitives[i]->setFlag(flag);
+  }
+}
+
+
+bool DataObject::inputFlagsSet() const {
+  PrimitiveList input_primitives = inputPrimitives();
+  int n = input_primitives.count();
+  bool all_set = true;
+  for (int i=0; i<n; i++) {
+    all_set &= input_primitives[i]->flagSet();
+  }
+
+  return all_set;
+}
+
 // Scans for plugins and stores the information for them
 void DataObject::scanPlugins() {
   Debug::self()->log(i18n("Scanning for data-object plugins."));
--- branches/work/kst/portto4/kst/src/libkstmath/dataobject.h #1291311:1291312
@@ -129,6 +129,11 @@
 
     void showDialog(bool isNew = true);
 
+    // used for sorting dataobjects by Document::sortedDataObjectList()
+    void setOutputFlags(bool flag);
+    bool inputFlagsSet() const;
+
+
   protected slots:
     virtual void showNewDialog() = 0;
     virtual void showEditDialog() = 0;
--- branches/work/kst/portto4/kst/src/libkstmath/equation.cpp #1291311:1291312
@@ -112,7 +112,6 @@
 
 void Equation::internalUpdate() {
   Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED);
-
   if (!_pe) {
     return;
   }
@@ -127,10 +126,6 @@
 
   _isValid = FillY(true);
 
-  //  should this be updated by the update manager?
-  //_yOutVector->internalUpdate();
-  //_xOutVector->internalUpdate();
-
   unlockInputsAndOutputs();
 
   updateVectorLabels();
@@ -202,6 +197,7 @@
 void Equation::setEquation(const QString& in_fn) {
   // assert(*_xVector); - ugly, we have to allow this here due to
   // document loading with vector lazy-loading
+
   _equation = in_fn;
 
   VectorsUsed.clear();
--- branches/work/kst/portto4/kst/src/plugins/filters/despike/filterdespike.cpp #1291311:1291312
@@ -143,8 +143,12 @@
 
 
 QString FilterDespikeSource::_automaticDescriptiveName() const {
+  if (vector()) {
   return QString(vector()->descriptiveName() + " Despike");
+  } else {
+    return QString("Despike");
 }
+}
 
 
 QString FilterDespikeSource::descriptionTip() const {


More information about the Kst mailing list