void GfDrivers::reload() { // Clear all. clear(); // (Re)Load robot modules from the "drivers" installed folder. std::string strDriversDirName(GfLibDir()); strDriversDirName += "drivers"; tModList* lstDriverModules = 0; const int nDriverModules = GfModInfoDir(CAR_IDENT, strDriversDirName.c_str(), 1, &lstDriverModules); if (nDriverModules <= 0 || !lstDriverModules) { GfLogFatal("Could not load any driver module from %s", strDriversDirName.c_str()); return; } // For each module found, load drivers information. tModList *pCurModule = lstDriverModules; do { pCurModule = pCurModule->next; // Determine the module name. std::string strModName(pCurModule->sopath); strModName.erase(strlen(pCurModule->sopath) - strlen(DLLEXT) - 1); // Truncate file ext. const size_t nLastSlashInd = strModName.rfind('/'); if (nLastSlashInd != std::string::npos) strModName = strModName.substr(nLastSlashInd+1); // Remove heading folder path. // Load the module XML descriptor file (try user settings first, and then installed one) std::ostringstream ossRobotFileName; ossRobotFileName << GfLocalDir() << "drivers/" << strModName << '/' << strModName << PARAMEXT; void *hparmRobot = GfParmReadFile(ossRobotFileName.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_REREAD); if (!hparmRobot) { ossRobotFileName.str(""); ossRobotFileName << "drivers/" << strModName << '/' << strModName << PARAMEXT; hparmRobot = GfParmReadFile(ossRobotFileName.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_REREAD); } if (!hparmRobot) { // Do not waste log with drivers that do not exists or do not have to exist! if (strncmp("dandroid",strModName.c_str(),8) == 0) continue; else if (strncmp("usr",strModName.c_str(),3) == 0) continue; else if (strncmp("replay",strModName.c_str(),6) == 0) continue; GfLogError("No usable '%s' driver (%s.xml not found or not readable)\n", strModName.c_str(), strModName.c_str()); continue; } // For each driver (= interface) "in" the module for (int nItfInd = 0; nItfInd < pCurModule->modInfoSize; nItfInd++) { // Ignore undefined drivers or showing an empty name if (!pCurModule->modInfo[nItfInd].name || pCurModule->modInfo[nItfInd].name[0] == '\0') { GfLogInfo("Ignoring '%s' driver #%d (not defined or empty name)\n", strModName.c_str(), nItfInd); continue; } // Create the driver and load info from the XML file. GfDriver* pDriver = new GfDriver(strModName, pCurModule->modInfo[nItfInd].index, pCurModule->modInfo[nItfInd].name, hparmRobot); // For human drivers, if the car was not found, select the 1st possible one. if (!pDriver->getCar() && pDriver->isHuman()) { GfCar* pSubstCar = GfCars::self()->getCarsInCategory()[0]; // Should never fail. if (pSubstCar) { std::ostringstream ossDrvSecPath; ossDrvSecPath << ROB_SECT_ROBOTS << '/' << ROB_LIST_INDEX << '/' << pCurModule->modInfo[nItfInd].index; const char* pszCarId = GfParmGetStr(hparmRobot, ossDrvSecPath.str().c_str(), ROB_ATTR_CAR, ""); GfLogWarning("Changing '%s' driver '%s' (#%d) 's car to %s (default one '%s' not available)\n", strModName.c_str(), pCurModule->modInfo[nItfInd].name, pCurModule->modInfo[nItfInd].index, pSubstCar->getId().c_str(), pszCarId); pDriver->setCar(pSubstCar); } } // Keep the driver only if he drives an existing car. if (pDriver->getCar()) { // Update the GfDrivers singleton. _pPrivate->vecDrivers.push_back(pDriver); const std::pair<std::string, int> driverKey(pDriver->getModuleName(), pDriver->getInterfaceIndex()); _pPrivate->mapDriversByKey[driverKey] = pDriver; if (std::find(_pPrivate->vecTypes.begin(), _pPrivate->vecTypes.end(), pDriver->getType()) == _pPrivate->vecTypes.end()) _pPrivate->vecTypes.push_back(pDriver->getType()); if (std::find(_pPrivate->vecCarCategoryIds.begin(), _pPrivate->vecCarCategoryIds.end(), pDriver->getCar()->getCategoryId()) == _pPrivate->vecCarCategoryIds.end()) _pPrivate->vecCarCategoryIds.push_back(pDriver->getCar()->getCategoryId()); } else { delete pDriver; std::ostringstream ossDrvSecPath; ossDrvSecPath << ROB_SECT_ROBOTS << '/' << ROB_LIST_INDEX << '/' << pCurModule->modInfo[nItfInd].index; const char* pszCarId = GfParmGetStr(hparmRobot, ossDrvSecPath.str().c_str(), ROB_ATTR_CAR, ""); GfLogInfo("Ignoring '%s' driver '%s' (#%d) (not defined or default car '%s' not available)\n", strModName.c_str(), pCurModule->modInfo[nItfInd].name, pCurModule->modInfo[nItfInd].index, pszCarId); } } // Close driver module descriptor file if open GfParmReleaseHandle(hparmRobot); } while (pCurModule != lstDriverModules); // Free the module list. GfModFreeInfoList(&lstDriverModules); // Sort the car category ids and driver types vectors. std::sort(_pPrivate->vecCarCategoryIds.begin(), _pPrivate->vecCarCategoryIds.end()); std::sort(_pPrivate->vecTypes.begin(), _pPrivate->vecTypes.end()); // Trace what we got. print(); }
void CarSettingsMenu::onAccept(void *p) { GfCar *pCar = GfCars::self()->getCarWithName(m_strCar); NetGetNetwork()->SetCarInfo(pCar->getId().c_str()); GfuiScreenActivate(pPrevMenu); }