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); } } } }
// 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; }