1 // File: Model_Update.cxx
2 // Created: 25 Jun 2014
3 // Author: Mikhail PONIKAROV
5 #include <Model_Update.h>
6 #include <ModelAPI_Feature.h>
7 #include <ModelAPI_Data.h>
8 #include <ModelAPI_Document.h>
9 #include <Model_Events.h>
10 #include <ModelAPI_AttributeReference.h>
11 #include <ModelAPI_AttributeRefList.h>
15 Model_Update MY_INSTANCE; /// the only one instance initialized on load of the library
17 Model_Update::Model_Update()
19 Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
22 void Model_Update::processEvent(const Events_Message* theMessage)
24 const Model_FeatureUpdatedMessage* aMsg =
25 dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
26 myInitial = aMsg->features();
27 // collect all documents involved into the update
28 set<boost::shared_ptr<ModelAPI_Document> > aDocs;
29 set<boost::shared_ptr<ModelAPI_Feature> >::iterator aFIter = myInitial.begin();
30 for(; aFIter != myInitial.end(); aFIter++) {
31 aDocs.insert((*aFIter)->document());
33 // iterate all features of features-documents to update them
34 set<boost::shared_ptr<ModelAPI_Document> >::iterator aDIter = aDocs.begin();
35 for(; aDIter != aDocs.end(); aDIter++) {
36 int aNbFeatures = (*aDIter)->size(FEATURES_GROUP);
37 for(int aFIndex = 0; aFIndex < aNbFeatures; aFIndex++) {
38 boost::shared_ptr<ModelAPI_Feature> aFeature = (*aDIter)->feature(FEATURES_GROUP, aFIndex);
40 updateFeature(aFeature);
46 bool Model_Update::updateFeature(boost::shared_ptr<ModelAPI_Feature> theFeature)
48 // check it is already processed
49 if (myUpdated.find(theFeature) != myUpdated.end())
50 return myUpdated[theFeature];
51 // check all features this feature depended on (recursive call of updateFeature)
52 bool aMustbeUpdated = myInitial.find(theFeature) != myInitial.end();
54 list<boost::shared_ptr<ModelAPI_Attribute> > aRefs =
55 theFeature->data()->attributes(ModelAPI_AttributeReference::type());
56 list<boost::shared_ptr<ModelAPI_Attribute> >::iterator aRefsIter = aRefs.begin();
57 for(; aRefsIter != aRefs.end(); aRefsIter++) {
58 boost::shared_ptr<ModelAPI_Feature> aSub =
59 boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(*aRefsIter)->value();
60 if (aSub && aSub != theFeature && updateFeature(aSub))
61 aMustbeUpdated = true;
63 // lists of references
64 aRefs = theFeature->data()->attributes(ModelAPI_AttributeRefList::type());
65 for(aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
66 list<FeaturePtr> aListRef =
67 boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*aRefsIter)->list();
68 list<FeaturePtr>::iterator aListIter = aListRef.begin();
69 for(; aListIter != aListRef.end(); aListIter++) {
70 boost::shared_ptr<ModelAPI_Feature> aSub = *aListIter;
71 if (aSub && updateFeature(aSub))
72 aMustbeUpdated = true;
75 // execute feature if it must be updated
76 bool anExecute = aMustbeUpdated || myInitial.find(theFeature) != myInitial.end();
78 theFeature->execute();
80 myUpdated[theFeature] = anExecute;