| 575 | } |
| 576 | |
| 577 | void PropertyExpressionEngine::setValue(const ObjectIdentifier& path, |
| 578 | std::shared_ptr<Expression> expr) |
| 579 | { |
| 580 | ObjectIdentifier usePath(canonicalPath(path)); |
| 581 | const Property* prop = usePath.getProperty(); |
| 582 | |
| 583 | // Try to access value; it should trigger an exception if it is not supported, or if the path is |
| 584 | // invalid |
| 585 | prop->getPathValue(usePath); |
| 586 | |
| 587 | // Check if the current expression equals the new one and do nothing if so to reduce unneeded |
| 588 | // computations |
| 589 | auto it = expressions.find(usePath); |
| 590 | if (it != expressions.end() |
| 591 | && (expr == it->second.expression |
| 592 | || (expr && it->second.expression && expr->isSame(*it->second.expression)))) { |
| 593 | return; |
| 594 | } |
| 595 | |
| 596 | if (expr) { |
| 597 | std::string error = validateExpression(usePath, expr); |
| 598 | if (!error.empty()) { |
| 599 | throw Base::RuntimeError(error.c_str()); |
| 600 | } |
| 601 | AtomicPropertyChange signaller(*this); |
| 602 | expressions[usePath] = ExpressionInfo(expr); |
| 603 | expressionChanged(usePath); |
| 604 | signaller.tryInvoke(); |
| 605 | } |
| 606 | else if (it != expressions.end()) { |
| 607 | AtomicPropertyChange signaller(*this); |
| 608 | expressions.erase(it); |
| 609 | expressionChanged(usePath); |
| 610 | signaller.tryInvoke(); |
| 611 | } |
| 612 | } |
| 613 | |
| 614 | std::vector<App::ObjectIdentifier> |
| 615 | PropertyExpressionEngine::computeEvaluationOrder(ExecuteOption option) |
nothing calls this directly
no test coverage detected