Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SofaCore] Add virtual getPathName function in Base #1455

Merged

Conversation

marques-bruno
Copy link
Member

@marques-bruno marques-bruno commented Aug 20, 2020

Both BaseObject and BaseNode have a getPathName function, but those can't be called from a Base ptr without dereferencing with toBaseNode / toBaseObject.


This PR:

  • builds with SUCCESS for all platforms on the CI.
  • does not generate new warnings.
  • does not generate new unit test failures.
  • does not generate new scene test failures.
  • does not break API compatibility.
  • is more than 1 week old (or has fast-merge label).

Reviewers will merge only if all these checks are true.

Both BaseObject and BaseNode have a getPathName function, but those can't be called from a Base ptr without dereferencing with toBaseNode / toBaseObject
@marques-bruno marques-bruno added the pr: status to review To notify reviewers to review this pull-request label Aug 20, 2020
@marques-bruno marques-bruno self-assigned this Aug 20, 2020
@@ -180,6 +180,9 @@ class SOFA_CORE_API Base
std::initializer_list<BaseData*> outputs);
void addOutputsToCallback(const std::string& name, std::initializer_list<BaseData*> outputs);


virtual std::string getPathName() const { return ""; }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ugly, I don't like it much but I can't put a virtual pure here since BaseContext also inherits Base, which means more than 1 final overrider for Node (inherits BaseNode & BaseContext...)

@@ -224,7 +224,7 @@ class SOFA_CORE_API BaseData : public DDGNode
/// @}

/// If we use the Data as a link and not as value directly
std::string getLinkPath() const { return parentBaseData.getPath(); }
virtual std::string getLinkPath() const { return parentBaseData.getPath(); }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has nothing to do with the PR, but I need this to be overridable for custom Data in SofaQtQuick

@damienmarchal
Copy link
Contributor

damienmarchal commented Aug 21, 2020

Hello @marques-bruno

My assumption is that, initially, Base was supposed to be more the Base class for "everything" and not only for scenegraph entries. This is why the initial design was that there is no "path" concept at this level.

My current approach to handle this kind of scenario was to implement an easing function like that:

std::string sofa::helper::objectmodel::getPathName(Base* o)
{
        BaseNode *node = dynamic_cast<BaseNode>(o);
        if(node)
            return node->getPathName();
        BaseObject *object = dynamic_cast<BaseNode>(o);
        if(object)
            return object->getPathName();
        ...
}

To avoid having if/else and dynamic cast at every call and thus easing the readability on the caller's.
But I agree with your that factoring them out in Base would make sense. Actually some refactoring of BaseNode/Node/DAGNode/BaseContext would also make sense given how hard these are interleaved and unclear to most of the developpers.

@marques-bruno
Copy link
Member Author

marques-bruno commented Aug 21, 2020

Hello @marques-bruno

My assumption is that, initially, Base was supposed to be more the Base class for "everything" and not only for scenegraph entries. This is why the initial design was that there is no "path" concept at this level.

My current approach to handle this kind of scenario was to implement an easing function like that:

std::string sofa::helper::objectmodel::getPathName(Base* o)
{
        BaseNode *node = dynamic_cast<BaseNode>(o);
        if(node)
            return node->getPathName();
        BaseObject *object = dynamic_cast<BaseNode>(o);
        if(object)
            return object->getPathName();
        ...
}

To avoid having if/else and dynamic cast at every call and thus easing the readability on the caller's.
But I agree with your that factoring them out in Base would make sense. Actually some refactoring of BaseNode/Node/DAGNode/BaseContext would also make sense given how hard these are interleaved and unclear to most of the developpers.

Let's get rid of BaseContext! ;)
More seriously, I was also using easing functions before, but I noticed that I was often just duplicating the code whenever I needed it, and felt like having it in Base made more sense, but I must say that I would have preferred a virtual pure method there.. your alternative (adding in SofaCore an easing function in the sofa::core::objectmodel or sofa::helper::objectmodel scope) makes sense to me, solves the problem of having an extra function to override when inheriting Base.
Do you know if there is an improvement in perfs when using toBaseNode() / toBaseObject() instead of a dynamic_cast here?

I would not bet too much on performance improvement without making small benchmark. But in a function that basically returns strings build by concatenating ... I would say this is probably very small.

In addition it has to be noted that using a getPathName() explingn function with if/else has a linear complexity in the amount of possible types (number of if/else) while a virtual getPathName in Base has a constant cost. But again...the calling costs is probably very small compared to what the function actually do :)

damienmarchal added a commit to CRIStAL-PADR/sofa that referenced this pull request Aug 25, 2020
@hugtalbot hugtalbot added enhancement About a possible enhancement pr: status ready Approved a pull-request, ready to be squashed and removed pr: status to review To notify reviewers to review this pull-request labels Aug 26, 2020
@damienmarchal
Copy link
Contributor

[ci-build]

@damienmarchal damienmarchal merged commit d67e93c into sofa-framework:master Aug 26, 2020
@damienmarchal damienmarchal deleted the virtual_getPathName branch August 26, 2020 21:20
@guparan guparan added this to the v20.12 milestone Nov 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement About a possible enhancement pr: status ready Approved a pull-request, ready to be squashed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants