From 27620ed717459a4ddf6f2af0726933273288e5ee Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sun, 10 Feb 2019 13:50:07 +0100 Subject: [PATCH] Part: GeometryDefaultExtensions template ======================================== Generalisation of code for a default geometry extension in the form of a template. Default geometry extensions provide a standard interface for an extension having a single stored value (e.g. one int or one string). Python implementation must be provided separatedly. --- src/Base/BaseClass.h | 26 +++- src/Mod/Part/App/AppPart.cpp | 3 +- src/Mod/Part/App/CMakeLists.txt | 6 +- src/Mod/Part/App/GeometryDefaultExtension.cpp | 113 ++++++++++++++++++ ...Extension.h => GeometryDefaultExtension.h} | 48 ++++++-- src/Mod/Part/App/GeometryIntExtension.cpp | 84 ------------- src/Mod/Part/App/GeometryIntExtension.h | 54 --------- src/Mod/Part/App/GeometryIntExtensionPy.xml | 2 +- .../Part/App/GeometryIntExtensionPyImp.cpp | 10 +- src/Mod/Part/App/GeometryStringExtension.cpp | 84 ------------- .../Part/App/GeometryStringExtensionPy.xml | 2 +- .../Part/App/GeometryStringExtensionPyImp.cpp | 10 +- 12 files changed, 189 insertions(+), 253 deletions(-) create mode 100644 src/Mod/Part/App/GeometryDefaultExtension.cpp rename src/Mod/Part/App/{GeometryStringExtension.h => GeometryDefaultExtension.h} (50%) delete mode 100644 src/Mod/Part/App/GeometryIntExtension.cpp delete mode 100644 src/Mod/Part/App/GeometryIntExtension.h delete mode 100644 src/Mod/Part/App/GeometryStringExtension.cpp diff --git a/src/Base/BaseClass.h b/src/Base/BaseClass.h index cab16ed716..0ba82f3448 100644 --- a/src/Base/BaseClass.h +++ b/src/Base/BaseClass.h @@ -61,6 +61,15 @@ void * _class_::create(void){\ return new _class_ ();\ } +/// define to implement a subclass of Base::BaseClass +#define TYPESYSTEM_SOURCE_TEMPLATE_P(_class_) \ +template<> Base::Type _class_::getClassTypeId(void) { return _class_::classTypeId; } \ +template<> Base::Type _class_::getTypeId(void) const { return _class_::classTypeId; } \ +template<> Base::Type _class_::classTypeId = Base::Type::badType(); \ +template<> void * _class_::create(void){\ + return new _class_ ();\ +} + /// define to implement a subclass of Base::BaseClass #define TYPESYSTEM_SOURCE_ABSTRACT_P(_class_) \ Base::Type _class_::getClassTypeId(void) { return _class_::classTypeId; } \ @@ -76,6 +85,13 @@ void _class_::init(void){\ initSubclass(_class_::classTypeId, #_class_ , #_parentclass_, &(_class_::create) ); \ } +/// define to implement a subclass of Base::BaseClass +#define TYPESYSTEM_SOURCE_TEMPLATE_T(_class_, _parentclass_) \ +TYPESYSTEM_SOURCE_TEMPLATE_P(_class_);\ +template<> void _class_::init(void){\ + initSubclass(_class_::classTypeId, #_class_ , #_parentclass_, &(_class_::create) ); \ +} + /// define to implement a subclass of Base::BaseClass #define TYPESYSTEM_SOURCE_ABSTRACT(_class_, _parentclass_) \ TYPESYSTEM_SOURCE_ABSTRACT_P(_class_);\ @@ -88,9 +104,9 @@ namespace Base /// BaseClass class and root of the type system class BaseExport BaseClass { -public: - static Type getClassTypeId(void); - virtual Type getTypeId(void) const; +public: + static Type getClassTypeId(void); + virtual Type getTypeId(void) const; bool isDerivedFrom(const Type type) const {return getTypeId().isDerivedFrom(type);} static void init(void); @@ -99,7 +115,7 @@ public: virtual void setPyObject(PyObject *); static void *create(void){return 0;} -private: +private: static Type classTypeId; protected: static void initSubclass(Base::Type &toInit,const char* ClassName, const char *ParentName, Type::instantiationMethod method=0); @@ -124,7 +140,7 @@ template T * freecad_dynamic_cast(Base::BaseClass * t) else return 0; } - + /** * Template that works just like dynamic_cast, but expects the argument to * inherit from a const Base::BaseClass. diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index 6f2f32e0b5..ae01cbf998 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -58,8 +58,7 @@ #include "CustomFeature.h" #include "Geometry.h" #include "GeometryExtension.h" -#include "GeometryIntExtension.h" -#include "GeometryStringExtension.h" +#include "GeometryDefaultExtension.h" #include "Geometry2d.h" #include "Mod/Part/App/GeometryIntExtensionPy.h" #include "Mod/Part/App/GeometryStringExtensionPy.h" diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index 1db8c4ffcc..1053c1ef43 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -351,10 +351,8 @@ SET(Part_SRCS CrossSection.h GeometryExtension.cpp GeometryExtension.h - GeometryIntExtension.cpp - GeometryIntExtension.h - GeometryStringExtension.cpp - GeometryStringExtension.h + GeometryDefaultExtension.cpp + GeometryDefaultExtension.h Geometry.cpp Geometry.h Geometry2d.cpp diff --git a/src/Mod/Part/App/GeometryDefaultExtension.cpp b/src/Mod/Part/App/GeometryDefaultExtension.cpp new file mode 100644 index 0000000000..6adbb62bec --- /dev/null +++ b/src/Mod/Part/App/GeometryDefaultExtension.cpp @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (c) 2019 Abdullah Tahiri * + * * + * 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 * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#include +#include +#include +#include + +#include "GeometryDefaultExtension.h" + +#include "GeometryStringExtensionPy.h" +#include "GeometryIntExtensionPy.h" + +using namespace Part; + +//---------- Geometry Extension +template +GeometryDefaultExtension::GeometryDefaultExtension(const T& obj):value(obj) +{ + +} + +// Persistence implementer +template +unsigned int GeometryDefaultExtension::getMemSize (void) const +{ + return 1; +} + +template +void GeometryDefaultExtension::Save(Base::Writer &writer) const +{ + + writer.Stream() << writer.ind() << "getTypeId().getName() + << "\" value=\"" << value << "\"/>" << std::endl; +} + +template +void GeometryDefaultExtension::Restore(Base::XMLReader &reader) +{ + value = reader.getAttribute("value"); +} + +template +std::unique_ptr GeometryDefaultExtension::copy(void) const +{ + std::unique_ptr> cpy = std::make_unique>(); + + cpy->value = this->value; + + return cpy; + // Don't std::move(cpy); RVO optimization Item 25, if the compiler fails to elide, would have to move it anyway + // move constructor is executed if available (it is). Unique_ptr does not have copy constructor. +} + +template +PyObject * GeometryDefaultExtension::getPyObject(void) +{ + THROWM(Base::NotImplementedError,"Python object not implemented for default geometry extension template type. Template Specialisation missing."); // use template specialisation to provide the actual object +} + +// ----------------------------- Template specialisations---------------------------------------------------- + +//typedef Part::GeometryDefaultExtension GeometryIntExtension; +//typedef Part::GeometryStringExtension GeometryStringExtension; + +// ---------- GeometryIntExtension ---------- +TYPESYSTEM_SOURCE_TEMPLATE_T(Part::GeometryIntExtension,Part::GeometryExtension) + +template <> +PyObject * GeometryDefaultExtension::getPyObject(void) +{ + return new GeometryIntExtensionPy(new GeometryIntExtension(this->value)); +} + +template <> +void GeometryDefaultExtension::Restore(Base::XMLReader &reader) +{ + value = reader.getAttributeAsInteger("value"); +} + +// ---------- GeometryStringExtension ---------- +TYPESYSTEM_SOURCE_TEMPLATE_T(Part::GeometryStringExtension,Part::GeometryExtension) + +template <> +PyObject * GeometryDefaultExtension::getPyObject(void) +{ + return new GeometryStringExtensionPy(new GeometryStringExtension(this->value)); +} + + diff --git a/src/Mod/Part/App/GeometryStringExtension.h b/src/Mod/Part/App/GeometryDefaultExtension.h similarity index 50% rename from src/Mod/Part/App/GeometryStringExtension.h rename to src/Mod/Part/App/GeometryDefaultExtension.h index b6a9f7163a..89f567143b 100644 --- a/src/Mod/Part/App/GeometryStringExtension.h +++ b/src/Mod/Part/App/GeometryDefaultExtension.h @@ -21,21 +21,22 @@ ***************************************************************************/ -#ifndef PART_GEOMETRYSTRINGEXTENSION_H -#define PART_GEOMETRYSTRINGEXTENSION_H +#ifndef PART_GEOMETRYDEFAULTEXTENSION_H +#define PART_GEOMETRYDEFAULTEXTENSION_H #include #include "GeometryExtension.h" namespace Part { - class PartExport GeometryStringExtension: public Part::GeometryExtension + template + class PartExport GeometryDefaultExtension: public Part::GeometryExtension { TYPESYSTEM_HEADER(); public: - GeometryStringExtension(); - GeometryStringExtension(std::string strp); - virtual ~GeometryStringExtension(); + GeometryDefaultExtension() = default; + GeometryDefaultExtension(const T& obj); + virtual ~GeometryDefaultExtension() = default; // Persistence implementer --------------------- virtual unsigned int getMemSize(void) const; @@ -47,9 +48,40 @@ namespace Part { virtual PyObject *getPyObject(void); public: - std::string str; + T value; }; + // Description: + // + // This template allows to define a geometry extension for a given type (uniform interface for one value of type T). + // + // Warnings: + // - The default constructor relies on the default constructor of T for initialisation. Built-in types + // so constructed will be uninitialised. Use the specific constructor from a T to initiliase it. + // + // Default assumptions: + // - T can be constructed from T + // - T can be assigned to T + // - T is convertible to a std::string + // - T is serialisable as a string + // + // template specialisation: + // + // If the assumptions do not meet for your type, template specialisation allows you to provide specific code, + // look for examples (int/string) in GeometryDefaultExtensions.cpp + // + // Instructions: + // + // 1. Read the assumptions above and provide template initilisation if needed. + // 2. Add an alias to your type under these comments + // 3. Add a TYPESYSTEM_SOURCE_TEMPLATE_T in the cpp file to generate class type information + // 4. Provide a specialisation of getPyObject to generate a py object of the corresponding type (cpp file) + // 5. Provide specialisations if your type does not meet the assumptions above (e.g. for serialisation) (cpp file) + // 6. Register your type and corresponding python type in AppPart.cpp + + // Prefer alias to typedef item 9 + using GeometryIntExtension = GeometryDefaultExtension; + using GeometryStringExtension = GeometryDefaultExtension; } -#endif // PART_GEOMETRYSTRINGEXTENSION_H +#endif // PART_GEOMETRYDEFAULTEXTENSION_H diff --git a/src/Mod/Part/App/GeometryIntExtension.cpp b/src/Mod/Part/App/GeometryIntExtension.cpp deleted file mode 100644 index da9af3f9fc..0000000000 --- a/src/Mod/Part/App/GeometryIntExtension.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2019 Abdullah Tahiri * - * * - * 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 * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#include -#include -#include - -#include "GeometryIntExtension.h" - -#include - -using namespace Part; - -//---------- Geometry Extension - -TYPESYSTEM_SOURCE(Part::GeometryIntExtension,Part::GeometryExtension) - -GeometryIntExtension::GeometryIntExtension():id(0) -{ - -} - -GeometryIntExtension::GeometryIntExtension(long cid):id(cid) -{ - -} - -GeometryIntExtension::~GeometryIntExtension() -{ -} - -// Persistence implementer -unsigned int GeometryIntExtension::getMemSize (void) const -{ - return sizeof(long int); -} - -void GeometryIntExtension::Save(Base::Writer &writer) const -{ - - writer.Stream() << writer.ind() << "getTypeId().getName() - << "\" value=\"" << id << "\"/>" << std::endl; -} - -void GeometryIntExtension::Restore(Base::XMLReader &reader) -{ - id = reader.getAttributeAsInteger("value"); -} - -std::unique_ptr GeometryIntExtension::copy(void) const -{ - std::unique_ptr cpy = std::make_unique(); - - cpy->id = this->id; - - return std::move(cpy); -} - -PyObject * GeometryIntExtension::getPyObject(void) -{ - return new GeometryIntExtensionPy(new GeometryIntExtension(this->id)); -} diff --git a/src/Mod/Part/App/GeometryIntExtension.h b/src/Mod/Part/App/GeometryIntExtension.h deleted file mode 100644 index 22fcbb1dcd..0000000000 --- a/src/Mod/Part/App/GeometryIntExtension.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2019 Abdullah Tahiri * - * * - * 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 PART_GEOMETRYINTEXTENSION_H -#define PART_GEOMETRYINTEXTENSION_H - -#include "GeometryExtension.h" - -namespace Part { - -class PartExport GeometryIntExtension: public Part::GeometryExtension -{ - TYPESYSTEM_HEADER(); -public: - GeometryIntExtension(); - GeometryIntExtension(long cid); - virtual ~GeometryIntExtension(); - - // Persistence implementer --------------------- - virtual unsigned int getMemSize(void) const; - virtual void Save(Base::Writer &/*writer*/) const; - virtual void Restore(Base::XMLReader &/*reader*/); - - virtual std::unique_ptr copy(void) const; - - virtual PyObject *getPyObject(void); - -public: - long int id; -}; - -} - -#endif // PART_GEOMETRYINTEXTENSION_H diff --git a/src/Mod/Part/App/GeometryIntExtensionPy.xml b/src/Mod/Part/App/GeometryIntExtensionPy.xml index 4709502668..694f1c2659 100644 --- a/src/Mod/Part/App/GeometryIntExtensionPy.xml +++ b/src/Mod/Part/App/GeometryIntExtensionPy.xml @@ -6,7 +6,7 @@ PythonName="Part.GeometryIntExtension" Twin="GeometryIntExtension" TwinPointer="GeometryIntExtension" - Include="Mod/Part/App/GeometryIntExtension.h" + Include="Mod/Part/App/GeometryDefaultExtension.h" Namespace="Part" FatherInclude="Mod/Part/App/GeometryExtensionPy.h" FatherNamespace="Part" diff --git a/src/Mod/Part/App/GeometryIntExtensionPyImp.cpp b/src/Mod/Part/App/GeometryIntExtensionPyImp.cpp index 82e4001dc5..d2d8600219 100644 --- a/src/Mod/Part/App/GeometryIntExtensionPyImp.cpp +++ b/src/Mod/Part/App/GeometryIntExtensionPyImp.cpp @@ -23,7 +23,7 @@ #include "PreCompiled.h" -#include "GeometryIntExtension.h" +#include "GeometryDefaultExtension.h" #include "GeometryIntExtensionPy.h" #include "GeometryIntExtensionPy.cpp" @@ -34,7 +34,7 @@ using namespace Part; std::string GeometryIntExtensionPy::representation(void) const { std::stringstream str; - long id = getGeometryIntExtensionPtr()->id; + long id = getGeometryIntExtensionPtr()->value; str << ""; return str.str(); } @@ -57,7 +57,7 @@ int GeometryIntExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/) PyErr_Clear(); int Id; if (PyArg_ParseTuple(args, "i", &Id)) { - this->getGeometryIntExtensionPtr()->id=Id; + this->getGeometryIntExtensionPtr()->value=Id; return 0; } @@ -71,12 +71,12 @@ int GeometryIntExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/) Py::Long GeometryIntExtensionPy::getValue(void) const { - return Py::Long(this->getGeometryIntExtensionPtr()->id); + return Py::Long(this->getGeometryIntExtensionPtr()->value); } void GeometryIntExtensionPy::setValue(Py::Long value) { - this->getGeometryIntExtensionPtr()->id=long(value); + this->getGeometryIntExtensionPtr()->value=long(value); } diff --git a/src/Mod/Part/App/GeometryStringExtension.cpp b/src/Mod/Part/App/GeometryStringExtension.cpp deleted file mode 100644 index 7019b8dd26..0000000000 --- a/src/Mod/Part/App/GeometryStringExtension.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2019 Abdullah Tahiri * - * * - * 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 * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#include -#include -#include - -#include "GeometryStringExtension.h" - -#include "GeometryStringExtensionPy.h" - -using namespace Part; - -//---------- Geometry Extension - -TYPESYSTEM_SOURCE(Part::GeometryStringExtension,Part::GeometryExtension) - -GeometryStringExtension::GeometryStringExtension() -{ - -} - -GeometryStringExtension::GeometryStringExtension(std::string strp):str(strp) -{ - -} - -GeometryStringExtension::~GeometryStringExtension() -{ -} - -// Persistence implementer -unsigned int GeometryStringExtension::getMemSize (void) const -{ - return 1; -} - -void GeometryStringExtension::Save(Base::Writer &writer) const -{ - - writer.Stream() << writer.ind() << "getTypeId().getName() - << "\" value=\"" << str << "\"/>" << std::endl; -} - -void GeometryStringExtension::Restore(Base::XMLReader &reader) -{ - str = reader.getAttribute("value"); -} - -std::unique_ptr GeometryStringExtension::copy(void) const -{ - std::unique_ptr cpy = std::make_unique(); - - cpy->str = this->str; - - return std::move(cpy); -} - -PyObject * GeometryStringExtension::getPyObject(void) -{ - return new GeometryStringExtensionPy(new GeometryStringExtension(this->str)); -} diff --git a/src/Mod/Part/App/GeometryStringExtensionPy.xml b/src/Mod/Part/App/GeometryStringExtensionPy.xml index 9d3787acff..0f371b9401 100644 --- a/src/Mod/Part/App/GeometryStringExtensionPy.xml +++ b/src/Mod/Part/App/GeometryStringExtensionPy.xml @@ -6,7 +6,7 @@ PythonName="Part.GeometryStringExtension" Twin="GeometryStringExtension" TwinPointer="GeometryStringExtension" - Include="Mod/Part/App/GeometryStringExtension.h" + Include="Mod/Part/App/GeometryDefaultExtension.h" Namespace="Part" FatherInclude="Mod/Part/App/GeometryExtensionPy.h" FatherNamespace="Part" diff --git a/src/Mod/Part/App/GeometryStringExtensionPyImp.cpp b/src/Mod/Part/App/GeometryStringExtensionPyImp.cpp index 64516d64d4..f1b39a0f6b 100644 --- a/src/Mod/Part/App/GeometryStringExtensionPyImp.cpp +++ b/src/Mod/Part/App/GeometryStringExtensionPyImp.cpp @@ -27,7 +27,7 @@ # include #endif -#include "GeometryStringExtension.h" +#include "GeometryDefaultExtension.h" #include "GeometryStringExtensionPy.h" #include "GeometryStringExtensionPy.cpp" @@ -38,7 +38,7 @@ using namespace Part; std::string GeometryStringExtensionPy::representation(void) const { std::stringstream str; - str << "str << ") >"; + str << "value << ") >"; return str.str(); } @@ -60,7 +60,7 @@ int GeometryStringExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/) PyErr_Clear(); char *pstr; if (PyArg_ParseTuple(args, "s", &pstr)) { - this->getGeometryStringExtensionPtr()->str=pstr; + this->getGeometryStringExtensionPtr()->value=pstr; return 0; } @@ -74,12 +74,12 @@ int GeometryStringExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/) Py::String GeometryStringExtensionPy::getValue(void) const { - return Py::String(this->getGeometryStringExtensionPtr()->str); + return Py::String(this->getGeometryStringExtensionPtr()->value); } void GeometryStringExtensionPy::setValue(Py::String value) { - this->getGeometryStringExtensionPtr()->str = value.as_std_string(); + this->getGeometryStringExtensionPtr()->value = value.as_std_string(); } PyObject *GeometryStringExtensionPy::getCustomAttributes(const char* /*attr*/) const