Esempio n. 1
0
/// Return the full path name of this node
std::string DAGNode::getPathName() const
{
    std::string str;
    Parents parents = getParents();
    if (!parents.empty())
    {
        // for the full path name, we arbitrarily take the first parent of the list...
        // no smarter choice without breaking the "Node" heritage
        str = parents[0]->getPathName();
        str += '/';
        str += getName();
    }

    return str;
}
Esempio n. 2
0
/// Generic object access, possibly searching up or down from the current context
///
/// Note that the template wrapper method should generally be used to have the correct return type,
void* DAGNode::getObject(const sofa::core::objectmodel::ClassInfo& class_info, const sofa::core::objectmodel::TagSet& tags, SearchDirection dir) const
{
    if (dir == SearchRoot)
    {
        if (!getParents().empty()) return getRootContext()->getObject(class_info, tags, dir);
        else dir = SearchDown; // we are the root, search down from here.
    }
    void *result = NULL;
#ifdef DEBUG_GETOBJECT
    std::string cname = class_info.name();
    if (cname != std::string("N4sofa4core6ShaderE"))
        std::cout << "DAGNode: search for object of type " << class_info.name() << std::endl;
    std::string gname = "N4sofa9component8topology32TetrahedronSetGeometryAlgorithms";
    bool isg = cname.length() >= gname.length() && std::string(cname, 0, gname.length()) == gname;
#endif
    if (dir != SearchParents)
        for (ObjectIterator it = this->object.begin(); it != this->object.end(); ++it)
        {
            core::objectmodel::BaseObject* obj = it->get();
            if (tags.empty() || (obj)->getTags().includes(tags))
            {
#ifdef DEBUG_GETOBJECT
                if (isg)
                    std::cout << "DAGNode: testing object " << (obj)->getName() << " of type " << (obj)->getClassName() << std::endl;
#endif
                result = class_info.dynamicCast(obj);
                if (result != NULL)
                {
#ifdef DEBUG_GETOBJECT
                    std::cout << "DAGNode: found object " << (obj)->getName() << " of type " << (obj)->getClassName() << std::endl;
#endif
                    break;
                }
            }
        }

    if (result == NULL)
    {
        switch(dir)
        {
        case Local:
            break;
        case SearchParents:
        case SearchUp:
        {
            Parents parents = getParents();
            if (!parents.empty())
                for (Parents::iterator it = parents.begin(); it!=parents.end() && !result; it++)
                    result = dynamic_cast<Node*>(*it)->getObject(class_info, tags, SearchUp);
        }
        break;
        case SearchDown:
            for(ChildIterator it = child.begin(); it != child.end(); ++it)
            {
                result = (*it)->getObject(class_info, tags, dir);
                if (result != NULL) break;
            }
            break;
        case SearchRoot:
            std::cerr << "SearchRoot SHOULD NOT BE POSSIBLE HERE!\n";
            break;
        }
    }

    return result;
}
Esempio n. 3
0
/// Generic object access, given a path from the current context
///
/// Note that the template wrapper method should generally be used to have the correct return type,
void* DAGNode::getObject(const sofa::core::objectmodel::ClassInfo& class_info, const std::string& path) const
{
    if (path.empty())
    {
        // local object
        return Node::getObject(class_info, Local);
    }
    else if (path[0] == '/')
    {
        // absolute path; let's start from root
        Parents parents = getParents();
        if (parents.empty()) return getObject(class_info,std::string(path,1));
        else return getRootContext()->getObject(class_info,path);
    }
    else if (std::string(path,0,2)==std::string("./"))
    {
        std::string newpath = std::string(path, 2);
        while (!newpath.empty() && path[0] == '/')
            newpath.erase(0);
        return getObject(class_info,newpath);
    }
    else if (std::string(path,0,3)==std::string("../"))
    {
        // tricky case:
        // let's test EACH parent and return the first object found (if any)
        std::string newpath = std::string(path, 3);
        while (!newpath.empty() && path[0] == '/')
            newpath.erase(0);
        Parents parents = getParents();
        if (!parents.empty())
        {
            for (Parents::iterator it = parents.begin(); it!=parents.end(); it++)
            {
                void* obj = dynamic_cast<Node*>(*it)->getObject(class_info,newpath);
                if (obj) return obj;
            }
            return 0;   // not found in any parent node at all
        }
        else return getObject(class_info,newpath);
    }
    else
    {
        std::string::size_type pend = path.find('/');
        if (pend == std::string::npos) pend = path.length();
        std::string name ( path, 0, pend );
        Node* child = getChild(name);
        if (child)
        {
            while (pend < path.length() && path[pend] == '/')
                ++pend;
            return child->getObject(class_info, std::string(path, pend));
        }
        else if (pend < path.length())
        {
            //std::cerr << "ERROR: child node "<<name<<" not found in "<<getPathName()<<std::endl;
            return NULL;
        }
        else
        {
            core::objectmodel::BaseObject* obj = simulation::Node::getObject(name);
            if (obj == NULL)
            {
                //std::cerr << "ERROR: object "<<name<<" not found in "<<getPathName()<<std::endl;
                return NULL;
            }
            else
            {
                void* result = class_info.dynamicCast(obj);
                if (result == NULL)
                {
                    std::cerr << "ERROR: object "<<name<<" in "<<getPathName()<<" does not implement class "<<class_info.name()<<std::endl;
                    return NULL;
                }
                else
                {
                    return result;
                }
            }
        }
    }
}
Esempio n. 4
0
void* Node::findLinkDestClass(const core::objectmodel::BaseClass* destType, const std::string& path, const core::objectmodel::BaseLink* link)
{
    std::string pathStr;
    if (link)
    {
        if (!link->parseString(path,&pathStr))
            return NULL;
    }
    else
    {
        if (!BaseLink::ParseString(path,&pathStr,NULL,this))
            return NULL;
    }
#ifdef DEBUG_LINK
    std::cout << "LINK: Looking for " << destType->className << "<" << destType->templateName << "> " << pathStr << " from Node " << getName() << std::endl;
#endif
    std::size_t ppos = 0;
    std::size_t psize = pathStr.size();
    if (ppos == psize || (ppos == psize-2 && pathStr[ppos] == '[' && pathStr[ppos+1] == ']')) // self-reference
    {
#ifdef DEBUG_LINK
        std::cout << "  self-reference link." << std::endl;
#endif
        if (!link || !link->getOwnerBase()) return destType->dynamicCast(this);
        return destType->dynamicCast(link->getOwnerBase());
    }
    Node* node = this;
    BaseObject* master = NULL;
    bool based = false;
    if (ppos < psize && pathStr[ppos] == '[') // relative index in the list of objects
    {
        if (pathStr[psize-1] != ']')
        {
            serr << "Invalid index-based path \"" << path << "\"" << sendl;
            return NULL;
        }
        int index = atoi(pathStr.c_str()+ppos+1);
#ifdef DEBUG_LINK
        std::cout << "  index-based path to " << index << std::endl;
#endif
        ObjectReverseIterator it = object.rbegin();
        ObjectReverseIterator itend = object.rend();
        if (link && link->getOwnerBase())
        {
            // index from last
            Base* b = link->getOwnerBase();
            while (it != itend && *it != b)
                ++it;
        }
        while (it != itend && index < 0)
        {
            ++it;
            ++index;
        }
        if (it == itend)
            return NULL;
#ifdef DEBUG_LINK
        std::cout << "  found " << it->get()->getTypeName() << " " << it->get()->getName() << "." << std::endl;
#endif
        return destType->dynamicCast(it->get());
    }
    else if (ppos < psize && pathStr[ppos] == '/') // absolute path
    {
#ifdef DEBUG_LINK
        std::cout << "  absolute path" << std::endl;
#endif
        node = dynamic_cast<Node*>(this->getRoot());
        if (!node) return NULL;
        ++ppos;
        based = true;
    }
    while(ppos < psize)
    {
        if ((ppos+1 < psize && pathStr.substr(ppos,2) == "./")
                || pathStr.substr(ppos) == ".")
        {
            // this must be this node
#ifdef DEBUG_LINK
            std::cout << "  to current node" << std::endl;
#endif
            ppos += 2;
            based = true;
        }
        else if ((ppos+2 < psize && pathStr.substr(ppos,3) == "../") // relative
                 || pathStr.substr(ppos) == "..")
        {
            ppos += 3;
            if (master)
            {
                master = master->getMaster();
#ifdef DEBUG_LINK
                std::cout << "  to master object " << master->getName() << std::endl;
#endif
            }
            else
            {
                Parents parents = node->getParents();
                if (parents.empty()) return NULL;
                node = dynamic_cast<Node*>(parents[0]); // TODO: explore other parents
                if (!node) return NULL;
#ifdef DEBUG_LINK
                std::cout << "  to parent node " << node->getName() << std::endl;
#endif
            }
            based = true;
        }
        else if (pathStr[ppos] == '/')
        {
            // extra /
#ifdef DEBUG_LINK
            std::cout << "  extra '/'" << std::endl;
#endif
            ppos += 1;
        }
        else
        {
            std::size_t p2pos = pathStr.find('/',ppos);
            if (p2pos == std::string::npos) p2pos = psize;
            std::string name = pathStr.substr(ppos,p2pos-ppos);
            ppos = p2pos+1;
            if (master)
            {
#ifdef DEBUG_LINK
                std::cout << "  to slave object " << name << std::endl;
#endif
                master = master->getSlave(name);
                if (!master) return NULL;
            }
            else
            {
                for (;;)
                {
                    BaseObject* obj = node->getObject(name);
                    Node* child = node->getChild(name);
                    if (child)
                    {
                        node = child;
#ifdef DEBUG_LINK
                        std::cout << "  to child node " << name << std::endl;
#endif
                        break;
                    }
                    else if (obj)
                    {
                        master = obj;
#ifdef DEBUG_LINK
                        std::cout << "  to object " << name << std::endl;
#endif
                        break;
                    }
                    if (based) return NULL;
                    // this can still be found from an ancestor node
                    Parents parents = node->getParents();
                    if (parents.empty()) return NULL;
                    node = dynamic_cast<Node*>(parents[0]); // TODO: explore other parents
                    if (!node) return NULL;
#ifdef DEBUG_LINK
                    std::cout << "  looking in ancestor node " << node->getName() << std::endl;
#endif
                }
            }
            based = true;
        }
    }
    if (master)
    {
#ifdef DEBUG_LINK
        std::cout << "  found " << master->getTypeName() << " " << master->getName() << "." << std::endl;
#endif
        return destType->dynamicCast(master);
    }
    else
    {
        void* r = destType->dynamicCast(node);
        if (r)
        {
#ifdef DEBUG_LINK
            std::cout << "  found node " << node->getName() << "." << std::endl;
#endif
            return r;
        }
        for (ObjectIterator it = node->object.begin(), itend = node->object.end(); it != itend; ++it)
        {
            BaseObject* obj = it->get();
            void *o = destType->dynamicCast(obj);
            if (!o) continue;
#ifdef DEBUG_LINK
            std::cout << "  found " << obj->getTypeName() << " " << obj->getName() << "." << std::endl;
#endif
            if (!r) r = o;
            else return NULL; // 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->getMeshTopology());
        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 NULL;
    }
}