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 <ModelAPI_Events.h>
10 #include <ModelAPI_AttributeReference.h>
11 #include <ModelAPI_AttributeRefList.h>
12 #include <Events_Loop.h>
16 Model_Update MY_INSTANCE; /// the only one instance initialized on load of the library
18 Model_Update::Model_Update()
20 Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
23 void Model_Update::processEvent(const Events_Message* theMessage)
25 const ModelAPI_ObjectUpdatedMessage* aMsg =
26 dynamic_cast<const ModelAPI_ObjectUpdatedMessage*>(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_Object> >::iterator aFIter = myInitial.begin();
31 for(; aFIter != myInitial.end(); aFIter++) {
32 aDocs.insert((*aFIter)->document());
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_Feature::group());
38 for(int aFIndex = 0; aFIndex < aNbFeatures; aFIndex++) {
39 boost::shared_ptr<ModelAPI_Feature> aFeature =
40 boost::dynamic_pointer_cast<ModelAPI_Feature>((*aDIter)->object(ModelAPI_Feature::group(), aFIndex));
42 updateFeature(aFeature);
47 static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
48 Events_Loop::loop()->flush(EVENT_DISP);
51 bool Model_Update::updateFeature(boost::shared_ptr<ModelAPI_Feature> theFeature)
53 // check it is already processed
54 if (myUpdated.find(theFeature) != myUpdated.end())
55 return myUpdated[theFeature];
56 // check all features this feature depended on (recursive call of updateFeature)
57 bool aMustbeUpdated = myInitial.find(theFeature) != myInitial.end();
59 list<boost::shared_ptr<ModelAPI_Attribute> > aRefs =
60 theFeature->data()->attributes(ModelAPI_AttributeReference::type());
61 list<boost::shared_ptr<ModelAPI_Attribute> >::iterator aRefsIter = aRefs.begin();
62 for(; aRefsIter != aRefs.end(); aRefsIter++) {
63 boost::shared_ptr<ModelAPI_Feature> aSub =
64 boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(*aRefsIter)->value();
65 if (aSub && aSub != theFeature && updateFeature(aSub))
66 aMustbeUpdated = true;
68 // lists of references
69 aRefs = theFeature->data()->attributes(ModelAPI_AttributeRefList::type());
70 for(aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
71 list<FeaturePtr> aListRef =
72 boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*aRefsIter)->list();
73 list<FeaturePtr>::iterator aListIter = aListRef.begin();
74 for(; aListIter != aListRef.end(); aListIter++) {
75 boost::shared_ptr<ModelAPI_Feature> aSub = *aListIter;
76 if (aSub && updateFeature(aSub))
77 aMustbeUpdated = true;
80 // execute feature if it must be updated
81 bool anExecute = aMustbeUpdated || myInitial.find(theFeature) != myInitial.end();
83 theFeature->execute();
84 static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
85 ModelAPI_EventCreator::get()->sendUpdated(theFeature, EVENT_DISP);
87 myUpdated[theFeature] = anExecute;