From 78bf8d26567a2054bd9ff5268f9f73cb07d82b98 Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 24 Feb 2014 09:17:02 +0100 Subject: Ref redesign, part 1 - Moved string and numeric mapregs into the same DBMap (for consistency with the other reg types.) Signed-off-by: Haru --- src/map/mapreg.h | 18 ++-- src/map/mapreg_sql.c | 228 +++++++++++++++++++++++++++------------------------ src/map/script.h | 11 --- 3 files changed, 130 insertions(+), 127 deletions(-) (limited to 'src') diff --git a/src/map/mapreg.h b/src/map/mapreg.h index c92b6f602..246f5b744 100644 --- a/src/map/mapreg.h +++ b/src/map/mapreg.h @@ -8,19 +8,19 @@ #include "../common/cbasetypes.h" #include "../common/db.h" +/** Container for a mapreg value */ struct mapreg_save { - int64 uid; + int64 uid; ///< Unique ID union { - int i; - char *str; + int i; ///< Numeric value + char *str; ///< String value } u; - bool save; + bool is_string; ///< true if it's a string, false if it's a number + bool save; ///< Whether a save operation is pending }; struct mapreg_interface { - DBMap *db; // int var_id -> int value - /* TODO duck str_db, use same */ - DBMap *str_db; // int var_id -> char* value + DBMap *db; // int var_id -> struct mapreg_save /* */ DBMap *array_db; /* */ @@ -30,8 +30,7 @@ struct mapreg_interface { /* */ char table[32]; /* */ - bool i_dirty; - bool str_dirty; + bool dirty; ///< Whether there are modified regs to be saved /* */ void (*init) (void); void (*final) (void); @@ -43,6 +42,7 @@ struct mapreg_interface { void (*load) (void); void (*save) (void); int (*save_timer) (int tid, int64 tick, int id, intptr_t data); + int (*destroyreg) (DBKey key, DBData *data, va_list ap); void (*reload) (void); bool (*config_read) (const char *w1, const char *w2); }; diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c index 3cf92454d..926df2994 100644 --- a/src/map/mapreg_sql.c +++ b/src/map/mapreg_sql.c @@ -20,19 +20,35 @@ struct mapreg_interface mapreg_s; #define MAPREG_AUTOSAVE_INTERVAL (300*1000) -/// Looks up the value of an integer variable using its uid. +/** + * Looks up the value of an integer variable using its uid. + * + * @param uid variable's unique identifier. + * @return variable's integer value + */ int mapreg_readreg(int64 uid) { struct mapreg_save *m = i64db_get(mapreg->db, uid); return m?m->u.i:0; } -/// Looks up the value of a string variable using its uid. +/** + * Looks up the value of a string variable using its uid. + * + * @param uid variable's unique identifier + * @return variable's string value + */ char* mapreg_readregstr(int64 uid) { - struct mapreg_save *m = i64db_get(mapreg->str_db, uid); + struct mapreg_save *m = i64db_get(mapreg->db, uid); return m?m->u.str:NULL; } -/// Modifies the value of an integer variable. +/** + * Modifies the value of an integer variable. + * + * @param uid variable's unique identifier + * @param val new value + * @retval true value was successfully set + */ bool mapreg_setreg(int64 uid, int val) { struct mapreg_save *m; int num = script_getvarid(uid); @@ -44,7 +60,7 @@ bool mapreg_setreg(int64 uid, int val) { m->u.i = val; if(name[1] != '@') { m->save = true; - mapreg->i_dirty = true; + mapreg->dirty = true; } } else { if( i ) @@ -55,6 +71,7 @@ bool mapreg_setreg(int64 uid, int val) { m->u.i = val; m->uid = uid; m->save = false; + m->is_string = false; if(name[1] != '@' && !mapreg->skip_insert) {// write new variable to database char tmp_str[32*2+1]; @@ -81,13 +98,19 @@ bool mapreg_setreg(int64 uid, int val) { return true; } -/// Modifies the value of a string variable. +/** + * Modifies the value of a string variable. + * + * @param uid variable's unique identifier + * @param str new value + * @retval true value was successfully set + */ bool mapreg_setregstr(int64 uid, const char* str) { struct mapreg_save *m; int num = script_getvarid(uid); unsigned int i = script_getvaridx(uid); const char* name = script->get_str(num); - + if( str == NULL || *str == 0 ) { if( i ) script->array_update(&mapreg->array_db,uid,true); @@ -95,31 +118,32 @@ bool mapreg_setregstr(int64 uid, const char* str) { if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg->table, name, i) ) Sql_ShowDebug(map->mysql_handle); } - if( (m = i64db_get(mapreg->str_db,uid)) ) { + if( (m = i64db_get(mapreg->db,uid)) ) { if( m->u.str != NULL ) aFree(m->u.str); ers_free(mapreg->ers, m); } - i64db_remove(mapreg->str_db,uid); + i64db_remove(mapreg->db,uid); } else { - if( (m = i64db_get(mapreg->str_db,uid)) ) { + if( (m = i64db_get(mapreg->db,uid)) ) { if( m->u.str != NULL ) aFree(m->u.str); m->u.str = aStrdup(str); if(name[1] != '@') { - mapreg->str_dirty = true; + mapreg->dirty = true; m->save = true; } } else { if( i ) script->array_update(&mapreg->array_db,uid,false); - + m = ers_alloc(mapreg->ers, struct mapreg_save); m->uid = uid; m->u.str = aStrdup(str); m->save = false; - + m->is_string = true; + if(name[1] != '@' && !mapreg->skip_insert) { //put returned null, so we must insert. char tmp_str[32*2+1]; char tmp_str2[255*2+1]; @@ -128,14 +152,16 @@ bool mapreg_setregstr(int64 uid, const char* str) { if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg->table, tmp_str, i, tmp_str2) ) Sql_ShowDebug(map->mysql_handle); } - i64db_put(mapreg->str_db, uid, m); + i64db_put(mapreg->db, uid, m); } } return true; } -/// Loads permanent variables from database +/** + * Loads permanent variables from database. + */ void script_load_mapreg(void) { /* 0 1 2 @@ -158,7 +184,7 @@ void script_load_mapreg(void) { } mapreg->skip_insert = true; - + SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL); SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL); @@ -166,145 +192,127 @@ void script_load_mapreg(void) { while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) { int s = script->add_str(varname); int i = index; - + + if( i64db_exists(mapreg->db, reference_uid(s, i)) ) { + ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value); + continue; + } if( varname[length-1] == '$' ) { - if( i64db_exists(mapreg->str_db, reference_uid(s, i)) ) { - ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value); - continue; - } mapreg->setregstr(reference_uid(s, i),value); } else { - if( i64db_exists(mapreg->db, reference_uid(s, i)) ) { - ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value); - continue; - } mapreg->setreg(reference_uid(s, i),atoi(value)); } } - + SQL->StmtFree(stmt); mapreg->skip_insert = false; - - mapreg->i_dirty = false; - mapreg->str_dirty = false; + + mapreg->dirty = false; } -/// Saves permanent variables to database +/** + * Saves permanent variables to database. + */ void script_save_mapreg(void) { DBIterator* iter; struct mapreg_save *m = NULL; - if( mapreg->i_dirty ) { + if( mapreg->dirty ) { iter = db_iterator(mapreg->db); for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { if( m->save ) { int num = script_getvarid(m->uid); int i = script_getvaridx(m->uid); const char* name = script->get_str(num); - - if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) ) - Sql_ShowDebug(map->mysql_handle); - m->save = false; - } - } - dbi_destroy(iter); - mapreg->i_dirty = false; - } - - if( mapreg->str_dirty ) { - iter = db_iterator(mapreg->str_db); - for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { - if( m->save ) { - int num = script_getvarid(m->uid); - int i = script_getvaridx(m->uid); - const char* name = script->get_str(num); - char tmp_str2[2*255+1]; - - SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, 255)); - if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, tmp_str2, name, i) ) - Sql_ShowDebug(map->mysql_handle); + if (!m->is_string) { + if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) ) + Sql_ShowDebug(map->mysql_handle); + } else { + char tmp_str2[2*255+1]; + SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, 255)); + if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, tmp_str2, name, i) ) + Sql_ShowDebug(map->mysql_handle); + } m->save = false; } } dbi_destroy(iter); - mapreg->str_dirty = false; + mapreg->dirty = false; } } +/** + * Timer event to auto-save permanent variables. + * + * @see timer->do_timer + */ int script_autosave_mapreg(int tid, int64 tick, int id, intptr_t data) { mapreg->save(); return 0; } - -void mapreg_reload(void) { - DBIterator* iter; +/** + * Destroys a mapreg_save structure, freeing the contained string, if any. + * + * @see DBApply + */ +int mapreg_destroyreg(DBKey key, DBData *data, va_list ap) { struct mapreg_save *m = NULL; - mapreg->save(); + if (data->type != DB_DATA_PTR) // Sanity check + return 0; - iter = db_iterator(mapreg->db); - for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { - ers_free(mapreg->ers, m); - } - dbi_destroy(iter); - - iter = db_iterator(mapreg->str_db); - for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { - if( m->u.str != NULL ) { + m = DB->data2ptr(data); + + if (m->is_string) { + if (m->u.str) aFree(m->u.str); - } - ers_free(mapreg->ers, m); } - dbi_destroy(iter); - - db_clear(mapreg->db); - db_clear(mapreg->str_db); - + ers_free(mapreg->ers, m); + + return 0; +} + +/** + * Reloads mapregs, saving to database beforehand. + * + * This has the effect of clearing the temporary variables, and + * reloading the permanent ones. + */ +void mapreg_reload(void) { + mapreg->save(); + + mapreg->db->clear(mapreg->db, mapreg->destroyreg); + if( mapreg->array_db ) { mapreg->array_db->destroy(mapreg->array_db,script->array_free_db); mapreg->array_db = NULL; } - - + mapreg->load(); } +/** + * Finalizer. + */ void mapreg_final(void) { - DBIterator* iter; - struct mapreg_save *m = NULL; - mapreg->save(); - iter = db_iterator(mapreg->db); - for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { - ers_free(mapreg->ers, m); - } - dbi_destroy(iter); - - iter = db_iterator(mapreg->str_db); - for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { - if( m->u.str != NULL ) { - aFree(m->u.str); - } - ers_free(mapreg->ers, m); - } - dbi_destroy(iter); - - db_destroy(mapreg->db); - db_destroy(mapreg->str_db); - + mapreg->db->destroy(mapreg->db, mapreg->destroyreg); + ers_destroy(mapreg->ers); - + if( mapreg->array_db ) mapreg->array_db->destroy(mapreg->array_db,script->array_free_db); } +/** + * Initializer. + */ void mapreg_init(void) { mapreg->db = i64db_alloc(DB_OPT_BASE); - mapreg->str_db = i64db_alloc(DB_OPT_BASE); mapreg->ers = ers_new(sizeof(struct mapreg_save), "mapreg_sql.c::mapreg_ers", ERS_OPT_CLEAN); mapreg->load(); @@ -313,6 +321,9 @@ void mapreg_init(void) { timer->add_interval(timer->gettick() + MAPREG_AUTOSAVE_INTERVAL, mapreg->save_timer, 0, 0, MAPREG_AUTOSAVE_INTERVAL); } +/** + * Loads the mapreg configuration file. + */ bool mapreg_config_read(const char* w1, const char* w2) { if(!strcmpi(w1, "mapreg_db")) safestrncpy(mapreg->table, w2, sizeof(mapreg->table)); @@ -321,26 +332,28 @@ bool mapreg_config_read(const char* w1, const char* w2) { return true; } + +/** + * Interface defaults initializer. + */ void mapreg_defaults(void) { mapreg = &mapreg_s; - + /* */ mapreg->db = NULL; - mapreg->str_db = NULL; mapreg->ers = NULL; mapreg->skip_insert = false; - + safestrncpy(mapreg->table, "mapreg", sizeof(mapreg->table)); - mapreg->i_dirty = false; - mapreg->str_dirty = false; - + mapreg->dirty = false; + /* */ mapreg->array_db = NULL; - + /* */ mapreg->init = mapreg_init; mapreg->final = mapreg_final; - + /* */ mapreg->readreg = mapreg_readreg; mapreg->readregstr = mapreg_readregstr; @@ -349,6 +362,7 @@ void mapreg_defaults(void) { mapreg->load = script_load_mapreg; mapreg->save = script_save_mapreg; mapreg->save_timer = script_autosave_mapreg; + mapreg->destroyreg = mapreg_destroyreg; mapreg->reload = mapreg_reload; mapreg->config_read = mapreg_config_read; diff --git a/src/map/script.h b/src/map/script.h index 7ab7f17c6..c0160fd49 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -407,17 +407,6 @@ struct script_state { unsigned int id; }; -/* TODO: HELLO DUCK THIS */ -struct script_reg { - int64 index; - int data; -}; -/* TODO: HELLO DUCK THIS */ -struct script_regstr { - int64 index; - char* data; -}; - struct script_function { bool (*func)(struct script_state *st); char *name; -- cgit v1.2.3-60-g2f50