src/driver.cpp
branchnoai
changeset 9869 6404afe43575
parent 9724 b39bc69bb2f2
child 10455 22c441f5adf9
equal deleted inserted replaced
9868:3998f2e73dda 9869:6404afe43575
    51 int GetDriverParamInt(const char* const* parm, const char* name, int def)
    51 int GetDriverParamInt(const char* const* parm, const char* name, int def)
    52 {
    52 {
    53 	const char* p = GetDriverParam(parm, name);
    53 	const char* p = GetDriverParam(parm, name);
    54 	return p != NULL ? atoi(p) : def;
    54 	return p != NULL ? atoi(p) : def;
    55 }
    55 }
       
    56 
       
    57 /**
       
    58  * Find the requested driver and return its class.
       
    59  * @param name the driver to select.
       
    60  * @post Sets the driver so GetCurrentDriver() returns it too.
       
    61  */
       
    62 const Driver *DriverFactoryBase::SelectDriver(const char *name, Driver::Type type)
       
    63 {
       
    64 	if (GetDrivers().size() == 0) return NULL;
       
    65 
       
    66 	if (*name == '\0') {
       
    67 		/* Probe for this driver */
       
    68 		for (int priority = 10; priority >= 0; priority--) {
       
    69 			Drivers::iterator it = GetDrivers().begin();
       
    70 			for (; it != GetDrivers().end(); ++it) {
       
    71 				DriverFactoryBase *d = (*it).second;
       
    72 
       
    73 				/* Check driver type */
       
    74 				if (d->type != type) continue;
       
    75 				if (d->priority != priority) continue;
       
    76 
       
    77 				Driver *newd = d->CreateInstance();
       
    78 				const char *err = newd->Start(NULL);
       
    79 				if (err == NULL) {
       
    80 					DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name);
       
    81 					delete *GetActiveDriver(type);
       
    82 					*GetActiveDriver(type) = newd;
       
    83 					return newd;
       
    84 				}
       
    85 
       
    86 				DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
       
    87 				delete newd;
       
    88 			}
       
    89 		}
       
    90 		error("Couldn't find any suitable %s driver", GetDriverTypeName(type));
       
    91 	} else {
       
    92 		char *parm;
       
    93 		char buffer[256];
       
    94 		const char *parms[32];
       
    95 
       
    96 		/* Extract the driver name and put parameter list in parm */
       
    97 		strecpy(buffer, name, lastof(buffer));
       
    98 		parm = strchr(buffer, ':');
       
    99 		parms[0] = NULL;
       
   100 		if (parm != NULL) {
       
   101 			uint np = 0;
       
   102 			/* Tokenize the parm. */
       
   103 			do {
       
   104 				*parm++ = '\0';
       
   105 				if (np < lengthof(parms) - 1) parms[np++] = parm;
       
   106 				while (*parm != '\0' && *parm != ',') parm++;
       
   107 			} while (*parm == ',');
       
   108 			parms[np] = NULL;
       
   109 		}
       
   110 
       
   111 		/* Find this driver */
       
   112 		Drivers::iterator it = GetDrivers().begin();
       
   113 		for (; it != GetDrivers().end(); ++it) {
       
   114 			DriverFactoryBase *d = (*it).second;
       
   115 
       
   116 			/* Check driver type */
       
   117 			if (d->type != type) continue;
       
   118 
       
   119 			/* Check driver name */
       
   120 			if (strcasecmp(buffer, d->name) != 0) continue;
       
   121 
       
   122 			/* Found our driver, let's try it */
       
   123 			Driver *newd = d->CreateInstance();
       
   124 
       
   125 			const char *err = newd->Start(parms);
       
   126 			if (err != NULL) {
       
   127 				delete newd;
       
   128 				error("Unable to load driver '%s'. The error was: %s", d->name, err);
       
   129 			}
       
   130 
       
   131 			DEBUG(driver, 1, "Successfully loaded %s driver '%s'", GetDriverTypeName(type), d->name);
       
   132 			delete *GetActiveDriver(type);
       
   133 			*GetActiveDriver(type) = newd;
       
   134 			return newd;
       
   135 		}
       
   136 		error("No such %s driver: %s\n", GetDriverTypeName(type), buffer);
       
   137 	}
       
   138 }
       
   139 
       
   140 /**
       
   141  * Register a driver internally, based on its name.
       
   142  * @param name the name of the driver.
       
   143  * @note an assert() will be trigger if 2 driver with the same name try to register.
       
   144  */
       
   145 void DriverFactoryBase::RegisterDriver(const char *name, Driver::Type type, int priority)
       
   146 {
       
   147 	/* Don't register nameless Drivers */
       
   148 	if (name == NULL) return;
       
   149 
       
   150 	this->name = strdup(name);
       
   151 	this->type = type;
       
   152 	this->priority = priority;
       
   153 
       
   154 	/* Prefix the name with driver type to make it unique */
       
   155 	char buf[32];
       
   156 	strecpy(buf, GetDriverTypeName(type), lastof(buf));
       
   157 	strecpy(buf + 5, name, lastof(buf));
       
   158 
       
   159 #if !defined(NDEBUG) || defined(WITH_ASSERT)
       
   160 	/* NDEBUG disables asserts and gives a warning: unused variable 'P' */
       
   161 	std::pair<Drivers::iterator, bool> P =
       
   162 #endif /* !NDEBUG */
       
   163 	GetDrivers().insert(Drivers::value_type(buf, this));
       
   164 	assert(P.second);
       
   165 }
       
   166 
       
   167 /**
       
   168  * Build a human readable list of available drivers, grouped by type.
       
   169  */
       
   170 char *DriverFactoryBase::GetDriversInfo(char *p, const char *last)
       
   171 {
       
   172 	for (Driver::Type type = Driver::DT_BEGIN; type != Driver::DT_END; type++) {
       
   173 		p += snprintf(p, last - p, "List of %s drivers:\n", GetDriverTypeName(type));
       
   174 
       
   175 		for (int priority = 10; priority >= 0; priority--) {
       
   176 			Drivers::iterator it = GetDrivers().begin();
       
   177 			for (; it != GetDrivers().end(); it++) {
       
   178 				DriverFactoryBase *d = (*it).second;
       
   179 				if (d->type != type) continue;
       
   180 				if (d->priority != priority) continue;
       
   181 				p += snprintf(p, last - p, "%18s: %s\n", d->name, d->GetDescription());
       
   182 			}
       
   183 		}
       
   184 
       
   185 		p += snprintf(p, last - p, "\n");
       
   186 	}
       
   187 
       
   188 	return p;
       
   189 }