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 <ModelAPI_Result.h>
13 #include <Events_Loop.h>
17 Model_Update MY_INSTANCE; /// the only one instance initialized on load of the library
19 Model_Update::Model_Update()
21 Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
24 void Model_Update::processEvent(const Events_Message* theMessage)
26 const ModelAPI_ObjectUpdatedMessage* aMsg =
27 dynamic_cast<const ModelAPI_ObjectUpdatedMessage*>(theMessage);
28 myInitial = aMsg->objects();
29 // collect all documents involved into the update
30 set<boost::shared_ptr<ModelAPI_Document> > aDocs;
31 set<boost::shared_ptr<ModelAPI_Object> >::iterator aFIter = myInitial.begin();
32 for(; aFIter != myInitial.end(); aFIter++) {
33 aDocs.insert((*aFIter)->document());
35 // iterate all features of features-documents to update them
36 set<boost::shared_ptr<ModelAPI_Document> >::iterator aDIter = aDocs.begin();
37 for(; aDIter != aDocs.end(); aDIter++) {
38 int aNbFeatures = (*aDIter)->size(ModelAPI_Feature::group());
39 for(int aFIndex = 0; aFIndex < aNbFeatures; aFIndex++) {
40 boost::shared_ptr<ModelAPI_Object> aFeature = boost::dynamic_pointer_cast<ModelAPI_Object>
41 ((*aDIter)->object(ModelAPI_Feature::group(), aFIndex));
43 updateObject(aFeature);
48 static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
49 Events_Loop::loop()->flush(EVENT_DISP);
52 bool Model_Update::updateObject(boost::shared_ptr<ModelAPI_Object> theObject)
54 // check it is already processed
55 if (myUpdated.find(theObject) != myUpdated.end())
56 return myUpdated[theObject];
57 // check all features this feature depended on (recursive call of updateFeature)
58 bool anExecute = myInitial.find(theObject) != myInitial.end();
59 bool aMustbeUpdated = myInitial.find(theObject) != myInitial.end();
60 FeaturePtr aRealFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
61 if (aRealFeature) { // only real feature contains references to other objects
63 list<boost::shared_ptr<ModelAPI_Attribute> > aRefs =
64 theObject->data()->attributes(ModelAPI_AttributeReference::type());
65 list<boost::shared_ptr<ModelAPI_Attribute> >::iterator aRefsIter = aRefs.begin();
66 for(; aRefsIter != aRefs.end(); aRefsIter++) {
67 boost::shared_ptr<ModelAPI_Object> aSub =
68 boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(*aRefsIter)->value();
69 if (aSub && aSub != theObject && updateObject(aSub))
70 aMustbeUpdated = true;
72 // lists of references
73 aRefs = theObject->data()->attributes(ModelAPI_AttributeRefList::type());
74 for(aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
75 list<ObjectPtr> aListRef =
76 boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*aRefsIter)->list();
77 list<ObjectPtr>::iterator aListIter = aListRef.begin();
78 for(; aListIter != aListRef.end(); aListIter++) {
79 boost::shared_ptr<ModelAPI_Object> aSub = *aListIter;
80 if (aSub && updateObject(aSub))
81 aMustbeUpdated = true;
84 // execute feature if it must be updated
85 anExecute = aMustbeUpdated || anExecute;
87 aRealFeature->execute();
88 // redisplay all results
89 static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
90 const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aRealFeature->results();
91 std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
92 for(; aRIter != aResults.cend(); aRIter++) {
93 boost::shared_ptr<ModelAPI_Result> aRes = *aRIter;
94 ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP);
98 myUpdated[theObject] = anExecute;