Salome HOME
Fix for issue #562 : correct update by dependencies in the parameters
[modules/shaper.git] / src / ParametersPlugin / ParametersPlugin_EvalListener.cpp
1 /*
2  * ParametersPlugin_EvalListener.cpp
3  *
4  *  Created on: Apr 28, 2015
5  *      Author: sbh
6  */
7
8 #include <ParametersPlugin_EvalListener.h>
9
10 #include <Events_Error.h>
11
12 #include <ModelAPI_Events.h>
13 #include <ModelAPI_Tools.h>
14 #include <ModelAPI_AttributeDouble.h>
15
16 #include <string>
17 #include <sstream>
18
19 ParametersPlugin_EvalListener::ParametersPlugin_EvalListener()
20 {
21   Events_Loop* aLoop = Events_Loop::loop();
22   const Events_ID kEvaluationEvent = ModelAPI_AttributeEvalMessage::eventId();
23   aLoop->registerListener(this, kEvaluationEvent, NULL, true);
24
25   myInterp = std::shared_ptr<ParametersPlugin_PyInterp>(new ParametersPlugin_PyInterp());
26   myInterp->initialize();
27 }
28
29 ParametersPlugin_EvalListener::~ParametersPlugin_EvalListener()
30 {
31 }
32
33 void ParametersPlugin_EvalListener::processEvent(const std::shared_ptr<Events_Message>& theMessage)
34 {
35   if (!theMessage.get())
36     return;
37
38   const Events_ID kEvaluationEvent = ModelAPI_AttributeEvalMessage::eventId();
39   if (theMessage->eventID() == kEvaluationEvent) {
40     std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
41         std::dynamic_pointer_cast<ModelAPI_AttributeEvalMessage>(theMessage);
42     AttributeDoublePtr aDoubleAttribute =
43         std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aMessage->attribute());
44     if (aDoubleAttribute.get()) {
45       std::string anError;
46       double aValue = evaluate(aDoubleAttribute->text(), anError);
47       if (anError.empty()) {
48         aDoubleAttribute->setValue(aValue);
49         aDoubleAttribute->setExpressionInvalid(false);
50       } else { // set feature as invalid-parameter arguments
51         aDoubleAttribute->setExpressionInvalid(true);
52       }
53     }
54   } else {
55     Events_Error::send(std::string("ParametersPlugin python interpreter, unhandled message caught: ")
56                        + theMessage->eventID().eventText());
57   }
58 }
59
60 double ParametersPlugin_EvalListener::evaluate(const std::string& theExpression,
61                                                std::string& theError)
62 {
63   std::list<std::string> anExprParams = myInterp->compile(theExpression);
64   // find expression's params in the model
65   std::list<std::string> aContext;
66   std::list<std::string>::iterator it = anExprParams.begin();
67   for ( ; it != anExprParams.end(); it++) {
68     double aValue;
69     ResultParameterPtr aParamRes;
70     if (!ModelAPI_Tools::findVariable(*it, aValue, aParamRes)) continue;
71
72     std::ostringstream sstream;
73     sstream << aValue;
74     std::string aParamValue = sstream.str();
75     aContext.push_back(*it + "=" + aParamValue);
76   }
77   myInterp->extendLocalContext(aContext);
78   double result = myInterp->evaluate(theExpression, theError);
79   myInterp->clearLocalContext();
80   return result;
81 }