- // check all features this feature depended on (recursive call of updateFeature)
- static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
-
- if (theFeature->isDisabled() || // nothing to do with disabled feature
- theFeature->data()->execState() == ModelAPI_StateInvalidArgument)
- return;
- bool aJustUpdated = false;
-
- if (theFeature) {
- if (myIsAutomatic && theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
- aJustUpdated = true;
-
- ModelAPI_ExecState aState = ModelAPI_StateDone;
-
- // check all references: if referenced objects are updated, this object also must be updated
- // also check state of referenced objects: if they are not ready, inherit corresponding state
- std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
- std::shared_ptr<Model_Data> aData =
- std::dynamic_pointer_cast<Model_Data>(theFeature->data());
- aData->referencesToObjects(aRefs);
- std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRef = aRefs.begin();
- for(; aRef != aRefs.end(); aRef++) {
- std::list<ObjectPtr>::iterator aRefObj = aRef->second.begin();
- for(; aRefObj != aRef->second.end(); aRefObj++) {
- if (myJustCreated.find(*aRefObj) != myJustCreated.end() ||
- myJustUpdated.find(*aRefObj) != myJustUpdated.end()) {
- aJustUpdated = true;
- }
- aState = stateByReference(*aRefObj, aState);
- }
- }
-
- // some arguments were changed, so, this feature must be updated
- if (myJustCreated.find(theFeature) != myJustCreated.end()) {
- aJustUpdated = true;
- } else {
- if (aJustUpdated) {
- if (myJustUpdated.find(theFeature) == myJustUpdated.end())
- myJustUpdated.insert(theFeature);
- } else {
- aJustUpdated = myJustUpdated.find(theFeature) != myJustUpdated.end();
- }
- }
- //std::cout<<"Update feature "<<theFeature->getKind()<<" must be updated = "<<aMustbeUpdated<<std::endl;
- // execute feature if it must be updated
- if (aJustUpdated) {
- if (theFeature->isPreviewNeeded()) {
- if (std::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures() ||
- !theFeature->isPersistentResult()) {
- if (aFactory->validate(theFeature)) {
- if (myIsAutomatic || !theFeature->isPersistentResult() /* execute quick, not persistent results */
- || (isUpdated(theFeature) &&
- (theFeature == theFeature->document()->currentFeature(false) ||
- theFeature->document()->currentFeature(false)->isMacro()))) // currently edited
- {
- if (aState == ModelAPI_StateDone || aState == ModelAPI_StateMustBeUpdated) {
- executeFeature(theFeature);
- }
- } else { // must be updatet, but not updated yet
- theFeature->data()->execState(ModelAPI_StateMustBeUpdated);
- const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
- for (; aRIter != aResults.cend(); aRIter++) {
- std::shared_ptr<ModelAPI_Result> aRes = *aRIter;
- aRes->data()->execState(ModelAPI_StateMustBeUpdated);
- }
- }
- } else {
- theFeature->eraseResults();
- redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
- }
- } else { // for automatically updated features (on abort, etc) it is necessary to redisplay anyway
- redisplayWithResults(theFeature, ModelAPI_StateNothing);
- }
- } else { // preview is not needed => make state Done
- if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
- theFeature->data()->execState(ModelAPI_StateDone);
- }
- }