/*************************************************************************** * Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #ifndef EXPRESSION_H #define EXPRESSION_H #include #include #include #include #include #include #include #include #include #include #include #if defined(__clang__) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Woverloaded-virtual" #endif namespace App { class DocumentObject; class Expression; class Document; typedef std::unique_ptr ExpressionPtr; AppExport bool isAnyEqual(const App::any &v1, const App::any &v2); AppExport Base::Quantity anyToQuantity(const App::any &value, const char *errmsg = 0); typedef std::map > > ExpressionDeps; class AppExport ExpressionVisitor { public: virtual ~ExpressionVisitor() {} virtual void visit(Expression &e) = 0; virtual void aboutToChange() {} virtual int changed() const { return 0;} virtual void reset() {} virtual App::PropertyLinkBase* getPropertyLink() {return 0;} protected: void getIdentifiers(Expression &e, std::set &); void getDeps(Expression &e, ExpressionDeps &); void getDepObjects(Expression &e, std::set &, std::vector *); bool adjustLinks(Expression &e, const std::set &inList); bool relabeledDocument(Expression &e, const std::string &oldName, const std::string &newName); bool renameObjectIdentifier(Expression &e, const std::map &, const ObjectIdentifier &); void collectReplacement(Expression &e, std::map &, const App::DocumentObject *parent, App::DocumentObject *oldObj, App::DocumentObject *newObj) const; bool updateElementReference(Expression &e, App::DocumentObject *feature,bool reverse); void importSubNames(Expression &e, const ObjectIdentifier::SubNameMap &subNameMap); void updateLabelReference(Expression &e, App::DocumentObject *obj, const std::string &ref, const char *newLabel); void moveCells(Expression &e, const CellAddress &address, int rowCount, int colCount); void offsetCells(Expression &e, int rowOffset, int colOffset); }; template class ExpressionModifier : public ExpressionVisitor { public: ExpressionModifier(P & _prop) : prop(_prop) , propLink(Base::freecad_dynamic_cast(&prop)) , signaller(_prop,false) , _changed(0) {} virtual ~ExpressionModifier() { } virtual void aboutToChange() override{ ++_changed; signaller.aboutToChange(); } virtual int changed() const override { return _changed; } virtual void reset() override {_changed = 0;} virtual App::PropertyLinkBase* getPropertyLink() override {return propLink;} protected: P & prop; App::PropertyLinkBase *propLink; typename AtomicPropertyChangeInterface

::AtomicPropertyChange signaller; int _changed; }; /** * Base class for expressions. * */ class AppExport Expression : public Base::BaseClass { TYPESYSTEM_HEADER(); public: Expression(const App::DocumentObject * _owner); virtual ~Expression(); virtual bool isTouched() const { return false; } virtual Expression * eval() const = 0; virtual std::string toString(bool persistent=false) const = 0; static Expression * parse(const App::DocumentObject * owner, const std::string& buffer); Expression * copy() const; virtual int priority() const { return 0; } void getIdentifiers(std::set &) const; std::set getIdentifiers() const; void getDeps(ExpressionDeps &deps) const; ExpressionDeps getDeps() const; std::set getDepObjects(std::vector *labels=0) const; void getDepObjects(std::set &, std::vector *labels=0) const; ExpressionPtr importSubNames(const std::map &nameMap) const; ExpressionPtr updateLabelReference(App::DocumentObject *obj, const std::string &ref, const char *newLabel) const; ExpressionPtr replaceObject(const App::DocumentObject *parent, App::DocumentObject *oldObj, App::DocumentObject *newObj) const; bool adjustLinks(const std::set &inList); virtual Expression * simplify() const = 0; void visit(ExpressionVisitor & v); class Exception : public Base::Exception { public: Exception(const char *sMessage) : Base::Exception(sMessage) { } }; App::DocumentObject * getOwner() const { return owner; } virtual boost::any getValueAsAny() const = 0; virtual Py::Object getPyValue() const = 0; bool isSame(const Expression &other) const; friend ExpressionVisitor; protected: virtual Expression *_copy() const = 0; virtual void _getDeps(ExpressionDeps &) const {} virtual void _getDepObjects(std::set &, std::vector *) const {} virtual void _getIdentifiers(std::set &) const {} virtual bool _adjustLinks(const std::set &, ExpressionVisitor &) {return false;} virtual bool _updateElementReference(App::DocumentObject *,bool,ExpressionVisitor &) {return false;} virtual bool _relabeledDocument(const std::string &, const std::string &, ExpressionVisitor &) {return false;} virtual void _importSubNames(const ObjectIdentifier::SubNameMap &) {} virtual void _updateLabelReference(App::DocumentObject *, const std::string &, const char *) {} virtual bool _renameObjectIdentifier(const std::map &, const ObjectIdentifier &, ExpressionVisitor &) {return false;} virtual void _collectReplacement(std::map &, const App::DocumentObject *parent, App::DocumentObject *oldObj, App::DocumentObject *newObj) const { (void)parent; (void)oldObj; (void)newObj; } virtual void _moveCells(const CellAddress &, int, int, ExpressionVisitor &) {} virtual void _offsetCells(int, int, ExpressionVisitor &) {} virtual void _visit(ExpressionVisitor &) {} protected: App::DocumentObject * owner; /**< The document object used to access unqualified variables (i.e local scope) */ public: std::string comment; }; } #if defined(__clang__) # pragma clang diagnostic pop #endif #endif // EXPRESSION_H