diff --git a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BruteForceDetection.h b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BruteForceDetection.h index 85837e1d5a0..c39a3d40fc6 100644 --- a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BruteForceDetection.h +++ b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BruteForceDetection.h @@ -40,6 +40,8 @@ class SOFA_COMPONENT_COLLISION_DETECTION_ALGORITHM_API BruteForceDetection final template static typename T::SPtr create(T*, sofa::core::objectmodel::BaseContext* context, sofa::core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // this one is funny as it behave like a Prefab, thus creating and adding other component in the graph. if (context) { if (const BruteForceBroadPhase::SPtr broadPhase = sofa::core::objectmodel::New()) diff --git a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DirectSAP.h b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DirectSAP.h index c2317ff9f88..2fe55e0c236 100644 --- a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DirectSAP.h +++ b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DirectSAP.h @@ -41,6 +41,8 @@ class SOFA_COMPONENT_COLLISION_DETECTION_ALGORITHM_API DirectSAP final : public template static typename T::SPtr create(T*, sofa::core::objectmodel::BaseContext* context, sofa::core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // this one is funny as it behave like a Prefab, thus creating and adding other component in the graph. if (context) { if (const BruteForceBroadPhase::SPtr broadPhase = sofa::core::objectmodel::New()) diff --git a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/RayTraceDetection.h b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/RayTraceDetection.h index 6a2d5e1bf58..d0394b68f9b 100644 --- a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/RayTraceDetection.h +++ b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/RayTraceDetection.h @@ -47,6 +47,8 @@ class SOFA_COMPONENT_COLLISION_DETECTION_ALGORITHM_API RayTraceDetection final : template static typename T::SPtr create(T*, sofa::core::objectmodel::BaseContext* context, sofa::core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // this one is funny as it behave like a Prefab, thus creating and adding other component in the graph. const BruteForceBroadPhase::SPtr broadPhase = sofa::core::objectmodel::New(); broadPhase->setName("bruteForceBroadPhase"); if (context) context->addObject(broadPhase); diff --git a/Sofa/Component/Collision/Geometry/src/sofa/component/collision/geometry/SphereModel.h b/Sofa/Component/Collision/Geometry/src/sofa/component/collision/geometry/SphereModel.h index ef5b8031204..21f164e74be 100644 --- a/Sofa/Component/Collision/Geometry/src/sofa/component/collision/geometry/SphereModel.h +++ b/Sofa/Component/Collision/Geometry/src/sofa/component/collision/geometry/SphereModel.h @@ -144,6 +144,8 @@ class SphereCollisionModel : public core::CollisionModel { typename T::SPtr obj; + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // duplicated code, path and context searching for states (probably to move into init) if( context) { auto* _mstate = dynamic_cast*>(context->getMechanicalState()); diff --git a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/CollisionResponse.h b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/CollisionResponse.h index 15780754ae8..e1b05bf25b1 100644 --- a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/CollisionResponse.h +++ b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/CollisionResponse.h @@ -56,6 +56,8 @@ public : template static typename T::SPtr create(T*, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // not sure how to handle this one... typename T::SPtr obj = sofa::core::objectmodel::New(); if (context) { diff --git a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/ContactListener.h b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/ContactListener.h index 9dcbaba1ae3..c5c536b3348 100644 --- a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/ContactListener.h +++ b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/ContactListener.h @@ -110,6 +110,9 @@ class SOFA_COMPONENT_COLLISION_RESPONSE_CONTACT_API ContactListener : public vir template static typename T::SPtr create(T* , core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // it seems there is some creative attribute hacking in this one. See if the behavior can be reimplemented + // using a mix of parse/init core::CollisionModel* collModel1 = nullptr; core::CollisionModel* collModel2 = nullptr; diff --git a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.h b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.h index 84671142adc..cedc270d8e7 100644 --- a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.h +++ b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.h @@ -72,7 +72,7 @@ class Distances : public core::DataEngine DistancesInternalData data; friend class DistancesInternalData; - Distances (); + Distances ( sofa::component::topology::container::dynamic::DynamicSparseGridTopologyContainer* hexaTopoContainer, core::behavior::MechanicalState* targetPointSet ); ~Distances() override {} @@ -200,15 +200,17 @@ class Distances : public core::DataEngine template static typename T::SPtr create(T*, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg ) { - typename T::SPtr obj = sofa::core::objectmodel::New(); + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // probably remove the constructor with arguments and replace that with SinglLink to delegate at + // init/parse the initiatilization. + typename T::SPtr obj = sofa::core::objectmodel::New( + ( arg?dynamic_cast ( arg->findObject ( arg->getAttribute ( "hexaContainerPath","../.." ) ) ) :nullptr ), + ( arg?dynamic_cast*> ( arg->findObject ( arg->getAttribute ( "targetPath",".." ) ) ) :nullptr ) ); if ( context ) context->addObject ( obj ); if ( arg ) { - obj->hexaContainer = dynamic_cast ( arg->findObject ( arg->getAttribute ( "hexaContainerPath","../.." ) ) ); - obj->target = dynamic_cast*> ( arg->findObject ( arg->getAttribute ( "targetPath",".." ) ) ); - if ( arg->getAttribute ( "hexaContainerPath" ) ) { obj->d_hexaContainerPath.setValue (arg->getAttribute ("hexaContainerPath" ) ); @@ -219,7 +221,6 @@ class Distances : public core::DataEngine obj->d_targetPath.setValue (arg->getAttribute ("targetPath" ) ); arg->removeAttribute ( "targetPath" ); } - obj->parse ( arg ); } diff --git a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.inl b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.inl index 74d24960570..abdae6d419e 100644 --- a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.inl +++ b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.inl @@ -39,7 +39,7 @@ using std::queue; using sofa::core::loader::VoxelLoader; template -Distances< DataTypes >::Distances () : +Distances< DataTypes >::Distances ( sofa::component::topology::container::dynamic::DynamicSparseGridTopologyContainer* hexaTopoContainer, core::behavior::MechanicalState* targetPointSet ) : d_showMapIndex (initData (&d_showMapIndex, (unsigned int)0, "showMapIndex", "Frame DOF index on which display values." ) ), d_showDistanceMap (initData (&d_showDistanceMap, false, "showDistancesMap", "show the distance for each point of the target point set." ) ), d_showGoalDistanceMap (initData (&d_showGoalDistanceMap, false, "showGoalDistancesMap", "show the distance for each point of the target point set." ) ), @@ -54,9 +54,9 @@ Distances< DataTypes >::Distances () : d_harmonicMaxValue (initData (&d_harmonicMaxValue, 100.0, "harmonicMaxValue", "Max value used to initialize the harmonic distance grid." ) ), d_fileDistance(initData(&d_fileDistance, "filename", "file containing the result of the computation of the distances")), d_targetPath(initData(&d_targetPath, "targetPath", "path to the goal point set topology")), - //target ( targetPointSet ) , - d_hexaContainerPath(initData(&d_hexaContainerPath, "hexaContainerPath", "path to the grid used to compute the distances")) - //hexaContainer ( hexaTopoContainer ) + target ( targetPointSet ) , + d_hexaContainerPath(initData(&d_hexaContainerPath, "hexaContainerPath", "path to the grid used to compute the distances")), + hexaContainer ( hexaTopoContainer ) { this->addAlias(&d_fileDistance, "d_fileDistance"); d_zonesFramePair.setDisplayed(false); // GUI can not display map. diff --git a/Sofa/framework/Core/src/sofa/core/Mapping.h b/Sofa/framework/Core/src/sofa/core/Mapping.h index daf5a0b3606..5bd1c2e48f5 100644 --- a/Sofa/framework/Core/src/sofa/core/Mapping.h +++ b/Sofa/framework/Core/src/sofa/core/Mapping.h @@ -239,6 +239,9 @@ class Mapping : public BaseMapping template static typename T::SPtr create(T*, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // it seems there is some creative attribute hacking in this one. See if we can implement similar + // behavior using parse/init() typename T::SPtr obj = sofa::core::objectmodel::New(); if (context) diff --git a/Sofa/framework/Core/src/sofa/core/Multi2Mapping.h b/Sofa/framework/Core/src/sofa/core/Multi2Mapping.h index 6616b222fa2..ea1408662c0 100644 --- a/Sofa/framework/Core/src/sofa/core/Multi2Mapping.h +++ b/Sofa/framework/Core/src/sofa/core/Multi2Mapping.h @@ -236,6 +236,8 @@ class Multi2Mapping : public BaseMapping template static typename T::SPtr create(T*, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // trivial remplacement (remarkably inconstitant behavior with the one implemented in Mapping::create) typename T::SPtr obj = sofa::core::objectmodel::New(); if (context) diff --git a/Sofa/framework/Core/src/sofa/core/MultiMapping.h b/Sofa/framework/Core/src/sofa/core/MultiMapping.h index c6ecfe48c78..60443004d65 100644 --- a/Sofa/framework/Core/src/sofa/core/MultiMapping.h +++ b/Sofa/framework/Core/src/sofa/core/MultiMapping.h @@ -238,6 +238,8 @@ class MultiMapping : public BaseMapping template static typename T::SPtr create(T*, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // trivial remplacement (remarkably inconstitant behavior with the one implemented in Mapping::create) typename T::SPtr obj = sofa::core::objectmodel::New(); if (context) diff --git a/Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp b/Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp index 20402e7c25f..6e862ea9af0 100644 --- a/Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp +++ b/Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp @@ -139,6 +139,20 @@ void findTemplatedCreator( } } +void ObjectFactory::postObjectCreation(sptr obj, objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg) +{ + if (context) + { + context->addObject(obj); + } + + if (arg) + { + obj->parse(arg); + } +} + + objectmodel::BaseObject::SPtr ObjectFactory::createObject(objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg) { objectmodel::BaseObject::SPtr object = nullptr; diff --git a/Sofa/framework/Core/src/sofa/core/ObjectFactory.h b/Sofa/framework/Core/src/sofa/core/ObjectFactory.h index e2b69590879..4443d9b37b3 100644 --- a/Sofa/framework/Core/src/sofa/core/ObjectFactory.h +++ b/Sofa/framework/Core/src/sofa/core/ObjectFactory.h @@ -59,7 +59,7 @@ class HasCreateMethod typedef char YesType[1]; typedef char NoType[2]; - template static YesType& test( decltype (&C::HasCreateMethod) ); + template static YesType& test( decltype (&C::template create) ); template static NoType& test(...); public: @@ -224,6 +224,9 @@ class SOFA_CORE_API ObjectFactory bool registerObjectsFromPlugin(const std::string& pluginName); bool registerObjects(ObjectRegistrationData& ro); + static void postObjectCreation(sptr object, + objectmodel::BaseContext* context, + objectmodel::BaseObjectDescription* arg); }; template @@ -279,32 +282,40 @@ class ObjectCreator : public ObjectFactory::Creator objectmodel::BaseObject::SPtr createInstance(objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg) override { + // This method is creating an instance of the specific Sofa object of template type "RealObject" typename RealObject::SPtr obj; + + // TODO(dmarchal: 08/01/2024) Deprecation layer for removal of canCreate/create + // The problem with create/canCreate is that it delegate to a sofa component to "check" + // and define its own "custom" creation process and condition for creatability. The consequence + // of the existing designs are the followin: + // - divergence in behavior between component including some "creative" usages like constructing + // complete sub-graph in the create function (like a Prefab) + // - the use of static template overload to "mimic" a kind of static override hard to understand. + // - strong duplication of creation code because of cut&past and unclear role of each method. + // - use of static method impose the code to be visible in the .h/.inl which contribute to the bloating + // of the dependency graph. + // So.. it was thus decided to remove it by: + // - moving the instanciation code in the factory part and not in the component itself, + // - enforcing the "common" behavior directly in the factory implemented on abstract type instead of + // concrete type. + // a constexpr pattern is used to implement a compatibility layer to keep old behavior. + + // This constexpr condition is there to branch between old code that is not yet updated + // to the new one in which. if constexpr(HasCreateMethod::value) { - obj = RealObject::create(context, arg); - msg_deprecated() << "This object was created using the RealObject::create method"; - } - else{ + // Create an instance of the object the "old way" & emit a deprecation message + RealObject* tmp; + obj = RealObject::create(tmp, context, arg); + msg_deprecated(obj.get()) << "This object was created using the RealObject::create method"; + } else{ obj = sofa::core::objectmodel::New(); - } - if (obj) - { - if (context) - { - context->addObject(obj); - } - if (arg) - { - obj->parse(arg); - } + ObjectFactory::postObjectCreation(obj, context, arg); } - else - { - msg_info(RealObject::GetClass()->className) << "Cannot create an instance"; - } - + // on case the creation is not possible... this is reported in the caller of + // create instance. return obj; } const std::type_info& type() override diff --git a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionConstraint.h b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionConstraint.h index d2c82954415..3038801de04 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionConstraint.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionConstraint.h @@ -119,7 +119,9 @@ class MixedInteractionConstraint : public BaseInteractionConstraint, public Pair template static typename T::SPtr create(T* p0, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { - typename T::SPtr obj = core::behavior::BaseInteractionConstraint::create(p0, context, arg); + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // not sure how to handle the call to the parent class + typename T::SPtr obj = core::behavior::BaseInteractionConstraint::deprecated_create(p0, context, arg); if (arg) { diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionConstraint.h b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionConstraint.h index 001c7e8ca6b..3cd749d6d63 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionConstraint.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionConstraint.h @@ -129,6 +129,8 @@ class PairInteractionConstraint : public BaseInteractionConstraint, public PairS template static typename T::SPtr create(T* p0, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // use parse/init instead of creative use of attribute hacking. typename T::SPtr obj = core::behavior::BaseInteractionConstraint::deprecated_create(p0, context, arg); if (arg) diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h index 20db861a697..7e0cc342f6e 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h @@ -186,6 +186,9 @@ class PairInteractionForceField : public BaseInteractionForceField, public PairS template static typename T::SPtr create(T* /*p0*/, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // use parse/init instead of creative use of attribute hacking. This one is inherited in other + // other interaction pair ? typename T::SPtr obj = sofa::core::objectmodel::New(); if (context) diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionProjectiveConstraintSet.h b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionProjectiveConstraintSet.h index 3547b05f9da..c36be2c86e8 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionProjectiveConstraintSet.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionProjectiveConstraintSet.h @@ -146,6 +146,10 @@ class PairInteractionProjectiveConstraintSet : public BaseInteractionProjectiveC template static typename T::SPtr create(T* /*p0*/, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) { + // TODO(dmarchal, 08/01/2025): Update the create function to the new factory creation process. + // use parse/init instead of creative use of attribute hacking. This one is inherited in other + // other interaction pair ? + typename T::SPtr obj = sofa::core::objectmodel::New(); if (context)