Ejemplo n.º 1
0
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);
}