PropertyExpressionEngine: Refactored and moved visitor code to separate file.

This commit is contained in:
Eivind Kvedalen
2016-02-08 21:01:33 +01:00
committed by wmayer
parent fa8b7bfb45
commit 452650440b
7 changed files with 197 additions and 95 deletions

View File

@@ -28,6 +28,7 @@
#include <Base/Writer.h>
#include <Base/Reader.h>
#include "Expression.h"
#include "ExpressionVisitors.h"
#include "PropertyExpressionEngine.h"
#include "PropertyStandard.h"
#include "PropertyUnits.h"
@@ -41,59 +42,6 @@ using namespace App;
using namespace Base;
using namespace boost;
typedef boost::function<void ()> aboutToSetValueFunc;
typedef boost::function<void ()> hasSetValueFunc;
/**
* @brief The RelabelDocumentObjectExpressionVisitor class is a functor class used to rename variables in an expression.
*/
class RelabelDocumentObjectExpressionVisitor : public ExpressionVisitor {
public:
RelabelDocumentObjectExpressionVisitor(aboutToSetValueFunc _aboutToSetValue, hasSetValueFunc _hasSetValue, const std::string & _oldName, const std::string & _newName)
: aboutToSetValue(_aboutToSetValue)
, hasSetValue(_hasSetValue)
, oldName(_oldName)
, newName(_newName)
, changed(0)
{
}
~RelabelDocumentObjectExpressionVisitor() {
if (changed > 0)
hasSetValue();
}
/**
* @brief Visit each node in the expression, and if it is a VariableExpression object, incoke renameDocumentObject in it.
* @param node Node to visit
*/
void visit(Expression * node) {
VariableExpression *expr = freecad_dynamic_cast<VariableExpression>(node);
if (expr) {
if (expr->renameDocumentObject(oldName, newName)) {
if (!changed) {
aboutToSetValue();
++changed;
}
}
}
}
int getChanged() const { return changed; }
private:
aboutToSetValueFunc aboutToSetValue;
hasSetValueFunc hasSetValue;
std::string oldName; /**< Document object name to replace */
std::string newName; /**< New document object name */
int changed;
};
class ObjectDeletedExpressionVisitor : public ExpressionVisitor {
public:
@@ -329,9 +277,7 @@ void PropertyExpressionEngine::slotObjectRenamed(const DocumentObject &obj)
if (!docObj || docObj->getNameInDocument() == 0)
return;
RelabelDocumentObjectExpressionVisitor v(boost::bind( &PropertyExpressionEngine::aboutToSetValue, this),
boost::bind( &PropertyExpressionEngine::hasSetValue, this),
obj.getOldLabel(), obj.Label.getStrValue());
RelabelDocumentObjectExpressionVisitor<PropertyExpressionEngine> v(*this, obj.getOldLabel(), obj.Label.getStrValue());
for (ExpressionMap::iterator it = expressions.begin(); it != expressions.end(); ++it) {
int changed = v.getChanged();
@@ -773,42 +719,6 @@ void PropertyExpressionEngine::renameExpressions(const std::map<ObjectIdentifier
hasSetValue();
}
/**
* @brief The RenameObjectIdentifierExpressionVisitor class is a functor used to visit each node of an expression, and
* possibly rename VariableExpression nodes.
*/
class RenameObjectIdentifierExpressionVisitor : public ExpressionVisitor {
public:
RenameObjectIdentifierExpressionVisitor(const std::map<ObjectIdentifier, ObjectIdentifier> &_paths, const ObjectIdentifier & _owner)
: paths(_paths)
, owner(_owner)
{
}
/**
* @brief If node is a VariableExpression object, look it up in the paths map, and possibly rename it.
* @param node Node to visit.
*/
void visit(Expression * node) {
VariableExpression *expr = freecad_dynamic_cast<VariableExpression>(node);
if (expr) {
const App::ObjectIdentifier & oldPath = expr->getPath().canonicalPath();
const std::map<ObjectIdentifier, ObjectIdentifier>::const_iterator it = paths.find(oldPath);
if (it != paths.end())
expr->setPath(it->second.relativeTo(owner));
}
}
private:
const std::map<ObjectIdentifier, ObjectIdentifier> &paths; /**< Map with current and new object identifiers */
const ObjectIdentifier & owner; /**< Owner og expression */
};
/**
* @brief Rename object identifiers in the registered expressions.
* @param paths Map with current and new object identifiers.
@@ -816,9 +726,8 @@ private:
void PropertyExpressionEngine::renameObjectIdentifiers(const std::map<ObjectIdentifier, ObjectIdentifier> &paths)
{
for (ExpressionMap::iterator it = expressions.begin(); it != expressions.end(); ++it) {
RenameObjectIdentifierExpressionVisitor v(paths, it->first);
RenameObjectIdentifierExpressionVisitor<PropertyExpressionEngine> v(*this, paths, it->first);
it->second.expression->visit(v);
}
}