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

[Core] No longer support links to Node in Links #5223

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 35 additions & 28 deletions Sofa/framework/Core/src/sofa/core/Mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,41 +191,48 @@ class Mapping : public BaseMapping
template<class T>
static bool canCreate(T*& obj, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg)
{
State<In>* stin = nullptr;
State<Out>* stout = nullptr;

std::string inPath, outPath;

if (arg->getAttribute("input"))
inPath = arg->getAttribute("input");
else
inPath = "@../";

context->findLinkDest(stin, inPath, nullptr);

if (arg->getAttribute("output"))
outPath = arg->getAttribute("output");
else
outPath = "@./";

context->findLinkDest(stout, outPath, nullptr);

if (stin == nullptr)
const auto checkLink = [&arg, context]<class StateType>(
const std::string& linkName, State<StateType>*& state)
{
arg->logError("Data attribute 'input' does not point to a mechanical state of data type '"+std::string(In::Name())+"' and none can be found in the parent node context.");
const std::string path = arg->getAttribute(linkName, "");

if (path.empty())
{
arg->logError(
"The '" + linkName +
"' data attribute is empty. It should contain a valid path "
"to a mechanical state of type '" + std::string(StateType::Name()) + "'.");
return false;
}

context->findLinkDest(state, path, nullptr);

if (state == nullptr)
{
arg->logError(
"Data attribute '" + linkName +
"' does not point to a mechanical state of data type '" +
std::string(StateType::Name()) + "'.");
return false;
}

return true;
};

State<In>* stateIn = nullptr;
if (!checkLink("input", stateIn))
return false;
}

if (stout == nullptr)
{
arg->logError("Data attribute 'output' does not point to a mechanical state of data type '"+std::string(Out::Name())+"' and none can be found in the parent node context.");
State<In>* stateOut = nullptr;
if (!checkLink("output", stateOut))
return false;
}

if (dynamic_cast<BaseObject*>(stin) == dynamic_cast<BaseObject*>(stout))
if (dynamic_cast<BaseObject*>(stateIn) == dynamic_cast<BaseObject*>(stateOut))
{
// we should refuse to create mappings with the same input and output model, which may happen if a State object is missing in the child node
arg->logError("Both the input and the output point to the same mechanical state ('"+stin->getName()+"').");
arg->logError(
"Both the input and the output point to the same mechanical state ('"
+ stateIn->getName() + "').");
return false;
}

Expand Down
74 changes: 1 addition & 73 deletions Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ Node::Node(const std::string& name)
{
_context = this;
setName(name);
f_printLog.setValue(DEBUG_LINK);
}


Expand Down Expand Up @@ -402,16 +401,10 @@ sofa::core::objectmodel::Base* Node::findLinkDestClass(const core::objectmodel::
return nullptr;
}

if(DEBUG_LINK)
dmsg_info() << "LINK: Looking for " << destType->className << "<" << destType->templateName << "> " << pathStr << " from Node " << getName() ;

std::size_t ppos = 0;
const std::size_t psize = pathStr.size();
if (ppos == psize || (ppos == psize-2 && pathStr[ppos] == '[' && pathStr[ppos+1] == ']')) // self-reference
{
if(DEBUG_LINK)
dmsg_info() << " self-reference link." ;

if (!link || !link->getOwnerBase()) return destType->dynamicCast(this);
return destType->dynamicCast(link->getOwnerBase());
}
Expand All @@ -427,9 +420,6 @@ sofa::core::objectmodel::Base* Node::findLinkDestClass(const core::objectmodel::
}
int index = atoi(pathStr.c_str()+ppos+1);

if(DEBUG_LINK)
dmsg_info() << " index-based path to " << index ;

ObjectReverseIterator it = object.rbegin();
const ObjectReverseIterator itend = object.rend();
if (link && link->getOwnerBase())
Expand All @@ -447,15 +437,10 @@ sofa::core::objectmodel::Base* Node::findLinkDestClass(const core::objectmodel::
if (it == itend)
return nullptr;

if(DEBUG_LINK)
dmsg_info() << " found " << it->get()->getTypeName() << " " << it->get()->getName() << "." ;

return destType->dynamicCast(it->get());
}
else if (ppos < psize && pathStr[ppos] == '/') // absolute path
{
if(DEBUG_LINK)
dmsg_info() << " absolute path" ;
BaseNode* basenode = this->getRoot();
if (!basenode) return nullptr;
node = down_cast<Node>(basenode);
Expand All @@ -468,9 +453,6 @@ sofa::core::objectmodel::Base* Node::findLinkDestClass(const core::objectmodel::
|| pathStr.substr(ppos) == ".")
{
// this must be this node
if(DEBUG_LINK)
dmsg_info() << " to current node" ;

ppos += 2;
based = true;
}
Expand All @@ -481,24 +463,18 @@ sofa::core::objectmodel::Base* Node::findLinkDestClass(const core::objectmodel::
if (master)
{
master = master->getMaster();
if(DEBUG_LINK)
dmsg_info() << " to master object " << master->getName() ;
}
else
{
core::objectmodel::BaseNode* firstParent = node->getFirstParent();
if (!firstParent) return nullptr;
node = static_cast<Node*>(firstParent); // TODO: explore other parents
if(DEBUG_LINK)
dmsg_info() << " to parent node " << node->getName() ;
}
based = true;
}
else if (pathStr[ppos] == '/')
{
// extra /
if(DEBUG_LINK)
dmsg_info() << " extra '/'" ;
ppos += 1;
}
else
Expand All @@ -509,8 +485,6 @@ sofa::core::objectmodel::Base* Node::findLinkDestClass(const core::objectmodel::
ppos = p2pos+1;
if (master)
{
if(DEBUG_LINK)
dmsg_info() << " to slave object " << name ;
master = master->getSlave(name);
if (!master) return nullptr;
}
Expand All @@ -523,75 +497,29 @@ sofa::core::objectmodel::Base* Node::findLinkDestClass(const core::objectmodel::
if (child)
{
node = child;
if(DEBUG_LINK)
dmsg_info() << " to child node " << name ;
break;
}
else if (obj)
{
master = obj;
if(DEBUG_LINK)
dmsg_info() << " to object " << name ;
break;
}
if (based) return nullptr;
// this can still be found from an ancestor node
core::objectmodel::BaseNode* firstParent = node->getFirstParent();
if (!firstParent) return nullptr;
node = static_cast<Node*>(firstParent); // TODO: explore other parents
if(DEBUG_LINK)
dmsg_info() << " looking in ancestor node " << node->getName() ;
}
}
based = true;
}
}
if (master)
{
if(DEBUG_LINK)
dmsg_info() << " found " << master->getTypeName() << " " << master->getName() << "." ;
return destType->dynamicCast(master);
}
else
{
Base* r = destType->dynamicCast(node);
if (r)
{
if(DEBUG_LINK)
dmsg_info() << " found node " << node->getName() << "." ;
return r;
}
for (ObjectIterator it = node->object.begin(), itend = node->object.end(); it != itend; ++it)
{
BaseObject* obj = it->get();
Base *o = destType->dynamicCast(obj);
if (!o) continue;
if(DEBUG_LINK)
dmsg_info() << " found " << obj->getTypeName() << " " << obj->getName() << "." ;
if (!r) r = o;
else return nullptr; // several objects are possible, this is an ambiguous path
}
if (r) return r;
// no object found, we look in parent nodes if the searched class is one of the known standard single components (state, topology, ...)
if (destType->hasParent(sofa::core::BaseState::GetClass()))
return destType->dynamicCast(node->getState());
else if (destType->hasParent(core::topology::BaseMeshTopology::GetClass()))
return destType->dynamicCast(node->getMeshTopologyLink());
else if (destType->hasParent(core::topology::Topology::GetClass()))
return destType->dynamicCast(node->getTopology());
else if (destType->hasParent(core::visual::Shader::GetClass()))
return destType->dynamicCast(node->getShader());
else if (destType->hasParent(core::behavior::BaseAnimationLoop::GetClass()))
return destType->dynamicCast(node->getAnimationLoop());
else if (destType->hasParent(core::behavior::OdeSolver::GetClass()))
return destType->dynamicCast(node->getOdeSolver());
else if (destType->hasParent(core::collision::Pipeline::GetClass()))
return destType->dynamicCast(node->getCollisionPipeline());
else if (destType->hasParent(core::visual::VisualLoop::GetClass()))
return destType->dynamicCast(node->getVisualLoop());

return nullptr;
}
return destType->dynamicCast(node);
}

/// Add an object. Detect the implemented interfaces and add the object to the corresponding lists.
Expand Down
Loading