* Use the database-meta-language code generator to generate a new stats loading function: loadSensorStatsFromDB

* Get rid of the previous (handcrafted) version for loadSensorStatsFromDB
 * Get rid of the old `sensor` table in the database and replace it with the autogenerated `SENSOR` table

This addresses #2


git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@6327 4a71c877-e1ca-e34f-864e-861f7616d084
master
Giel van Schijndel 2008-11-16 03:52:34 +00:00
parent b918d96671
commit db0253a0d8
7 changed files with 365 additions and 154 deletions

Binary file not shown.

View File

@ -249,7 +249,7 @@ static BOOL bufferSSENSORLoad(const char *pBuffer, UDWORD size, void **ppData)
static BOOL dataDBSENSORLoad(struct sqlite3* db, const char* tableName, void **ppData)
{
if (!loadSensorStatsFromDB(db, tableName)
if (!loadSensorStatsFromDB(db)
|| !allocComponentList(COMP_SENSOR, numSensorStats))
{
return false;

View File

@ -1054,150 +1054,6 @@ in_statement_err:
return retval;
}
/** Load the Sensor stats from the given SQLite database file
* \param filename name of the database file to load the propulsion stats
* from.
*/
bool loadSensorStatsFromDB(sqlite3* db, const char* tableName)
{
bool retval = false;
sqlite3_stmt* stmt;
int rc;
SQL_COMP_BASE_STATS cols;
// Prepare this SQL statement for execution
if (!prepareStatement(db, &stmt, "SELECT MAX(id) FROM `%s`;", tableName))
return false;
/* Execute and process the results of the above SQL statement to
* determine the amount of propulsions we're about to fetch. Then make
* sure to allocate memory for that amount of propulsions. */
rc = sqlite3_step(stmt);
if (rc != SQLITE_ROW
|| sqlite3_data_count(stmt) != 1
|| !statsAllocSensor(sqlite3_column_int(stmt, 0)))
{
goto in_statement_err;
}
sqlite3_finalize(stmt);
if (!prepareStatement(db, &stmt,
"SELECT * FROM `%s`;", tableName))
return false;
if ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
if (!compBaseStatColumnNames(&cols, stmt))
goto in_statement_err;
while (rc == SQLITE_ROW)
{
SENSOR_STATS sStats, * const stats = &sStats;
const unsigned int sensor_id = sqlite3_column_int(stmt, getColNumByName(stmt, "id"));
int colnum;
const char* str;
memset(stats, 0, sizeof(*stats));
if (!loadComponentBaseStats((COMPONENT_STATS *)stats, &cols, stmt, REF_SENSOR_START + sensor_id - 1))
{
goto in_statement_err;
}
// Get the rest of the IMDs
// mountGfx TEXT, -- The turret mount to use
colnum = getColNumByName(stmt, "mountGfx");
if (sqlite3_column_type(stmt, colnum) != SQLITE_NULL)
{
stats->pMountGraphic = (iIMDShape *) resGetData("IMD", (const char*)sqlite3_column_text(stmt, colnum));
if (stats->pMountGraphic == NULL)
{
debug(LOG_ERROR, "Cannot find the mount PIE for record %s", getStatName(stats));
abort();
goto in_statement_err;
}
}
else
{
stats->pMountGraphic = NULL;
}
// range NUMERIC NOT NULL, -- Sensor range
stats->range = sqlite3_column_double(stmt, getColNumByName(stmt, "range"));
// location TEXT NOT NULL, -- specifies whether the Sensor is default or for the Turret
str = (const char*)sqlite3_column_text(stmt, getColNumByName(stmt, "location"));
if (!strcmp(str, "DEFAULT"))
{
stats->location = LOC_DEFAULT;
}
else if(!strcmp(str, "TURRET"))
{
stats->location = LOC_TURRET;
}
else
{
ASSERT(!"invalid sensor location", "Invalid sensor location");
}
// type TEXT NOT NULL, -- used for combat
str = (const char*)sqlite3_column_text(stmt, getColNumByName(stmt, "type"));
if (!strcmp(str,"STANDARD"))
{
stats->type = STANDARD_SENSOR;
}
else if (!strcmp(str, "INDIRECT CB"))
{
stats->type = INDIRECT_CB_SENSOR;
}
else if (!strcmp(str, "VTOL CB"))
{
stats->type = VTOL_CB_SENSOR;
}
else if (!strcmp(str, "VTOL INTERCEPT"))
{
stats->type = VTOL_INTERCEPT_SENSOR;
}
else if (!strcmp(str, "SUPER"))
{
stats->type = SUPER_SENSOR;
}
else
{
ASSERT(!"invalid sensor type", "Invalid sensor type");
}
// time NUMERIC NOT NULL, -- time delay before associated weapon droids 'know' where the attack is from
stats->time = sqlite3_column_double(stmt, getColNumByName(stmt, "time"));
// multiply time stats
stats->time *= WEAPON_TIME;
// power NUMERIC NOT NULL, -- Sensor power (put against ecm power)
stats->power = sqlite3_column_double(stmt, getColNumByName(stmt, "power"));
// set the max stats values for the design screen
if (stats->designable)
{
setMaxSensorRange(stats->range);
setMaxSensorPower(stats->power);
setMaxComponentWeight(stats->weight);
}
//save the stats
statsSetSensor(stats, sensor_id - 1);
// Retrieve next row
rc = sqlite3_step(stmt);
}
retval = true;
in_statement_err:
sqlite3_finalize(stmt);
return retval;
}
/** Load the ECM (Electronic Counter Measures) stats from the given SQLite
* database file
* \param filename name of the database file to load the propulsion stats

View File

@ -37,7 +37,6 @@ extern bool loadWeaponStatsFromDB(struct sqlite3* db, const char* tableName);
extern bool loadBodyStatsFromDB(struct sqlite3* db, const char* tableName);
extern bool loadBrainStatsFromDB(struct sqlite3* db, const char* tableName);
extern bool loadPropulsionStatsFromDB(struct sqlite3* db, const char* tableName);
extern bool loadSensorStatsFromDB(struct sqlite3* db, const char* tableName);
extern bool loadECMStatsFromDB(struct sqlite3* db, const char* tableName);
#endif // __INCLUDED_STATS_DB_H__

View File

@ -5,6 +5,327 @@
#line 1 "stats-db2.tpl.sql.c"
#line 7 "stats-db2.c"
/** Load the contents of the SENSOR table from the given SQLite database.
*
* @param db represents the database to load from
*
* @return true if we succesfully loaded all available rows from the table,
* false otherwise.
*/
bool
#line 220 "stats-db2.tpl"
loadSensorStatsFromDB
#line 19 "stats-db2.c"
(sqlite3* db)
{
bool retval = false;
sqlite3_stmt* stmt;
int rc;
unsigned int CUR_ROW_NUM = 0;
struct
{
int unique_inheritance_id;
int pName;
int buildPower;
int buildPoints;
int weight;
int body;
int designable;
int pIMD;
int range;
int power;
int location;
int type;
int time;
int pMountGraphic;
} cols;
{
int MAX_ID_VAR;
/* Prepare this SQL statement for execution */
if (!prepareStatement(db, &stmt, "SELECT MAX(`SENSOR`.unique_inheritance_id) FROM `BASE` INNER JOIN `COMPONENT` ON `BASE`.`unique_inheritance_id` = `COMPONENT`.`unique_inheritance_id` INNER JOIN `SENSOR` ON `COMPONENT`.`unique_inheritance_id` = `SENSOR`.`unique_inheritance_id`;"))
return false;
/* Execute and process the results of the above SQL statement */
if (sqlite3_step(stmt) != SQLITE_ROW
|| sqlite3_data_count(stmt) != 1)
goto in_statement_err;
MAX_ID_VAR = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
#line 222 "stats-db2.tpl"
if (!statsAllocSensor(MAX_ID_VAR))
return false;
#line 61 "stats-db2.c"
}
/* Prepare the query to start fetching all rows */
if (!prepareStatement(db, &stmt,
"SELECT\n"
"-- Automatically generated ID to link the inheritance hierarchy.\n"
"BASE.unique_inheritance_id,\n"
"-- Unique ID of the item\n"
"-- Unique language independant name that can be used to identify a specific\n"
"-- stats instance\n"
"`BASE`.`pName` AS `pName`,\n"
"-- Power required to build this component\n"
"`COMPONENT`.`buildPower` AS `buildPower`,\n"
"-- Build points (which are rate-limited in the construction units) required\n"
"-- to build this component.\n"
"`COMPONENT`.`buildPoints` AS `buildPoints`,\n"
"-- Weight of this component\n"
"`COMPONENT`.`weight` AS `weight`,\n"
"-- Body points of this component\n"
"`COMPONENT`.`body` AS `body`,\n"
"-- Indicates whether this component is \"designable\" and can thus be used in\n"
"-- the design screen.\n"
"`COMPONENT`.`designable` AS `designable`,\n"
"-- The \"base\" IMD model representing this component in 3D space.\n"
"`COMPONENT`.`pIMD` AS `pIMD`,\n"
"-- Sensor range.\n"
"`SENSOR`.`range` AS `range`,\n"
"-- Sensor power (put against ecm power).\n"
"`SENSOR`.`power` AS `power`,\n"
"-- specifies whether the Sensor is default or for the Turret.\n"
"`SENSOR`.`location` AS `location`,\n"
"-- used for combat\n"
"`SENSOR`.`type` AS `type`,\n"
"-- Time delay before the associated weapon droids 'know' where the attack is\n"
"-- from.\n"
"`SENSOR`.`time` AS `time`,\n"
"-- The turret mount to use.\n"
"`SENSOR`.`pMountGraphic` AS `pMountGraphic`\n"
"FROM `BASE` INNER JOIN `COMPONENT` ON `BASE`.`unique_inheritance_id` = `COMPONENT`.`unique_inheritance_id` INNER JOIN `SENSOR` ON `COMPONENT`.`unique_inheritance_id` = `SENSOR`.`unique_inheritance_id`;"))
return false;
/* Fetch the first row */
if ((rc = sqlite3_step(stmt)) != SQLITE_ROW)
{
/* Apparently we fetched no rows at all, this is a non-failure, terminal condition. */
sqlite3_finalize(stmt);
return true;
}
/* Fetch and cache column numbers */
/* BEGIN of inherited "COMPONENT" definition */
/* BEGIN of inherited "BASE" definition */
cols.unique_inheritance_id = getColNumByName(stmt, "unique_inheritance_id");
ASSERT(cols.unique_inheritance_id != -1, "Column unique_inheritance_id not found in result set!");
if (cols.unique_inheritance_id == -1)
goto in_statement_err;
cols.pName = getColNumByName(stmt, "pName");
ASSERT(cols.pName != -1, "Column pName not found in result set!");
if (cols.pName == -1)
goto in_statement_err;
/* END of inherited "BASE" definition */
cols.buildPower = getColNumByName(stmt, "buildPower");
ASSERT(cols.buildPower != -1, "Column buildPower not found in result set!");
if (cols.buildPower == -1)
goto in_statement_err;
cols.buildPoints = getColNumByName(stmt, "buildPoints");
ASSERT(cols.buildPoints != -1, "Column buildPoints not found in result set!");
if (cols.buildPoints == -1)
goto in_statement_err;
cols.weight = getColNumByName(stmt, "weight");
ASSERT(cols.weight != -1, "Column weight not found in result set!");
if (cols.weight == -1)
goto in_statement_err;
cols.body = getColNumByName(stmt, "body");
ASSERT(cols.body != -1, "Column body not found in result set!");
if (cols.body == -1)
goto in_statement_err;
cols.designable = getColNumByName(stmt, "designable");
ASSERT(cols.designable != -1, "Column designable not found in result set!");
if (cols.designable == -1)
goto in_statement_err;
cols.pIMD = getColNumByName(stmt, "pIMD");
ASSERT(cols.pIMD != -1, "Column pIMD not found in result set!");
if (cols.pIMD == -1)
goto in_statement_err;
/* END of inherited "COMPONENT" definition */
cols.range = getColNumByName(stmt, "range");
ASSERT(cols.range != -1, "Column range not found in result set!");
if (cols.range == -1)
goto in_statement_err;
cols.power = getColNumByName(stmt, "power");
ASSERT(cols.power != -1, "Column power not found in result set!");
if (cols.power == -1)
goto in_statement_err;
cols.location = getColNumByName(stmt, "location");
ASSERT(cols.location != -1, "Column location not found in result set!");
if (cols.location == -1)
goto in_statement_err;
cols.type = getColNumByName(stmt, "type");
ASSERT(cols.type != -1, "Column type not found in result set!");
if (cols.type == -1)
goto in_statement_err;
cols.time = getColNumByName(stmt, "time");
ASSERT(cols.time != -1, "Column time not found in result set!");
if (cols.time == -1)
goto in_statement_err;
cols.pMountGraphic = getColNumByName(stmt, "pMountGraphic");
ASSERT(cols.pMountGraphic != -1, "Column pMountGraphic not found in result set!");
if (cols.pMountGraphic == -1)
goto in_statement_err;
while (rc == SQLITE_ROW)
{
SENSOR_STATS sStats, * const stats = &sStats;
memset(stats, 0, sizeof(*stats));
/* BEGIN of inherited "COMPONENT" definition */
/* BEGIN of inherited "BASE" definition */
/* Unique ID of the item
*/
/* Unique language independant name that can be used to identify a specific
* stats instance
*/
stats->pName = strdup((const char*)sqlite3_column_text(stmt, cols.pName));
if (stats->pName == NULL)
{
debug(LOG_ERROR, "Out of memory");
abort();
goto in_statement_err;
}
/* END of inherited "BASE" definition */
/* Power required to build this component
*/
stats->buildPower = sqlite3_column_int(stmt, cols.buildPower);
/* Build points (which are rate-limited in the construction units) required
* to build this component.
*/
stats->buildPoints = sqlite3_column_int(stmt, cols.buildPoints);
/* Weight of this component
*/
stats->weight = sqlite3_column_int(stmt, cols.weight);
/* Body points of this component
*/
stats->body = sqlite3_column_int(stmt, cols.body);
/* Indicates whether this component is "designable" and can thus be used in
* the design screen.
*/
stats->designable = sqlite3_column_int(stmt, cols.designable) ? true : false;
/* The "base" IMD model representing this component in 3D space.
*/
if (sqlite3_column_type(stmt, cols.pIMD) != SQLITE_NULL)
{
stats->pIMD = (iIMDShape *) resGetData("IMD", (const char*)sqlite3_column_text(stmt, cols.pIMD));
}
else
{
stats->pIMD = NULL;
}
/* END of inherited "COMPONENT" definition */
/* Sensor range.
*/
stats->range = sqlite3_column_int(stmt, cols.range);
/* Sensor power (put against ecm power).
*/
stats->power = sqlite3_column_int(stmt, cols.power);
/* specifies whether the Sensor is default or for the Turret.
*/
if (strcmp((const char*)sqlite3_column_text(stmt, cols.location), "DEFAULT") == 0)
stats->location = LOC_DEFAULT;
else if (strcmp((const char*)sqlite3_column_text(stmt, cols.location), "TURRET") == 0)
stats->location = LOC_TURRET;
else
{
debug(LOG_ERROR, "Unknown enumerant (%s) for field location", (const char*)sqlite3_column_text(stmt, cols.location));
goto in_statement_err;
}
/* used for combat
*/
if (strcmp((const char*)sqlite3_column_text(stmt, cols.type), "STANDARD") == 0)
stats->type = STANDARD_SENSOR;
else if (strcmp((const char*)sqlite3_column_text(stmt, cols.type), "INDIRECT_CB") == 0
|| strcmp((const char*)sqlite3_column_text(stmt, cols.type), "INDIRECT CB") == 0)
stats->type = INDIRECT_CB_SENSOR;
else if (strcmp((const char*)sqlite3_column_text(stmt, cols.type), "VTOL_CB") == 0
|| strcmp((const char*)sqlite3_column_text(stmt, cols.type), "VTOL CB") == 0)
stats->type = VTOL_CB_SENSOR;
else if (strcmp((const char*)sqlite3_column_text(stmt, cols.type), "VTOL_INTERCEPT") == 0
|| strcmp((const char*)sqlite3_column_text(stmt, cols.type), "VTOL INTERCEPT") == 0)
stats->type = VTOL_INTERCEPT_SENSOR;
else if (strcmp((const char*)sqlite3_column_text(stmt, cols.type), "SUPER") == 0)
stats->type = SUPER_SENSOR;
else
{
debug(LOG_ERROR, "Unknown enumerant (%s) for field type", (const char*)sqlite3_column_text(stmt, cols.type));
goto in_statement_err;
}
/* Time delay before the associated weapon droids 'know' where the attack is
* from.
*/
stats->time = sqlite3_column_int(stmt, cols.time);
/* The turret mount to use.
*/
if (sqlite3_column_type(stmt, cols.pMountGraphic) != SQLITE_NULL)
{
stats->pMountGraphic = (iIMDShape *) resGetData("IMD", (const char*)sqlite3_column_text(stmt, cols.pMountGraphic));
}
else
{
stats->pMountGraphic = NULL;
}
{
#line 226 "stats-db2.tpl"
stats->ref = REF_SENSOR_START + CUR_ROW_NUM;
// save the stats
statsSetSensor(stats, CUR_ROW_NUM);
// set the max stat values for the design screen
if (stats->designable)
{
setMaxSensorRange(stats->range);
setMaxSensorPower(stats->power);
setMaxComponentWeight(stats->weight);
}
#line 314 "stats-db2.c"
}
/* Retrieve the next row */
rc = sqlite3_step(stmt);
++CUR_ROW_NUM;
}
retval = true;
in_statement_err:
sqlite3_finalize(stmt);
return retval;
}
/** Load the contents of the CONSTRUCT table from the given SQLite database.
*
* @param db represents the database to load from
@ -13,9 +334,9 @@
* false otherwise.
*/
bool
#line 418 "stats-db2.tpl"
#line 437 "stats-db2.tpl"
loadConstructStatsFromDB
#line 19 "stats-db2.c"
#line 340 "stats-db2.c"
(sqlite3* db)
{
bool retval = false;
@ -50,10 +371,10 @@ loadConstructStatsFromDB
ROW_COUNT_VAR = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
#line 420 "stats-db2.tpl"
#line 439 "stats-db2.tpl"
if (!statsAllocConstruct(ROW_COUNT_VAR))
return false;
#line 57 "stats-db2.c"
#line 378 "stats-db2.c"
}
/* Prepare the query to start fetching all rows */
@ -222,7 +543,7 @@ loadConstructStatsFromDB
{
#line 424 "stats-db2.tpl"
#line 443 "stats-db2.tpl"
stats->ref = REF_CONSTRUCT_START + CUR_ROW_NUM;
// save the stats
@ -234,7 +555,7 @@ loadConstructStatsFromDB
setMaxConstPoints(stats->constructPoints);
setMaxComponentWeight(stats->weight);
}
#line 238 "stats-db2.c"
#line 559 "stats-db2.c"
}
/* Retrieve the next row */

View File

@ -529,6 +529,22 @@ typedef struct SENSOR_STATS
iIMDShape* pMountGraphic;
} WZ_DECL_MAY_ALIAS SENSOR_STATS;
/* Forward declaration to allow pointers to this type */
struct sqlite3;
/** Load the contents of the SENSOR table from the given SQLite database.
*
* @param db represents the database to load from
*
* @return true if we succesfully loaded all available rows from the table,
* false otherwise.
*/
extern bool
#line 220 "stats-db2.tpl"
loadSensorStatsFromDB
#line 546 "stats-db2.h"
(struct sqlite3* db);
typedef struct ECM_STATS
{
/* BEGIN of inherited "COMPONENT" definition */
@ -1099,9 +1115,9 @@ struct sqlite3;
* false otherwise.
*/
extern bool
#line 418 "stats-db2.tpl"
#line 437 "stats-db2.tpl"
loadConstructStatsFromDB
#line 1105 "stats-db2.h"
#line 1121 "stats-db2.h"
(struct sqlite3* db);
#endif // __INCLUDED_DB_TEMPLATE_SCHEMA_STRUCTDEF_STATS_DB2_TPL_H__

View File

@ -217,6 +217,25 @@ end;
struct SENSOR
%inherit COMPONENT;
%nomacro;
%loadFunc "loadSensorStatsFromDB";
%preLoadTable maxId
if (!statsAllocSensor($maxId))
ABORT;
end;
%postLoadRow curRow rowNum
$curRow->ref = REF_SENSOR_START + $rowNum;
// save the stats
statsSetSensor($curRow, $rowNum);
// set the max stat values for the design screen
if ($curRow->designable)
{
setMaxSensorRange($curRow->range);
setMaxSensorPower($curRow->power);
setMaxComponentWeight($curRow->weight);
}
end;
%csv-file "sensor.txt";
# Sensor range.