diff --git a/SofaKernel/modules/SofaCore/src/sofa/core/collision/Contact.h b/SofaKernel/modules/SofaCore/src/sofa/core/collision/Contact.h index b2c9599acdf..379ca2696e3 100644 --- a/SofaKernel/modules/SofaCore/src/sofa/core/collision/Contact.h +++ b/SofaKernel/modules/SofaCore/src/sofa/core/collision/Contact.h @@ -83,10 +83,10 @@ class SOFA_CORE_API Contact : public virtual objectmodel::BaseObject virtual void setKeepAlive(bool /* val */) {} //Todo adding TPtr parameter - class Factory : public helper::Factory< std::string, Contact, std::pair,Intersection*>, Contact::SPtr > + class SOFA_CORE_API Factory : public helper::Factory< std::string, Contact, std::pair,Intersection*>, Contact::SPtr > { public: - static Factory SOFA_CORE_API *getInstance(); + static Factory *getInstance(); static ObjectPtr CreateObject(Key key, Argument arg) { diff --git a/SofaKernel/modules/SofaHelper/SofaHelper_test/CMakeLists.txt b/SofaKernel/modules/SofaHelper/SofaHelper_test/CMakeLists.txt index 7a11101ea33..d9a07c70f8d 100644 --- a/SofaKernel/modules/SofaHelper/SofaHelper_test/CMakeLists.txt +++ b/SofaKernel/modules/SofaHelper/SofaHelper_test/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.12) project(SofaHelper_test) set(SOURCE_FILES + Factory_test.cpp KdTree_test.cpp Utils_test.cpp io/MeshOBJ_test.cpp diff --git a/SofaKernel/modules/SofaHelper/SofaHelper_test/Factory_test.cpp b/SofaKernel/modules/SofaHelper/SofaHelper_test/Factory_test.cpp new file mode 100644 index 00000000000..dbb588f1f9d --- /dev/null +++ b/SofaKernel/modules/SofaHelper/SofaHelper_test/Factory_test.cpp @@ -0,0 +1,120 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program 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 Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#include +using sofa::testing::BaseTest; + +#include +#include + +namespace sofa +{ + +/// Enum class used as the key of a factory +enum class DummyEnum +{ + A, B, C, D +}; + +/// Factories require this operator in order to have a custom class as a key +std::ostream& operator << ( std::ostream& out, const DummyEnum& d ) +{ + switch (d) + { + case DummyEnum::A: out << "A"; + case DummyEnum::B: out << "B"; + case DummyEnum::C: out << "C"; + case DummyEnum::D: out << "D"; + } + return out; +} + +struct DummyBaseClass +{ + virtual std::string getTestValue() const { return "Base";} + + /// Helper function required by the factory to instantiate a new object + template + static T* create(T*, sofa::helper::NoArgument /*noarg*/) + { + return new T(); + } +}; +struct DummyClassA : public DummyBaseClass { std::string getTestValue() const override { return "A";}}; +struct DummyClassB : public DummyBaseClass { std::string getTestValue() const override { return "B";}}; +struct DummyClassC : public DummyBaseClass { std::string getTestValue() const override { return "C";}}; +struct DummyClassD : public DummyBaseClass { std::string getTestValue() const override { return "D";}}; + +/// Definition of the factory +/// Key is the enum type defined earlier. It requires the less operator and operator << +/// Objects created based on the key are of type DummyBaseClass +using DummyEnumFactory = sofa::helper::Factory; + +namespace helper +{ +template class +sofa::helper::Factory< DummyEnum, DummyBaseClass>; +} + +class Factory_test : public BaseTest +{ +public: + void testEnumKey() + { + sofa::helper::Creator dummyClassACreator(DummyEnum::A, false); + sofa::helper::Creator dummyClassBCreator(DummyEnum::B, false); + sofa::helper::Creator dummyClassCCreator(DummyEnum::C, false); + sofa::helper::Creator dummyClassDCreator(DummyEnum::D, false); + + auto a = DummyEnumFactory::CreateObject(DummyEnum::A, sofa::helper::NoArgument()); + EXPECT_TRUE(a); + EXPECT_TRUE(dynamic_cast(a)); + EXPECT_EQ(a->getTestValue(), "A"); + + auto b = DummyEnumFactory::CreateObject(DummyEnum::B, sofa::helper::NoArgument()); + EXPECT_TRUE(b); + EXPECT_TRUE(dynamic_cast(b)); + EXPECT_EQ(b->getTestValue(), "B"); + + auto c = DummyEnumFactory::CreateObject(DummyEnum::C, sofa::helper::NoArgument()); + EXPECT_TRUE(c); + EXPECT_TRUE(dynamic_cast(c)); + EXPECT_EQ(c->getTestValue(), "C"); + + auto d = DummyEnumFactory::CreateObject(DummyEnum::D, sofa::helper::NoArgument()); + EXPECT_TRUE(d); + EXPECT_TRUE(dynamic_cast(d)); + EXPECT_EQ(d->getTestValue(), "D"); + + DummyEnumFactory::ResetEntry(DummyEnum::A); + DummyEnumFactory::ResetEntry(DummyEnum::B); + DummyEnumFactory::ResetEntry(DummyEnum::C); + DummyEnumFactory::ResetEntry(DummyEnum::D); + + } +}; + +TEST_F(Factory_test, EnumKey) +{ + testEnumKey(); +} + +} //namespace sofa \ No newline at end of file diff --git a/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.cpp b/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.cpp index aea6d2c50ac..698e5ea9827 100644 --- a/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.cpp +++ b/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.cpp @@ -19,6 +19,7 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ +#define SOFAHELPER_FACTORY_CPP #include #include #ifdef __GNUC__ @@ -26,14 +27,11 @@ #endif #include -namespace sofa -{ - -namespace helper +namespace sofa::helper { /// Decode the type's name to a more readable form if possible -std::string SOFA_HELPER_API gettypename(const std::type_info& t) +SOFA_HELPER_API std::string gettypename(const std::type_info& t) { std::string name; #ifdef __GNUC__ @@ -82,27 +80,20 @@ std::string SOFA_HELPER_API gettypename(const std::type_info& t) return name; } -static std::string& getFactoryLog() +SOFA_HELPER_API std::string& getFactoryLog() { static std::string s; return s; } -/// Log classes registered in the factory -void SOFA_HELPER_API logFactoryRegister(std::string baseclass, std::string classname, std::string key, bool multi) -{ - getFactoryLog() += baseclass + (multi?" template class ":" class ") - + classname + " registered as " + key + "\n"; -} - /// Print factory log -void SOFA_HELPER_API printFactoryLog(std::ostream& out) +SOFA_HELPER_API void printFactoryLog(std::ostream& out) { out << getFactoryLog(); } +//explicit instantiation for std::string +template SOFA_HELPER_API void logFactoryRegister(const std::string& baseclass, const std::string& classname, std::string key, bool multi); -} // namespace helper - -} // namespace sofa +} // namespace sofa::helper diff --git a/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.h b/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.h index ff725c47d5c..ea386657bd4 100644 --- a/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.h +++ b/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.h @@ -19,8 +19,7 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#ifndef SOFA_HELPER_FACTORY_H -#define SOFA_HELPER_FACTORY_H +#pragma once #include #include @@ -30,23 +29,23 @@ #include #include -namespace sofa -{ - -namespace helper +namespace sofa::helper { /// Allow us to use BaseCreator and Factory without using any Arguments class NoArgument {} ; /// Decode the type's name to a more readable form if possible -std::string SOFA_HELPER_API gettypename(const std::type_info& t); +SOFA_HELPER_API std::string gettypename(const std::type_info& t); /// Log classes registered in the factory -void SOFA_HELPER_API logFactoryRegister(std::string baseclass, std::string classname, std::string key, bool multi); +template +SOFA_HELPER_API void logFactoryRegister(const std::string& baseclass, const std::string& classname, TKey key, bool multi); + +SOFA_HELPER_API std::string& getFactoryLog(); /// Print factory log -void SOFA_HELPER_API printFactoryLog(std::ostream& out = std::cout); +SOFA_HELPER_API void printFactoryLog(std::ostream& out = std::cout); template class BaseCreator @@ -66,7 +65,6 @@ class Factory typedef TPtr ObjectPtr; typedef TArgument Argument; typedef BaseCreator Creator; - typedef std::multimap Registry; protected: std::multimap registry; @@ -134,7 +132,7 @@ class Factory }; template -class Creator : public Factory::Creator, public Factory::Key +class Creator : public Factory::Creator { public: typedef typename Factory::Object Object; @@ -142,7 +140,7 @@ class Creator : public Factory::Creator, public Factory::Key typedef typename Factory::Argument Argument; typedef typename Factory::Key Key; explicit Creator(Key key, bool multi=false) - : Key(key) + : m_key(key) { Factory::getInstance()->registerCreator(key, this, multi); } @@ -162,6 +160,14 @@ class Creator : public Factory::Creator, public Factory::Key msg_info("Creator") << "[SOFA]Registration of class : " << type().name(); } + const Key& getKey() const + { + return m_key; + } + +private: + + Key m_key; }; template @@ -192,12 +198,11 @@ class CreatorFn : public Factory::Creator, public Factory::Key } }; +#if !defined(SOFAHELPER_FACTORY_CPP) +extern template SOFA_HELPER_API void logFactoryRegister(const std::string& baseclass, const std::string& classname, std::string key, bool multi); +#endif -} // namespace helper - -} // namespace sofa +} // namespace sofa::helper // Creator is often used without namespace qualifiers using sofa::helper::Creator; - -#endif diff --git a/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.inl b/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.inl index d947d9961b9..24a68760fdb 100644 --- a/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.inl +++ b/SofaKernel/modules/SofaHelper/src/sofa/helper/Factory.inl @@ -29,11 +29,17 @@ #include #include -namespace sofa +namespace sofa::helper { -namespace helper +template +void logFactoryRegister(const std::string& baseclass, const std::string& classname, TKey key, bool multi) { + std::stringstream ss; + ss << key; + getFactoryLog() += baseclass + (multi?" template class ":" class ") + + classname + " registered as " + ss.str() + "\n"; +} template @@ -158,8 +164,6 @@ bool Factory::resetEntry( Key existingKey) } -} // namespace helper - -} // namespace sofa +} // namespace sofa::helper #endif diff --git a/SofaKernel/modules/SofaMeshCollision/src/SofaMeshCollision/BarycentricPenalityContact.cpp b/SofaKernel/modules/SofaMeshCollision/src/SofaMeshCollision/BarycentricPenalityContact.cpp index 37d0425252a..7799be53f72 100644 --- a/SofaKernel/modules/SofaMeshCollision/src/SofaMeshCollision/BarycentricPenalityContact.cpp +++ b/SofaKernel/modules/SofaMeshCollision/src/SofaMeshCollision/BarycentricPenalityContact.cpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace sofa::component::collision { diff --git a/SofaKernel/modules/SofaSimpleFem/src/SofaSimpleFem/TetrahedronFEMForceField.inl b/SofaKernel/modules/SofaSimpleFem/src/SofaSimpleFem/TetrahedronFEMForceField.inl index acb4ab07e8f..d2a82081a6b 100644 --- a/SofaKernel/modules/SofaSimpleFem/src/SofaSimpleFem/TetrahedronFEMForceField.inl +++ b/SofaKernel/modules/SofaSimpleFem/src/SofaSimpleFem/TetrahedronFEMForceField.inl @@ -1977,7 +1977,7 @@ void TetrahedronFEMForceField::addKToMatrix(sofa::defaulttype::BaseMa } else { - int i,j,n1, n2, row, column, ROW, COLUMN , IT; + int IT; StiffnessMatrix JKJt,tmp; Index noeud1, noeud2; diff --git a/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/AttributeElement.cpp b/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/AttributeElement.cpp index 6ef6c3548ff..daa4b1ce92d 100644 --- a/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/AttributeElement.cpp +++ b/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/AttributeElement.cpp @@ -64,7 +64,7 @@ Creator AttributeNodeClass("Attribut const char* AttributeElement::getClass() const { - return AttributeNodeClass.c_str(); + return AttributeNodeClass.getKey().c_str(); } } // namespace sofa::simulation::xml diff --git a/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/DataElement.cpp b/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/DataElement.cpp index ef1de2d0afb..c7e297879fd 100644 --- a/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/DataElement.cpp +++ b/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/DataElement.cpp @@ -55,7 +55,7 @@ Creator DataNodeClass("Data"); const char* DataElement::getClass() const { - return DataNodeClass.c_str(); + return DataNodeClass.getKey().c_str(); } } // namespace sofa::simulation::xml diff --git a/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/NodeElement.cpp b/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/NodeElement.cpp index ae1932fbf10..c387f71ea21 100644 --- a/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/NodeElement.cpp +++ b/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/NodeElement.cpp @@ -85,7 +85,7 @@ helper::Creator NodeNodeClass("Node"); const char* NodeElement::getClass() const { - return NodeNodeClass.c_str(); + return NodeNodeClass.getKey().c_str(); } } // namespace sofa::simulation::xml diff --git a/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/ObjectElement.cpp b/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/ObjectElement.cpp index fc57362e155..df40215ac6e 100644 --- a/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/ObjectElement.cpp +++ b/SofaKernel/modules/SofaSimulationCommon/src/SofaSimulationCommon/xml/ObjectElement.cpp @@ -113,7 +113,7 @@ Creator ObjectNodeClass("Object"); const char* ObjectElement::getClass() const { - return ObjectNodeClass.c_str(); + return ObjectNodeClass.getKey().c_str(); } } // namespace sofa::simulation::xml diff --git a/SofaKernel/modules/SofaSimulationGraph/src/SofaSimulationGraph/DAGNodeMultiMappingElement.cpp b/SofaKernel/modules/SofaSimulationGraph/src/SofaSimulationGraph/DAGNodeMultiMappingElement.cpp index e6d99bc6dc2..136a95160b2 100644 --- a/SofaKernel/modules/SofaSimulationGraph/src/SofaSimulationGraph/DAGNodeMultiMappingElement.cpp +++ b/SofaKernel/modules/SofaSimulationGraph/src/SofaSimulationGraph/DAGNodeMultiMappingElement.cpp @@ -55,7 +55,7 @@ helper::Creator #include #include +#include namespace sofa { diff --git a/modules/SofaUserInteraction/src/SofaUserInteraction/AddRecordedCameraPerformer.cpp b/modules/SofaUserInteraction/src/SofaUserInteraction/AddRecordedCameraPerformer.cpp index 5aefe489030..9f02729a8f8 100644 --- a/modules/SofaUserInteraction/src/SofaUserInteraction/AddRecordedCameraPerformer.cpp +++ b/modules/SofaUserInteraction/src/SofaUserInteraction/AddRecordedCameraPerformer.cpp @@ -37,31 +37,33 @@ using namespace sofa::core::objectmodel; namespace sofa::component::collision { - helper::Creator AddRecordedCameraPerformerClass("AddRecordedCamera"); - void AddRecordedCameraPerformer::start() +void AddRecordedCameraPerformer::start() +{ + sofa::simulation::Node::SPtr root = down_cast( interactor->getContext()->getRootContext() ); + if(root) { - sofa::simulation::Node::SPtr root = down_cast( interactor->getContext()->getRootContext() ); - if(root) - { - sofa::component::visualmodel::RecordedCamera* currentCamera = root->getNodeObject(); + sofa::component::visualmodel::RecordedCamera* currentCamera = root->getNodeObject(); - if(currentCamera) - { - // Set the current camera's position in recorded camera for navigation - sofa::component::visualmodel::RecordedCamera::Vec3 _pos = currentCamera->p_position.getValue(); - sofa::type::vector posis = currentCamera->m_translationPositions.getValue(); - posis.push_back(_pos); - currentCamera->m_translationPositions.setValue(posis); + if(currentCamera) + { + // Set the current camera's position in recorded camera for navigation + sofa::component::visualmodel::RecordedCamera::Vec3 _pos = currentCamera->p_position.getValue(); + sofa::type::vector posis = currentCamera->m_translationPositions.getValue(); + posis.push_back(_pos); + currentCamera->m_translationPositions.setValue(posis); - // Set the current camera's orientation in recorded camera for navigation - sofa::component::visualmodel::RecordedCamera::Quat _ori = currentCamera->p_orientation.getValue(); - sofa::type::vectororis = currentCamera->m_translationOrientations.getValue();//push_back(m_vectorOrientations); - oris.push_back(_ori); - currentCamera->m_translationOrientations.setValue(oris); + // Set the current camera's orientation in recorded camera for navigation + sofa::component::visualmodel::RecordedCamera::Quat _ori = currentCamera->p_orientation.getValue(); + sofa::type::vectororis = currentCamera->m_translationOrientations.getValue();//push_back(m_vectorOrientations); + oris.push_back(_ori); + currentCamera->m_translationOrientations.setValue(oris); - } } } +} + + +helper::Creator AddRecordedCameraPerformerClass("AddRecordedCamera"); }// namespace sofa::component::collision diff --git a/modules/SofaUserInteraction/src/SofaUserInteraction/AttachBodyPerformer.cpp b/modules/SofaUserInteraction/src/SofaUserInteraction/AttachBodyPerformer.cpp index 338b3622fee..eb6d29b80a4 100644 --- a/modules/SofaUserInteraction/src/SofaUserInteraction/AttachBodyPerformer.cpp +++ b/modules/SofaUserInteraction/src/SofaUserInteraction/AttachBodyPerformer.cpp @@ -39,8 +39,8 @@ template class SOFA_SOFAUSERINTERACTION_API AttachBodyPerformer; template class SOFA_SOFAUSERINTERACTION_API AttachBodyPerformer; -static helper::Creator > AttachBodyPerformerVec2dClass("AttachBody",true); -static helper::Creator > AttachBodyPerformerVec3dClass("AttachBody",true); -static helper::Creator > AttachBodyPerformerRigid3dClass("AttachBody",true); +helper::Creator > AttachBodyPerformerVec2dClass("AttachBody",true); +helper::Creator > AttachBodyPerformerVec3dClass("AttachBody",true); +helper::Creator > AttachBodyPerformerRigid3dClass("AttachBody",true); } // namespace sofa::component::collision diff --git a/modules/SofaUserInteraction/src/SofaUserInteraction/AttachBodyPerformer.inl b/modules/SofaUserInteraction/src/SofaUserInteraction/AttachBodyPerformer.inl index 92282cead15..e2132273fc7 100644 --- a/modules/SofaUserInteraction/src/SofaUserInteraction/AttachBodyPerformer.inl +++ b/modules/SofaUserInteraction/src/SofaUserInteraction/AttachBodyPerformer.inl @@ -25,6 +25,7 @@ #include #include #include + namespace sofa::component::collision {