Esempio n. 1
0
void BaseObject::setSrc(const std::string &valueString, const BaseObject *loader, std::vector< std::string > *attributeList)
{
    BaseObject* obj = this;

    std::multimap < std::string, BaseData*> dataLoaderMap(loader->m_aliasData);
    std::multimap < std::string, BaseData*>::iterator it_map;

    //for (unsigned int j = 0; j<loader->m_fieldVec.size(); ++j)
    //{
    //	dataLoaderMap.insert (std::pair<std::string, BaseData*> (loader->m_fieldVec[j].first, loader->m_fieldVec[j].second));
    //}

    if (attributeList != 0)
    {
        for (unsigned int j = 0; j<attributeList->size(); ++j)
        {
            it_map = dataLoaderMap.find ((*attributeList)[j]);
            if (it_map != dataLoaderMap.end())
                dataLoaderMap.erase (it_map);
        }
    }

    // -- Temporary patch, using exceptions. TODO: use a flag to set Data not to be automatically linked. --
    //{
    it_map = dataLoaderMap.find ("type");
    if (it_map != dataLoaderMap.end())
        dataLoaderMap.erase (it_map);

    it_map = dataLoaderMap.find ("filename");
    if (it_map != dataLoaderMap.end())
        dataLoaderMap.erase (it_map);
    //}


    for (it_map = dataLoaderMap.begin(); it_map != dataLoaderMap.end(); ++it_map)
    {
        BaseData* data = obj->findData( (*it_map).first );
        if (data != NULL)
        {
            if (!(*it_map).second->isAutoLink())
            {
                sout << "Disabling autolink for Data " << data->getName() << sendl;
            }
            else
            {
                //serr << "Autolinking Data " << data->getName() << sendl;
                std::string linkPath = valueString+"."+(*it_map).first;
                data->setParent( (*it_map).second, linkPath);
            }
        }
    }
}
Esempio n. 2
0
// helper function for parsing Python arguments
// not defined static in order to be able to use this fcn somewhere else also
BaseData* helper_addNewData(PyObject *args, PyObject * kw, Base * obj) {

    char* dataRawType = new char;
    char* dataClass = new char;
    char* dataHelp = new char;
    char * dataName = new char;
    std::string val = "";
    
    PyObject* dataValue = nullptr;

    bool KwargsOrArgs = 0; //Args = 0, Kwargs = 1

    if(PyArg_ParseTuple(args, "s|sssO", &dataName, &dataClass, &dataHelp, &dataRawType, &dataValue))
    {
        // first argument (name) is mandatory, the rest are optionally found in the args and, if not there, in kwargs
        dataName = getStringCopy(dataName) ;

        if (strcmp(dataName,"")==0)
        {
            return nullptr;
        }

        if (dataValue==nullptr) // the content of dataValue is not set, so parsing normal args didn't succeed fully --> look for kwargs
        {
            KwargsOrArgs = 1;
        }
        else // arguments are available ...
        {
            dataClass = getStringCopy(dataClass) ;
            dataHelp  = getStringCopy(dataHelp) ;
            dataRawType  = getStringCopy(dataRawType) ;
            Py_IncRef(dataValue); // want to hold on it for a while
        }
    }
    else
    {
        return nullptr;
    }    
    BaseData* bd = nullptr;
    if(KwargsOrArgs) // parse kwargs
    {
        if(kw==nullptr || !PyDict_Check(kw) )
        {
            msg_warning("SofaPython") << "Could not parse kwargs for adding Data.";
        }
        else
        {
            PyObject * tmp;
            tmp = PyDict_GetItemString(kw,"datatype");
            if (tmp!=nullptr){
                dataRawType = getStringCopy(PyString_AsString(tmp));
            }

            tmp = PyDict_GetItemString(kw,"helptxt");
            if (tmp!=nullptr){
                dataHelp = getStringCopy(PyString_AsString(tmp));
            }

            tmp = PyDict_GetItemString(kw,"dataclass");
            if (tmp!=nullptr){
                dataClass= getStringCopy(PyString_AsString(tmp));
            }

            tmp = PyDict_GetItemString(kw,"value");
            if (tmp!=nullptr){
                dataValue = tmp;
                Py_IncRef(dataValue); // call to Py_GetItemString doesn't increment the ref count, but we want to hold on to it for a while ...
                val = std::string(PyString_AsString(dataValue));
                bd = deriveTypeFromParentValue(obj, val);
            }
        }
    }

    if (dataRawType[0]==0) // We cannot construct without a type
    {
        if (val.empty())
        {
            bd = new EmptyData;
            bd->setName(dataName);
        }
        else if (std::string(dataName) != "type")
        {
            msg_warning(obj) << "No type provided for Data " << dataName << " with value " << val << ", creating void* data.";
            return bd;
        }
        else return new EmptyData;
    }

    if (bd == nullptr)
        bd = getFactoryInstance()->createObject(dataRawType, sofa::helper::NoArgument());
    if (bd == nullptr)
    {
        if (val.empty())
        {
            bd = new EmptyData;
            bd->setName(dataName);
        }
        else if (std::string(dataName) != "type")
        {
  	        sofa::helper::vector<std::string> validTypes;
	          getFactoryInstance()->uniqueKeys(std::back_inserter(validTypes));
	          std::string typesString = "[";
	          for (const auto& i : validTypes)
	              typesString += i + ", ";
	          typesString += "\b\b]";
	          msg_error(obj) << dataRawType << " is not a known type. Available "
	                            "types are:\n" << typesString;
            return nullptr;
        }
        else return new EmptyData;
    }
    else
    {
        bd->setName(dataName);
        bd->setHelp(dataHelp);
        obj->addData(bd);
        if(dataValue!=nullptr) // parse provided data: Py->SofaStr->Data or link
        {
            std::stringstream tmp;
            pythonToSofaDataString(dataValue, tmp);
            if(tmp.str()[0]=='@' && bd->canBeLinked())
            {
                if(!bd->setParent(tmp.str()))
                {
                    msg_warning(obj) << "Could not setup link for Data, initialzing empty.";
                }
            }
            else
            {
                bd->read( tmp.str() );
            }
            bd->setGroup(dataClass);
            Py_DecRef(dataValue);
        }
    }
    return bd;
}