Salome HOME
2db098aea0193d9af8a0fef4dda8c50478eb6f1f
[modules/shaper.git] / src / Model / Model_Update.cpp
1 // File:        Model_Update.cxx
2 // Created:     25 Jun 2014
3 // Author:      Mikhail PONIKAROV
4
5 #include <Model_Update.h>
6 #include <ModelAPI_Feature.h>
7 #include <ModelAPI_Data.h>
8 #include <ModelAPI_Document.h>
9 #include <ModelAPI_Events.h>
10 #include <ModelAPI_AttributeReference.h>
11 #include <ModelAPI_AttributeRefList.h>
12 #include <Events_Loop.h>
13
14 using namespace std;
15
16 Model_Update MY_INSTANCE; /// the only one instance initialized on load of the library
17
18 Model_Update::Model_Update()
19 {
20   Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
21 }
22
23 void Model_Update::processEvent(const Events_Message* theMessage)
24 {
25   const ModelAPI_FeatureUpdatedMessage* aMsg = 
26     dynamic_cast<const ModelAPI_FeatureUpdatedMessage*>(theMessage);
27   myInitial = aMsg->features();
28   // collect all documents involved into the update
29   set<boost::shared_ptr<ModelAPI_Document> > aDocs;
30   set<boost::shared_ptr<ModelAPI_Feature> >::iterator aFIter = myInitial.begin();
31   for(; aFIter != myInitial.end(); aFIter++) {
32     aDocs.insert((*aFIter)->document());
33   }
34   // iterate all features of features-documents to update them
35   set<boost::shared_ptr<ModelAPI_Document> >::iterator aDIter = aDocs.begin();
36   for(; aDIter != aDocs.end(); aDIter++) {
37     int aNbFeatures = (*aDIter)->size(ModelAPI_Document::FEATURES_GROUP());
38     for(int aFIndex = 0; aFIndex < aNbFeatures; aFIndex++) {
39       boost::shared_ptr<ModelAPI_Feature> aFeature = (*aDIter)->feature(ModelAPI_Document::FEATURES_GROUP(), aFIndex);
40       if (aFeature)
41         updateFeature(aFeature);
42     }
43   }
44   myUpdated.clear();
45   // flush
46   static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_FEATURE_TO_REDISPLAY);
47   Events_Loop::loop()->flush(EVENT_DISP);
48 }
49
50 bool Model_Update::updateFeature(boost::shared_ptr<ModelAPI_Feature> theFeature)
51 {
52   // check it is already processed
53   if (myUpdated.find(theFeature) != myUpdated.end())
54     return myUpdated[theFeature];
55   // check all features this feature depended on (recursive call of updateFeature)
56   bool aMustbeUpdated = myInitial.find(theFeature) != myInitial.end();
57   // references
58   list<boost::shared_ptr<ModelAPI_Attribute> > aRefs = 
59     theFeature->data()->attributes(ModelAPI_AttributeReference::type());
60   list<boost::shared_ptr<ModelAPI_Attribute> >::iterator aRefsIter = aRefs.begin();
61   for(; aRefsIter != aRefs.end(); aRefsIter++) {
62     boost::shared_ptr<ModelAPI_Feature> aSub =
63       boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(*aRefsIter)->value();
64     if (aSub && aSub != theFeature && updateFeature(aSub))
65       aMustbeUpdated = true;
66   }
67   // lists of references
68   aRefs = theFeature->data()->attributes(ModelAPI_AttributeRefList::type());
69   for(aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
70     list<FeaturePtr> aListRef = 
71       boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*aRefsIter)->list();
72     list<FeaturePtr>::iterator aListIter = aListRef.begin();
73     for(; aListIter != aListRef.end(); aListIter++) {
74       boost::shared_ptr<ModelAPI_Feature> aSub = *aListIter;
75       if (aSub && updateFeature(aSub))
76         aMustbeUpdated = true;
77     }
78   }
79   // execute feature if it must be updated
80   bool anExecute = aMustbeUpdated || myInitial.find(theFeature) != myInitial.end();
81   if (anExecute) {
82     theFeature->execute();
83     static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_FEATURE_TO_REDISPLAY);
84     ModelAPI_EventCreator::get()->sendUpdated(theFeature, EVENT_DISP);
85   }
86   myUpdated[theFeature] = anExecute;
87   return anExecute;
88 }