Salome HOME
Optimize and debug the updater
authormpv <mpv@opencascade.com>
Wed, 2 Sep 2015 17:14:21 +0000 (20:14 +0300)
committermpv <mpv@opencascade.com>
Wed, 2 Sep 2015 17:14:21 +0000 (20:14 +0300)
13 files changed:
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/Model/Model_Document.cpp
src/Model/Model_Objects.cpp
src/Model/Model_Update.cpp
src/Model/Model_Validator.cpp
src/ModelAPI/ModelAPI_Data.h
src/ModelAPI/ModelAPI_Feature.cpp
src/ModelAPI/ModelAPI_Feature.h
src/ModelAPI/ModelAPI_Object.h
src/ModelAPI/ModelAPI_Result.cpp
src/ModelAPI/ModelAPI_Result.h
src/XGUI/XGUI_ErrorMgr.cpp

index 45779f4c8f1a968b87627b9a2ae54e7fd892471a..b98dbf49ce710c00a4cb9078ce0a2aa5f3dd9bd5 100644 (file)
@@ -42,6 +42,7 @@
 #include <TDF_AttributeIterator.hxx>
 #include <TDF_ChildIterator.hxx>
 #include <TDF_RelocationTable.hxx>
+#include <TColStd_HArray1OfByte.hxx>
 
 #include <string>
 
@@ -53,6 +54,8 @@
 static const int kFlagInHistory = 0;
 //                             1 - is displayed or not
 static const int kFlagDisplayed = 1;
+//                             2 - is deleted (for results) or not
+static const int kFlagDeleted = 2;
 
 // invalid data
 const static std::shared_ptr<ModelAPI_Data> kInvalid(new Model_Data());
@@ -67,9 +70,16 @@ void Model_Data::setLabel(TDF_Label theLab)
   // set or get the default flags
   if (!myLab.FindAttribute(TDataStd_BooleanArray::GetID(), myFlags)) {
     // set default values if not found
-    myFlags = TDataStd_BooleanArray::Set(myLab, 0, 1);
+    myFlags = TDataStd_BooleanArray::Set(myLab, 0, 2);
     myFlags->SetValue(kFlagInHistory, Standard_True); // is in history by default is true
     myFlags->SetValue(kFlagDisplayed, Standard_True); // is displayed by default is true
+    myFlags->SetValue(kFlagDeleted, Standard_False); // is deleted by default is false
+  } else if (myFlags->Length() != 3) { // for old formats support
+    Handle(TColStd_HArray1OfByte) aNewArray = new TColStd_HArray1OfByte(0, 2);
+    aNewArray->SetValue(0, myFlags->Upper() > 0 ? myFlags->Value(0) : Standard_True); 
+    aNewArray->SetValue(1, myFlags->Upper() > 1 ? myFlags->Value(1) : Standard_True); 
+    aNewArray->SetValue(1, myFlags->Upper() > 2 ? myFlags->Value(2) : Standard_False); 
+    myFlags->SetInternalArray(aNewArray);
   }
 }
 
@@ -317,6 +327,11 @@ void Model_Data::setError(const std::string& theError, bool theSend)
   TDataStd_AsciiString::Set(myLab, theError.c_str());
 }
 
+void Model_Data::eraseErrorString()
+{
+  myLab.ForgetAttribute(TDataStd_AsciiString::GetID());
+}
+
 std::string Model_Data::error() const
 {
   Handle(TDataStd_AsciiString) anErrorAttr;
@@ -393,7 +408,7 @@ void Model_Data::updateConcealmentFlag()
   // thus, no concealment references anymore => make not-concealed
   std::shared_ptr<ModelAPI_Result> aRes = 
     std::dynamic_pointer_cast<ModelAPI_Result>(myObject);
-  if (aRes.get()) {
+  if (aRes.get() && aRes->isConcealed()) {
     aRes->setIsConcealed(false);
     static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
     ModelAPI_EventCreator::get()->sendUpdated(aRes, anEvent);
@@ -547,6 +562,16 @@ void Model_Data::setIsInHistory(const bool theFlag)
   return myFlags->SetValue(kFlagInHistory, theFlag);
 }
 
+bool Model_Data::isDeleted()
+{
+  return myFlags->Value(kFlagDeleted) == Standard_True;
+}
+
+void Model_Data::setIsDeleted(const bool theFlag)
+{
+  return myFlags->SetValue(kFlagDeleted, theFlag);
+}
+
 bool Model_Data::isDisplayed()
 {
   if (!myObject.get() || !myObject->document().get() || // object is in valid
index f1d5c59e85d07be60543fa2d2341d11c59da4b3d..1e6c0d65082a4df12d4f9b7c7e61c9b78feed426 100644 (file)
@@ -170,6 +170,9 @@ class Model_Data : public ModelAPI_Data
   /// Registers error during the execution, causes the ExecutionFailed state
   MODEL_EXPORT virtual void setError(const std::string& theError, bool theSend = true);
 
+  /// Erases the error string if it is not empty
+  void eraseErrorString();
+
   /// Registers error during the execution, causes the ExecutionFailed state
   MODEL_EXPORT virtual std::string error() const;
 
@@ -211,6 +214,12 @@ protected:
   /// Defines the custom "is in history" behavior
   MODEL_EXPORT virtual void setIsInHistory(const bool theFlag);
 
+  /// Returns true if the object is deleted, but some data is still keept in memory
+  MODEL_EXPORT virtual bool isDeleted();
+
+  /// Sets true if the object is deleted, but some data is still keept in memory
+  MODEL_EXPORT virtual void setIsDeleted(const bool theFlag);
+
 private:
   /// Removes all information about back references
   void eraseBackReferences();
index fe3d061bbeb119961ce427e006e34288a26338a9..668999dd8e4fc51284839be8dd5322c3df5bb82b 100644 (file)
@@ -512,7 +512,7 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron
       subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize);
     }
   }
-  // after redo of all sub-documents to avoid updates on not-modified data (issue 370)
+  // after undo of all sub-documents to avoid updates on not-modified data (issue 370)
   if (theSynchronize) {
     myObjs->synchronizeFeatures(aDeltaLabels, true, isRoot());
     // update the current features status
index 71f28a123d01ec6dfdb7bf9e01d58f71b17d32a4..e638e7e411dde3a02789cad6f6aaeb3006b97137 100644 (file)
@@ -475,9 +475,10 @@ void Model_Objects::allResults(const std::string& theGroupID, std::list<ResultPt
         for (; aRIter != aResults.cend(); aRIter++) {
           ResultPtr aRes = *aRIter;
           if (aRes->groupName() != theGroupID) break; // feature have only same group results
-          if (aRes->isInHistory() && !aRes->isConcealed()) {
+          // iterate also concealed: ALL RESULTS (for translation parts undo/redo management)
+          //if (aRes->isInHistory() && !aRes->isConcealed()) {
             theResults.push_back(*aRIter);
-          }
+          //}
         }
       }
     }
@@ -931,7 +932,8 @@ void Model_Objects::updateResults(FeaturePtr theFeature)
   while(aResIter != theFeature->results().cend()) {
     ResultPtr aBody = std::dynamic_pointer_cast<ModelAPI_Result>(*aResIter);
     if (aBody.get()) {
-      if (!aBody->data()->isValid()) { 
+      std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(aBody->data());
+      if (!aData.get() || !aData->isValid() || aData->isDeleted()) { 
         // found a disappeared result => remove it
         theFeature->eraseResultFromList(aBody);
         // start iterate from beginning because iterator is corrupted by removing
@@ -977,7 +979,7 @@ void Model_Objects::updateResults(FeaturePtr theFeature)
             TCollection_AsciiString(aGroup->Get()).ToCString());
         }
       }
-      if (aNewBody) {
+      if (aNewBody && !aNewBody->data()->isDeleted()) {
         theFeature->setResult(aNewBody, aResIndex);
       }
     }
index 0abbf501441d9effabc1e14051668558073e8cfd..097673efc2f67b9a6613383d69d7a2331db6bdd2 100644 (file)
@@ -102,24 +102,30 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
       if ((*anObjIter)->groupName() == ModelAPI_ResultParameter::group()) {
         myIsParamUpdated = true;
       }
-      // created objects are always must be up to date (python box feature)
-      // and updated not in internal uptation chain
-      myUpdated[*anObjIter] = myModification;
-
-      // something is updated during the execution: re-execute it (sketch update by parameters or
-      // Box macro that updates the upper features during the execution)
-      if (myIsExecuted) { 
-        FeaturePtr anUpdated = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIter);
-        if (anUpdated.get() &&  anUpdated->data()->isValid())
-          iterateUpdateBreak(anUpdated);
-      }
-      #ifdef DEB_UPDATE
-      if (myIsExecuted) std::cout<<"During execution ";
-      if ((*anObjIter)->data() && (*anObjIter)->data()->isValid()) {
-        std::cout<<"add updated "<<(*anObjIter)->groupName()<<" "
-          <<(*anObjIter)->data()->name()<<std::endl;
+      // on undo/redo, abort do not update persisten features
+      FeaturePtr anUpdated = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIter);
+      if (std::dynamic_pointer_cast<Model_Document>((*anObjIter)->document())->executeFeatures() ||
+          (anUpdated.get() && !anUpdated->isPersistentResult())) {
+        // created objects are always must be up to date (python box feature)
+        // and updated not in internal uptation chain
+        myUpdated[*anObjIter] = myModification;
+
+        // something is updated during the execution: re-execute it (sketch update by parameters or
+        // Box macro that updates the upper features during the execution)
+        if (myIsExecuted) { 
+          FeaturePtr anUpdated = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIter);
+          if (anUpdated.get() &&  anUpdated->data()->isValid())
+            iterateUpdateBreak(anUpdated);
+        }
+#ifdef DEB_UPDATE
+        if (myIsExecuted) std::cout<<"During execution ";
+        if ((*anObjIter)->data() && (*anObjIter)->data()->isValid()) {
+          std::cout<<"add updated "<<(*anObjIter)->groupName()<<" "
+            <<(*anObjIter)->data()->name()<<std::endl;
+        }
+#endif
       }
-      #endif
+
     }
     // this event is for solver update, not here, do not react immediately
     if (!isOnlyResults && !(theMessage->eventID() == kMovedEvent))
@@ -273,7 +279,9 @@ void Model_Update::updateFeature(FeaturePtr theFeature)
   CompositeFeaturePtr aCompos = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
   // If automatice update is not needed and feature attributes were not updated right now,
   // do not execute it and do not update arguments.
-  if (!myIsAutomatic && myUpdated.find(theFeature) == myUpdated.end() && !aCompos.get()) {
+  if (!myIsAutomatic && 
+       (myUpdated.find(theFeature) == myUpdated.end() || myUpdated[theFeature] != myModification)
+       && !aCompos.get()) {
     // execute will be performed later, but some features may have not-result 
     // presentations, so call update for them (like coincidence in the sketcher)
     static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
@@ -300,7 +308,8 @@ void Model_Update::updateFeature(FeaturePtr theFeature)
     return;
   }
 
-  bool aJustUpdated = myUpdated.find(theFeature) != myUpdated.end();
+  // only the currently updated features are executed
+  bool aJustUpdated = myUpdated.find(theFeature) != myUpdated.end() && myUpdated[theFeature] == myModification;
 
   if (myIsAutomatic && theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
     aJustUpdated = true;
@@ -322,6 +331,10 @@ void Model_Update::updateFeature(FeaturePtr theFeature)
       if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) { // it is done (in the tree)
         theFeature->data()->execState(ModelAPI_StateDone);
       }
+      // it will be not updated with new modifications: only the currently updated features are updated
+      //if (myUpdated.find(theFeature) != myUpdated.end()) {
+      //  myUpdated.erase(theFeature); // do not update this persistent feature even in the future
+      //}
     }
     return;
   }
index 621f33b5f0eabbffa6b82383b7c583de04a6f1eb..9f186a1a0d13db1248c4d1cc02c8778740599a25 100644 (file)
@@ -12,8 +12,8 @@
 #include <ModelAPI_Attribute.h>
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_AttributeValidator.h>
-#include <ModelAPI_Data.h>
 #include <ModelAPI_Feature.h>
+#include <Model_Data.h>
 
 #include <Events_Error.h>
 
@@ -150,9 +150,13 @@ void Model_ValidatorsFactory::addDefaultAttributeValidators(Validators& theValid
 
 bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>& theFeature) const
 {
-  ModelAPI_ExecState anExecState = theFeature->data()->execState();
-  theFeature->setError("", false);
-  theFeature->data()->execState(anExecState);
+  std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theFeature->data());
+  if (aData.get() && aData->isValid()) {
+    if (aData->execState() == ModelAPI_StateDone)
+      aData->eraseErrorString(); // no error => erase the information string
+  } else {
+    return false; // feature is broken, already not presented in the data structure
+  }
 
   // check feature validators first
   Validators aValidators;
@@ -204,7 +208,6 @@ bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>&
   //}
   
   // check all attributes for validity
-  std::shared_ptr<ModelAPI_Data> aData = theFeature->data();
   // Validity of data is checked by "Model_FeatureValidator" (kDefaultId)
   // if (!aData || !aData->isValid())
   //   return false;
index 1d37ad60f5f88f1494c927a9e66ff84408da4e13..c9599820691e0201db1026df0264f2ce84a535ea 100644 (file)
@@ -161,6 +161,12 @@ class MODELAPI_EXPORT ModelAPI_Data
   /// Returns the owner of htis data
   virtual std::shared_ptr<ModelAPI_Object> owner() = 0;
 
+  /// Returns true if the object is deleted, but some data is still keept in memory
+  virtual bool isDeleted() = 0;
+
+  /// Sets true if the object is deleted, but some data is still keept in memory
+  virtual void setIsDeleted(const bool theFlag) = 0;
+
  protected:
   /// Objects are created for features automatically
   ModelAPI_Data();
index 11431a82ca785772950256a647ceac9ec1193aee..84fe978475d087f4d62f74d8567caad94a040176 100644 (file)
@@ -194,7 +194,7 @@ bool ModelAPI_Feature::setDisabled(const bool theFlag)
   return false;
 }
 
-bool ModelAPI_Feature::isDisabled() const
+bool ModelAPI_Feature::isDisabled()
 {
   return myIsDisabled;
 }
index 85ce31df224b59c55cd7a3937733da8e92fe8011..aed22e183c7df08f3ace228016203629588fd89b 100644 (file)
@@ -124,7 +124,7 @@ class ModelAPI_Feature : public ModelAPI_Object
   MODELAPI_EXPORT virtual bool setDisabled(const bool theFlag);
 
   /// Returns the feature is disabled or not.
-  MODELAPI_EXPORT virtual bool isDisabled() const;
+  MODELAPI_EXPORT virtual bool isDisabled();
 
   /// To virtually destroy the fields of successors
   MODELAPI_EXPORT virtual ~ModelAPI_Feature();
index 07776479cf194c85bbae1d5bd82807fab11315b1..591c75c002031a244002802ce32468da1d894be1 100644 (file)
@@ -55,7 +55,7 @@ class ModelAPI_Object: public ModelAPI_Entity
   virtual void initAttributes() = 0;
 
   /// Returns the feature is disabled or not.
-  virtual bool isDisabled() const = 0;
+  virtual bool isDisabled() = 0;
 
   /// Called on change of any argument-attribute of this object
   /// \param theID identifier of changed attribute
index 25b97c3a92a98c778a660327c3099fac00e11e78..8f0b43c5ecdbefe6c8bc711ae62099507db9f5dc 100644 (file)
@@ -18,6 +18,7 @@ bool ModelAPI_Result::setDisabled(std::shared_ptr<ModelAPI_Result> theThis, cons
 {
   if (myIsDisabled != theFlag) {
     myIsDisabled = theFlag;
+    data()->setIsDeleted(theFlag); // store it in data model (t oget back on undo/redo, etc)
     // this must be before "updated" message send to have history updated for OB update
     document()->updateHistory(groupName()); // to update the history cash data in the document
     // generate related events
@@ -36,8 +37,11 @@ bool ModelAPI_Result::setDisabled(std::shared_ptr<ModelAPI_Result> theThis, cons
   return false;
 }
 
-bool ModelAPI_Result::isDisabled() const
+bool ModelAPI_Result::isDisabled()
 {
+  if (myIsDisabled != data()->isDeleted())
+    setDisabled(std::dynamic_pointer_cast<ModelAPI_Result>(
+      data()->owner()), data()->isDeleted()); // restore from the data model the correct value
   return myIsDisabled;
 }
 
index 5508f4273dcad6e826316f1329e9b9d99e09ab07..d71e5c3854199664ff3ff41deb5de824aaf18237 100644 (file)
@@ -50,7 +50,7 @@ class ModelAPI_Result : public ModelAPI_Object
     const bool theFlag);
 
   /// Returns the result is disabled or not.
-  MODELAPI_EXPORT virtual bool isDisabled() const;
+  MODELAPI_EXPORT virtual bool isDisabled();
 
   // Returns the parameters of color definition in the resources config manager
   virtual void colorConfigInfo(std::string& theSection, std::string& theName,
index 500452a44d0ebdb8921d756ec7210cb497bffd95..7a7a86c202872fd938a8d5554ea793b1f7ed7167 100644 (file)
@@ -38,7 +38,7 @@ const char* toString(ModelAPI_ExecState theExecState)
   TO_STRING(ModelAPI_StateExecFailed)
   TO_STRING(ModelAPI_StateInvalidArgument)
   TO_STRING(ModelAPI_StateNothing)
-  default: "Unknown ExecState.";
+  default: return "Unknown ExecState.";
   }
 #undef TO_STRING
 }