Home › Forum › SOFA › Programming with SOFA › [SOLVED] How and where template field is parsed ?
Tagged: 64_bits, Linux_other, SOFA_1608
- This topic has 5 replies, 3 voices, and was last updated 7 years, 3 months ago by ErwanDouaille.
-
AuthorPosts
-
26 July 2017 at 15:14 #9856ErwanDouailleBlocked
As an example,
<MyTemplatedComponent template=”float” … >
I just would like to know where sofa parse the “float” string and convert it to a known sofa type.
Thanks 🙂
26 July 2017 at 17:17 #9863jnbrunetModeratorHello Erwan,
This is a good question and I think it would be a good idea to document it a little bit more since it is not that trivial to see it in the sofa’s code.
I’ve just had a quick look up and here is what I think is going on.
-
First, in one of the cpp file of your plugin’s code, you should have registered your object by calling
sofa::core::RegisterObject::add
which will create and register for you asofa::core::ObjectFactory::Creator
with the right template. Exemple:int MyTemplatedComponentClass = sofa::core::RegisterObject("My templated component description") .add< MyTemplatedComponent<sofa::defaulttype::Vec3dTypes> >(true) ;
The add function should be called for every templates your component needs to make available to the simulation.
Note that the add function can take a boolean argument to make the given template the default template in case you did not specify it in the scene’s xml node.
To get to right template name, the
sofa::core::RegisterObject::add
function will call your object’sMyTemplatedComponent::templateName
function which, if it is not overridden, will callsofa::core::objectmodel::Base::templateName
function (that your object’s class should inherit). This will in turn simply callBaseClass::decodeTemplateName(typeid(MyTemplatedComponent<Vec3dTypes>))
to get the templates. -
At this point, there is an object creator registered for your object with the available templates. Next, the
sofa::simulation:Simulation
loads the scene and parse the xml of each node withsofa::simulation::xml::ObjectElement
.The
sofa::core::ObjectFactory
will be called to create the object by finding the rightObjectCreator
that you usually will have declared in the first step. To do so, it will try to get thetemplate
xml attribute. If it is not found, it will get the default template of your object (passed with the boolean argument of the add function in the first step). You can look at sofa/core/ObjectFactory.cpp:115 (ObjectFactory::createObject
function) for more information about this. -
Finally, once the right
sofa::core::ObjectCreator
(which should be of typesofa::core::ObjectCreator<MyTemplatedComponent<sofa::defaulttype::Vec3dTypes>>
is created, the creator will call your component’s functionMyTemplatedComponent<sofa::defaulttype::Vec3dTypes>::create
, which again should simply inherits thesofa::core::objectmodel::Base::create
function to complete the component creation.
Let me know if this is still not very clear, I’ll try to detail it a little bit more.
Edit: formating
27 July 2017 at 11:30 #9867ErwanDouailleBlockedThanks for your answer.
Your answer is clear and some parts should be added to the sofa documentation.
But I need more details for the second part. As an exemple, I register a std::string template. But when I try to create an object with template=”std::string” it doesn’t works because the std::string template is named “<__cxx11basic_string<char, char_traits<char>, allocator<char> > >>”.
Do you know where it converts a type to a string aka templateName in ObjectFactory ?
27 July 2017 at 14:13 #9868VincentBlockedHi Erwan,
If you want to add a template that does not already exist in SOFA, you also need to give it a name with the Name() function that returns the string you will use in your scene. For example:
template<> inline const char* Vec3fTypes::Name() { return "Vec3f"; }
In this case, the
Vec3fTypes
is a specific typedef for another more general template, juste likestd::string
with the<__cxx11basic_string<char, char_traits<char>, allocator<char> > >>
. This particular example can be found in sofa/defaulttype/VecTypes.h. It is also possible to define an alias for a particular template, as can be seen in sofa/defaulttype/TemplateAliases.cpp.To summarize, you can define your template name with something like
template<> inline const char* std::string::Name() { return "String"; }
and if you want to be able to write it differently,
RegisterTemplateAlias StringAlias("str", "String");
Cheers,
Vincent27 July 2017 at 20:33 #9871jnbrunetModeratorJust to add a little bit to Vincent’s answer.
The
BaseClass::decodeTemplateName
will use the abi to demangle the type name of your class and then parse what is between the first ‘<‘ and the last ‘>’. The type name of your class’s template is obtained through thestd::string::Name()
function which you will need to define.If you want to assign
std::string
instead of the demangled type name of the later, you could also override the methodMyTemplatedComponent::templateName()
to return the string std::string.Something like this :
template<class T> class MyTemplatedComponent { ... template<> static std::string templateName(const MyTemplatedComponent<std::string>* ptr= NULL) { return "std::string"; } ... }
1 August 2017 at 11:59 #9892ErwanDouailleBlockedThanks @jnbrunet and @Vincent !
Your answers are well completing the documentation about templates (https://www.sofa-framework.org/community/doc/programming-with-sofa/components-api/components-and-datas/)Thanks
-
First, in one of the cpp file of your plugin’s code, you should have registered your object by calling
-
AuthorPosts
- You must be logged in to reply to this topic.