@@ -38,33 +38,34 @@ namespace sofa::helper::system
3838namespace sofa ::core
3939{
4040
41+ class ObjectRegistrationData ;
42+
43+ typedef std::function<void (sofa::core::objectmodel::Base*, sofa::core::objectmodel::BaseObjectDescription*)> OnCreateCallback ;
44+
4145/* *
4246 * \brief Main class used to register and dynamically create objects
4347 *
44- * It uses the Factory design pattern, where each class is registered in a map,
48+ * It uses the Factory design pattern, where each class is registered in a map
4549 * and dynamically retrieved given the type name.
4650 *
47- * It also stores metainformation on each classes , such as description,
51+ * It also stores metainformation on each class , such as description,
4852 * authors, license, and available template types.
49- *
50- * \see RegisterObject for how new classes should be registered.
51- *
5253 */
53-
54- class ObjectRegistrationData ;
55-
56- typedef std::function<void (sofa::core::objectmodel::Base*, sofa::core::objectmodel::BaseObjectDescription*)> OnCreateCallback ;
5754class SOFA_CORE_API ObjectFactory
5855{
5956public:
6057
61- // / Abstract interface of objects used to create instances of a given type
62- class Creator
58+ /* *
59+ * Abstract interface used to create instances (object) of a given type
60+ * See the derived class @ref ObjectCreator.
61+ */
62+ class SOFA_CORE_API BaseObjectCreator
6363 {
6464 public:
65- typedef std::shared_ptr<Creator> SPtr;
65+ using SPtr = std::shared_ptr<BaseObjectCreator>;
66+
67+ virtual ~BaseObjectCreator () = default ;
6668
67- virtual ~Creator () { }
6869 // / Pre-construction check.
6970 // /
7071 // / \return true if the object can be created successfully.
@@ -75,24 +76,31 @@ class SOFA_CORE_API ObjectFactory
7576 // / \pre canCreate(context, arg) == true.
7677 virtual objectmodel::BaseObject::SPtr createInstance (objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg) = 0;
7778
78- // / type_info structure associated with the type of intanciated objects.
79+ // / type_info structure associated with the type of instantiated objects.
7980 virtual const std::type_info& type () = 0;
8081
81- // / BaseClass structure associated with the type of intanciated objects.
82+ // / BaseClass structure associated with the type of instantiated objects.
8283 virtual const objectmodel::BaseClass* getClass () = 0;
8384
8485 // / The name of the library or executable containing the binary code for this component
8586 virtual const char * getTarget () = 0;
8687
8788 virtual const char * getHeaderFileLocation () = 0;
8889 };
89- typedef std::map<std::string, Creator::SPtr> CreatorMap;
90+ using Creator SOFA_CORE_DEPRECATED_RENAME_CREATOR_BASEOBJECTCREATOR () = BaseObjectCreator;
91+
92+ using TemplateName = std::string;
93+
94+ // / For a given templated class, the map stores all creators and the key is the template name.
95+ using ObjectTemplateCreatorMap = std::map<TemplateName, BaseObjectCreator::SPtr>;
96+
97+ using CreatorMap SOFA_CORE_DEPRECATED_RENAME_CREATORMAP_OBJECTTEMPLATECREATORMAP () = ObjectTemplateCreatorMap;
9098
9199 // / Record storing information about a class
92100 class ClassEntry
93101 {
94102 public:
95- typedef std::shared_ptr<ClassEntry> SPtr ;
103+ using SPtr = std::shared_ptr<ClassEntry>;
96104
97105 std::string className;
98106 std::set<std::string> aliases;
@@ -101,14 +109,20 @@ class SOFA_CORE_API ObjectFactory
101109 std::string license;
102110 std::string documentationURL;
103111 std::string defaultTemplate;
104- CreatorMap creatorMap;
112+ ObjectTemplateCreatorMap creatorMap; // to create instances of the class for different templates
105113 std::map<std::string, std::vector<std::string>> m_dataAlias ;
106114 };
107- typedef std::map<std::string, ClassEntry::SPtr> ClassEntryMap;
115+
116+ using ClassName = std::string;
117+
118+ // / Map to store all class entries, key is the class name.
119+ using ClassEntryMap = std::map<ClassName, ClassEntry::SPtr>;
108120
109121protected:
110- // / Main class registry
122+
123+ // / Main registry of all classes
111124 ClassEntryMap registry;
125+
112126 OnCreateCallback m_callbackOnCreate ;
113127
114128 // / Keep track of plugins who already registered
@@ -217,20 +231,24 @@ template<class BaseClass>
217231void ObjectFactory::getEntriesDerivedFrom (std::vector<ClassEntry::SPtr>& result) const
218232{
219233 result.clear ();
220- for (const auto & r : registry)
234+ for (const auto & [mapKeyClassName, entryInRegistry] : registry)
221235 {
222- ClassEntry::SPtr entry = r. second ;
223- // Push the entry only if it is not an alias
224- if (entry ->className == r. first )
236+ // Discard the entry if its class name is not consistent with its key in the map.
237+ // Differences happen for class aliases.
238+ if (entryInRegistry ->className == mapKeyClassName )
225239 {
226- const auto creatorEntry = entry->creatorMap .begin ();
227- if (creatorEntry != entry->creatorMap .end ())
228- {
229- const auto * baseClass = creatorEntry->second ->getClass ();
230- if (baseClass && baseClass->hasParent (BaseClass::GetClass ()))
240+ const auto & templateCreators = entryInRegistry->creatorMap ;
241+ const auto isAnyInstantiationDerived = std::any_of (templateCreators.begin (), templateCreators.end (),
242+ [](const auto & it)
231243 {
232- result.push_back (entry);
233- }
244+ const auto & templateInstantiation = it.second ;
245+ const auto * instantiationClass = templateInstantiation->getClass ();
246+ return instantiationClass
247+ && instantiationClass->hasParent (BaseClass::GetClass ());
248+ });
249+ if (isAnyInstantiationDerived) // at least one template instantiation of the class is derived from BaseClass
250+ {
251+ result.push_back (entryInRegistry);
234252 }
235253 }
236254 }
@@ -241,21 +259,16 @@ std::string ObjectFactory::listClassesDerivedFrom(const std::string& separator)
241259{
242260 std::vector<ClassEntry::SPtr> entries;
243261 getEntriesDerivedFrom<BaseClass>(entries);
244- if (entries.empty ()) return std::string ();
245262
246- const auto join = [&separator](std::string a, ClassEntry::SPtr b)
247- {
248- return std::move (a) + separator + b->className ;
249- };
250- return std::accumulate (std::next (entries.begin ()), entries.end (),
251- entries.front ()->className , join);
263+ return sofa::helper::join (entries.begin (), entries.end (),
264+ [](const ClassEntry::SPtr& entry){ return entry->className ;}, separator);
252265}
253266
254267/* *
255268 * \brief Typed Creator class used to create instances of object type RealObject
256269 */
257270template <class RealObject >
258- class ObjectCreator : public ObjectFactory ::Creator
271+ class ObjectCreator : public ObjectFactory ::BaseObjectCreator
259272{
260273public:
261274 bool canCreate (objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg) override
@@ -339,7 +352,7 @@ class SOFA_CORE_API ObjectRegistrationData
339352 // /
340353 // / See the add<RealObject>() method for an easy way to add a Creator.
341354 ObjectRegistrationData& addCreator (std::string classname, std::string templatename,
342- ObjectFactory::Creator ::SPtr creator);
355+ ObjectFactory::BaseObjectCreator ::SPtr creator);
343356
344357 // / Add a template instantiation of this class.
345358 // /
@@ -398,7 +411,7 @@ class SOFA_ATTRIBUTE_DEPRECATED__REGISTEROBJECT() SOFA_CORE_API RegisterObject
398411 RegisterObject& addLicense (std::string val);
399412 RegisterObject& addDocumentationURL (std::string url);
400413 RegisterObject& addCreator (std::string classname, std::string templatename,
401- ObjectFactory::Creator ::SPtr creator);
414+ ObjectFactory::BaseObjectCreator ::SPtr creator);
402415
403416 template <class RealObject >
404417 RegisterObject& add (bool defaultTemplate = false )
0 commit comments