Browse Source

Instance (core) cleanup
* Changed instance_db array to DBMap
* Removed MAX_INSTANCE_DB
* Valid Instance ID is 1 ~ 65535
* Removed MAX_MAP_PER_INSTANCE from instance_db struct (in the map arrays)
* Change mapnames for instance_db to StringBuf

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>

Cydh Ramdh 10 years ago
parent
commit
fb01b02283
5 changed files with 140 additions and 87 deletions
  1. 4 4
      db/pre-re/instance_db.txt
  2. 13 13
      db/re/instance_db.txt
  3. 1 1
      src/map/atcommand.c
  4. 118 66
      src/map/instance.c
  5. 4 3
      src/map/instance.h

+ 4 - 4
db/pre-re/instance_db.txt

@@ -3,7 +3,7 @@
 // Structure of Database:
 // Structure of Database:
 // ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8
 // ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8
 
 
-0,Endless Tower,14400,1@tower,50,355,1@tower,2@tower,3@tower,4@tower,5@tower,6@tower
-1,Sealed Catacomb,7200,1@cata,100,224,1@cata,2@cata
-2,Orc's Memory,3600,1@orcs,179,15,1@orcs,2@orcs
-3,Nidhoggur's Nest,14400,1@nyd,32,36,1@nyd,2@nyd
+1,Endless Tower,14400,1@tower,50,355,1@tower,2@tower,3@tower,4@tower,5@tower,6@tower
+2,Sealed Catacomb,7200,1@cata,100,224,1@cata,2@cata
+3,Orc's Memory,3600,1@orcs,179,15,1@orcs,2@orcs
+4,Nidhoggur's Nest,14400,1@nyd,32,36,1@nyd,2@nyd

+ 13 - 13
db/re/instance_db.txt

@@ -3,16 +3,16 @@
 // Structure of Database:
 // Structure of Database:
 // ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8
 // ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8
 
 
-0,Endless Tower,14400,1@tower,50,355,1@tower,2@tower,3@tower,4@tower,5@tower,6@tower
-1,Sealed Catacomb,7200,1@cata,100,224,1@cata,2@cata
-2,Orc's Memory,3600,1@orcs,179,15,1@orcs,2@orcs
-3,Nidhoggur's Nest,14400,1@nyd,32,36,1@nyd,2@nyd
-4,Mistwood Maze,7200,1@mist,89,29,1@mist
-5,Culvert,3600,1@pump,63,98,1@pump,2@pump
-6,Octopus Cave,3600,1@cash,199,99,1@cash
-7,Bangungot Hospital 2F,3600,1@ma_h,40,157,1@ma_h
-8,Buwaya Cave,3600,1@ma_c,35,57,1@ma_c
-9,Bakonawa Lake,7200,1@ma_b,64,51,1@ma_b
-10,Wolfchev's Laboratory,14400,1@lhz,45,148,1@lhz
-11,Old Glast Heim,3600,1@gl_k,150,20,1@gl_k,2@gl_k
-12,Eclage Interior,1200,1@ecl,60,50,1@ecl
+1,Endless Tower,14400,1@tower,50,355,1@tower,2@tower,3@tower,4@tower,5@tower,6@tower
+2,Sealed Catacomb,7200,1@cata,100,224,1@cata,2@cata
+3,Orc's Memory,3600,1@orcs,179,15,1@orcs,2@orcs
+4,Nidhoggur's Nest,14400,1@nyd,32,36,1@nyd,2@nyd
+5,Mistwood Maze,7200,1@mist,89,29,1@mist
+6,Culvert,3600,1@pump,63,98,1@pump,2@pump
+7,Octopus Cave,3600,1@cash,199,99,1@cash
+8,Bangungot Hospital 2F,3600,1@ma_h,40,157,1@ma_h
+9,Buwaya Cave,3600,1@ma_c,35,57,1@ma_c
+10,Bakonawa Lake,7200,1@ma_b,64,51,1@ma_b
+11,Wolfchev's Laboratory,14400,1@lhz,45,148,1@lhz
+12,Old Glast Heim,3600,1@gl_k,150,20,1@gl_k,2@gl_k
+13,Eclage Interior,1200,1@ecl,60,50,1@ecl

+ 1 - 1
src/map/atcommand.c

@@ -3834,7 +3834,7 @@ ACMD_FUNC(reload) {
 		packetdb_readdb(true);
 		packetdb_readdb(true);
 		clif_displaymessage(fd, msg_txt(sd,1477)); // Packet database has been reloaded.
 		clif_displaymessage(fd, msg_txt(sd,1477)); // Packet database has been reloaded.
 	} else if (strstr(command, "instancedb") || strncmp(message, "instancedb", 4) == 0) {
 	} else if (strstr(command, "instancedb") || strncmp(message, "instancedb", 4) == 0) {
-		instance_readdb();
+		instance_reload();
 		clif_displaymessage(fd, msg_txt(sd,516)); // Instance database has been reloaded.
 		clif_displaymessage(fd, msg_txt(sd,516)); // Instance database has been reloaded.
 	}
 	}
 
 

+ 118 - 66
src/map/instance.c

@@ -8,6 +8,7 @@
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
 #include "../common/db.h"
 #include "../common/db.h"
+#include "../common/malloc.h"
 
 
 #include "clif.h"
 #include "clif.h"
 #include "instance.h"
 #include "instance.h"
@@ -18,7 +19,6 @@
 
 
 #include <stdlib.h>
 #include <stdlib.h>
 
 
-#define MAX_INSTANCE_DB		15	// Max number of instance types
 #define INSTANCE_INTERVAL	60000	// Interval used to check when an instance is to be destroyed (ms)
 #define INSTANCE_INTERVAL	60000	// Interval used to check when an instance is to be destroyed (ms)
 #define INSTANCE_LIMIT		300000	// Idle timer before instance is destroyed (ms) : 5 Minute Default
 #define INSTANCE_LIMIT		300000	// Idle timer before instance is destroyed (ms) : 5 Minute Default
 
 
@@ -26,16 +26,20 @@ int instance_start = 0; // To keep the last index + 1 of normal map inserted in
 
 
 struct instance_data instance_data[MAX_INSTANCE_DATA];
 struct instance_data instance_data[MAX_INSTANCE_DATA];
 
 
-static struct instance_db{
-	short type;
-	char name[61];
-	int limit;
+struct instance_db {
+	unsigned short id;
+	StringBuf *name;
+	unsigned int limit;
 	struct {
 	struct {
-		char mapname[MAP_NAME_LENGTH_EXT];
-		short x, y;
+		StringBuf *mapname; ///< Mapname, the limit should be MAP_NAME_LENGTH_EXT
+		unsigned short x, y; ///< Map coordinates
 	} enter;
 	} enter;
-	char mapname[MAX_MAP_PER_INSTANCE][MAP_NAME_LENGTH_EXT];
-} instance_db[MAX_INSTANCE_DB];
+	StringBuf **maplist; ///< Used maps, the limit should be MAP_NAME_LENGTH_EXT
+	uint8 maplist_count;
+};
+
+static DBMap *InstanceDB; /// Instance DB: struct instance_db, key: id
+static DBMap *InstanceNameDB; /// instance id, key: name
 
 
 static struct {
 static struct {
 	int id[MAX_INSTANCE_DATA];
 	int id[MAX_INSTANCE_DATA];
@@ -46,31 +50,22 @@ static struct {
 /*==========================================
 /*==========================================
  * Searches for an instance ID in the database
  * Searches for an instance ID in the database
  *------------------------------------------*/
  *------------------------------------------*/
-static struct instance_db *instance_searchtype_db(short instance_type)
-{
-	int i;
-
-	for(i=0; i < MAX_INSTANCE_DB; i++) {
-		if(instance_db[i].type == instance_type)
-			return &instance_db[i];
-	}
+static struct instance_db *instance_searchtype_db(unsigned short instance_id) {
+	return (struct instance_db *)uidb_get(InstanceDB,instance_id);
+}
 
 
-	return NULL;
+static uint16 instance_name2id(const char *instance_name) {
+	return (uint16)strdb_uiget(InstanceNameDB,instance_name);
 }
 }
 
 
 /*==========================================
 /*==========================================
  * Searches for an instance name in the database
  * Searches for an instance name in the database
  *------------------------------------------*/
  *------------------------------------------*/
-static struct instance_db *instance_searchname_db(const char *instance_name)
-{
-	int i;
-
-	for(i=0; i < MAX_INSTANCE_DB; i++) {
-		if(strcmp(instance_db[i].name, instance_name) == 0)
-			return &instance_db[i];
-	}
-
-	return NULL;
+static struct instance_db *instance_searchname_db(const char *instance_name) {
+	uint16 id = instance_name2id(instance_name);
+	if (id == 0)
+		return NULL;
+	return (struct instance_db *)uidb_get(InstanceDB,id);
 }
 }
 
 
 /*==========================================
 /*==========================================
@@ -117,7 +112,7 @@ static int instance_subscription_timer(int tid, unsigned int tick, int id, intpt
 	if(instance_wait.count)
 	if(instance_wait.count)
 		instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
 		instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
 	else
 	else
-		instance_wait.timer = -1;
+		instance_wait.timer = INVALID_TIMER;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -145,7 +140,7 @@ static int instance_startkeeptimer(struct instance_data *im, short instance_id)
 
 
 	// Notify party of the added instance timer
 	// Notify party of the added instance timer
 	if( ( p = party_search( im->party_id ) ) != NULL )
 	if( ( p = party_search( im->party_id ) ) != NULL )
-		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1 );
+		clif_instance_status( party_getavailablesd( p ), StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 1 );
 
 
 	return 0;
 	return 0;
 }
 }
@@ -172,8 +167,9 @@ static int instance_startidletimer(struct instance_data *im, short instance_id)
 	// Notify party of added instance timer
 	// Notify party of added instance timer
 	if( ( p = party_search( im->party_id ) ) != NULL &&
 	if( ( p = party_search( im->party_id ) ) != NULL &&
 		( db = instance_searchtype_db( im->type ) ) != NULL
 		( db = instance_searchtype_db( im->type ) ) != NULL
-		){
-		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1 );
+		)
+	{
+		clif_instance_status( party_getavailablesd( p ), StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 1 );
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -274,7 +270,7 @@ int instance_create(int party_id, const char *name)
 	if( i >= MAX_INSTANCE_DATA )
 	if( i >= MAX_INSTANCE_DATA )
 		return -4;
 		return -4;
 
 
-	instance_data[i].type = db->type;
+	instance_data[i].type = db->id;
 	instance_data[i].state = INSTANCE_IDLE;
 	instance_data[i].state = INSTANCE_IDLE;
 	instance_data[i].party_id = p->party.party_id;
 	instance_data[i].party_id = p->party.party_id;
 	instance_data[i].keep_limit = 0;
 	instance_data[i].keep_limit = 0;
@@ -326,16 +322,16 @@ int instance_addmap(short instance_id)
 	im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);
 	im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);
 
 
 	// Add the maps
 	// Add the maps
-	for(i = 0; i < MAX_MAP_PER_INSTANCE; i++) {
-		if(strlen(db->mapname[i]) < 1)
+	for(i = 0; i < db->maplist_count; i++) {
+		if(strlen(StringBuf_Value(db->maplist[i])) < 1)
 			continue;
 			continue;
-		else if( (m = map_addinstancemap(db->mapname[i], instance_id)) < 0) {
+		else if( (m = map_addinstancemap(StringBuf_Value(db->maplist[i]), instance_id)) < 0) {
 			// An error occured adding a map
 			// An error occured adding a map
 			ShowError("instance_addmap: No maps added to instance %d.\n",instance_id);
 			ShowError("instance_addmap: No maps added to instance %d.\n",instance_id);
 			return 0;
 			return 0;
 		} else {
 		} else {
 			im->map[cnt_map].m = m;
 			im->map[cnt_map].m = m;
-			im->map[cnt_map].src_m = map_mapname2mapid(db->mapname[i]);
+			im->map[cnt_map].src_m = map_mapname2mapid(StringBuf_Value(db->maplist[i]));
 			cnt_map++;
 			cnt_map++;
 		}
 		}
 	}
 	}
@@ -347,7 +343,7 @@ int instance_addmap(short instance_id)
 
 
 	// Inform party members of the created instance
 	// Inform party members of the created instance
 	if( (p = party_search( im->party_id ) ) != NULL )
 	if( (p = party_search( im->party_id ) ) != NULL )
-		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1);
+		clif_instance_status( party_getavailablesd( p ), StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 1);
 
 
 	return cnt_map;
 	return cnt_map;
 }
 }
@@ -427,7 +423,7 @@ int instance_destroy(short instance_id)
 				if(instance_wait.count)
 				if(instance_wait.count)
 					instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
 					instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
 				else
 				else
-					instance_wait.timer = -1;
+					instance_wait.timer = INVALID_TIMER;
 				type = 0;
 				type = 0;
 				break;
 				break;
 			}
 			}
@@ -517,14 +513,14 @@ int instance_enter_position(struct map_session_data *sd, const char *name, short
 		return 3;
 		return 3;
 	if(im->state != INSTANCE_BUSY)
 	if(im->state != INSTANCE_BUSY)
 		return 3;
 		return 3;
-	if(im->type != db->type)
+	if(im->type != db->id)
 		return 3;
 		return 3;
 
 
 	// Does the instance match?
 	// Does the instance match?
-	if((m = instance_mapname2mapid(db->enter.mapname, p->instance_id)) < 0)
+	if((m = instance_mapname2mapid(StringBuf_Value(db->enter.mapname), p->instance_id)) < 0)
 		return 3;
 		return 3;
 
 
-	if(pc_setpos(sd, map_id2index(m), x, y, 0))
+	if(pc_setpos(sd, map_id2index(m), x, y, CLR_OUTSIGHT))
 		return 3;
 		return 3;
 
 
 	// If there was an idle timer, let's stop it
 	// If there was an idle timer, let's stop it
@@ -560,12 +556,12 @@ int instance_reqinfo(struct map_session_data *sd, short instance_id)
 
 
 		for(i = 0; i < instance_wait.count; i++) {
 		for(i = 0; i < instance_wait.count; i++) {
 			if(instance_wait.id[i] == instance_id) {
 			if(instance_wait.id[i] == instance_id) {
-				clif_instance_create(sd, db->name, i+1, 0);
+				clif_instance_create(sd, StringBuf_Value(db->name), i+1, 0);
 				break;
 				break;
 			}
 			}
 		}
 		}
 	} else if(im->state == INSTANCE_BUSY) // Give info on the instance if busy
 	} else if(im->state == INSTANCE_BUSY) // Give info on the instance if busy
-		clif_instance_status(sd, db->name, im->keep_limit, im->idle_limit, 0);
+		clif_instance_status(sd, StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 0);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -624,37 +620,89 @@ int instance_delusers(short instance_id)
  *------------------------------------------*/
  *------------------------------------------*/
 static bool instance_readdb_sub(char* str[], int columns, int current)
 static bool instance_readdb_sub(char* str[], int columns, int current)
 {
 {
-	int i, type, k=0;
+	uint8 i;
+	int id = atoi(str[0]);
+	struct instance_db *db;
+	bool isNew = false;
 
 
-	type=atoi(str[0]);
+	if (!id || id >  USHRT_MAX) {
+		ShowError("instance_readdb_sub: Cannot add instance with ID '%d'. Valid ID is 1 ~ %d.\n", id, USHRT_MAX);
+		return false;
+	}
+
+	if (!(db = (struct instance_db *)uidb_get(InstanceDB, id))) {
+		CREATE(db, struct instance_db, 1);
+		db->id = id;
+		db->name = StringBuf_Malloc();
+		db->enter.mapname = StringBuf_Malloc();
+		isNew = true;
+	}
+	else {
+		StringBuf_Clear(db->name);
+		StringBuf_Clear(db->enter.mapname);
+		if (db->maplist_count) {
+			for (i = 0; i < db->maplist_count; i++)
+				StringBuf_Free(db->maplist[i]);
+			aFree(db->maplist);
+			db->maplist = NULL;
+		}
+	}
 
 
-	instance_db[type].type=type;
-	safestrncpy(instance_db[type].name, str[1], 24);
-	instance_db[type].limit=atoi(str[2]);
-	safestrncpy(instance_db[type].enter.mapname, str[3], MAP_NAME_LENGTH);
-	instance_db[type].enter.x=atoi(str[4]);
-	instance_db[type].enter.y=atoi(str[5]);
+	StringBuf_AppendStr(db->name, str[1]);
+	db->limit = atoi(str[2]);
+	StringBuf_AppendStr(db->enter.mapname, str[3]);
+	db->enter.x = atoi(str[4]);
+	db->enter.y = atoi(str[5]);
 
 
 	//Instance maps
 	//Instance maps
-	for(i=6; i<columns; i++)
-		if(strlen(str[i])) {
-			safestrncpy(instance_db[type].mapname[k], str[i], MAP_NAME_LENGTH);
-			k++;
+	for (i = 6; i < columns; i++) {
+		if (strlen(str[i])) {
+			RECREATE(db->maplist, StringBuf *, db->maplist_count+1);
+			db->maplist[db->maplist_count] = StringBuf_Malloc();
+			StringBuf_AppendStr(db->maplist[db->maplist_count], str[i]);
+			db->maplist_count++;
 		}
 		}
+	}
 
 
+	if (isNew) {
+		uidb_put(InstanceDB, id, db);
+		strdb_uiput(InstanceNameDB, StringBuf_Value(db->name), id);
+	}
 	return true;
 	return true;
 }
 }
 
 
-void instance_readdb(void)
-{
+static int instance_db_free(DBKey key, DBData *data, va_list ap) {
+	struct instance_db *db = (struct instance_db *)db_data2ptr(data);
+	bool clear = va_arg(ap, bool);
+	if (!db)
+		return 1;
+	StringBuf_Free(db->name);
+	StringBuf_Free(db->enter.mapname);
+	if (db->maplist_count) {
+		uint8 i;
+		for (i = 0; i < db->maplist_count; i++)
+			StringBuf_Free(db->maplist[i]);
+		aFree(db->maplist);
+	}
+	aFree(db);
+	return 0;
+}
+
+void instance_readdb(void) {
 	const char* filename[] = { DBPATH"instance_db.txt", "import/instance_db.txt"};
 	const char* filename[] = { DBPATH"instance_db.txt", "import/instance_db.txt"};
 	int f;
 	int f;
-	memset(&instance_db, 0, sizeof(instance_db));
-	for (f=0; f<ARRAYLENGTH(filename); f++){
-		sv_readdb(db_path, filename[f], ',', 7, 7+MAX_MAP_PER_INSTANCE, MAX_INSTANCE_DB, &instance_readdb_sub, f);
+
+	for (f = 0; f<ARRAYLENGTH(filename); f++) {
+		sv_readdb(db_path, filename[f], ',', 7, 7+MAX_MAP_PER_INSTANCE, -1, &instance_readdb_sub, f);
 	}
 	}
 }
 }
 
 
+void instance_reload(void) {
+	InstanceDB->clear(InstanceDB, instance_db_free);
+	db_clear(InstanceNameDB);
+	instance_readdb();
+}
+
 /*==========================================
 /*==========================================
  * Reloads the instance in runtime (reloadscript)
  * Reloads the instance in runtime (reloadscript)
  *------------------------------------------*/
  *------------------------------------------*/
@@ -688,7 +736,7 @@ void do_reload_instance(void)
 			if(!(p = party_search(sd->status.party_id)) || p->instance_id != map[sd->bl.m].instance_id) // Someone not in party is on instance map
 			if(!(p = party_search(sd->status.party_id)) || p->instance_id != map[sd->bl.m].instance_id) // Someone not in party is on instance map
 				continue;
 				continue;
 			im = &instance_data[p->instance_id];
 			im = &instance_data[p->instance_id];
-			if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd,db->name)) { // All good
+			if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd,StringBuf_Value(db->name))) { // All good
 				clif_displaymessage(sd->fd, msg_txt(sd,515)); // Instance has been reloaded
 				clif_displaymessage(sd->fd, msg_txt(sd,515)); // Instance has been reloaded
 				instance_reqinfo(sd,p->instance_id);
 				instance_reqinfo(sd,p->instance_id);
 			} else // Something went wrong
 			} else // Something went wrong
@@ -697,8 +745,10 @@ void do_reload_instance(void)
 	mapit_free(iter);
 	mapit_free(iter);
 }
 }
 
 
-void do_init_instance(void)
-{
+void do_init_instance(void) {
+	InstanceDB = uidb_alloc(DB_OPT_BASE);
+	InstanceNameDB = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,0);
+
 	instance_readdb();
 	instance_readdb();
 	memset(instance_data, 0, sizeof(instance_data));
 	memset(instance_data, 0, sizeof(instance_data));
 	memset(&instance_wait, 0, sizeof(instance_wait));
 	memset(&instance_wait, 0, sizeof(instance_wait));
@@ -708,10 +758,12 @@ void do_init_instance(void)
 	add_timer_func_list(instance_subscription_timer,"instance_subscription_timer");
 	add_timer_func_list(instance_subscription_timer,"instance_subscription_timer");
 }
 }
 
 
-void do_final_instance(void)
-{
+void do_final_instance(void) {
 	int i;
 	int i;
 
 
 	for( i = 1; i < MAX_INSTANCE_DATA; i++ )
 	for( i = 1; i < MAX_INSTANCE_DATA; i++ )
 		instance_destroy(i);
 		instance_destroy(i);
+
+	InstanceDB->destroy(InstanceDB, instance_db_free);
+	db_destroy(InstanceNameDB);
 }
 }

+ 4 - 3
src/map/instance.h

@@ -11,9 +11,9 @@
 
 
 typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
 typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
 
 
-struct instance_data
-{
-	short type, cnt_map;
+struct instance_data {
+	unsigned short type, ///< Instance DB ID
+		cnt_map;
 	int state;
 	int state;
 	int party_id;
 	int party_id;
 	unsigned int keep_limit;
 	unsigned int keep_limit;
@@ -43,6 +43,7 @@ int instance_addmap(short instance_id);
 
 
 void instance_addnpc(struct instance_data *im);
 void instance_addnpc(struct instance_data *im);
 void instance_readdb(void);
 void instance_readdb(void);
+void instance_reload(void);
 void do_reload_instance(void);
 void do_reload_instance(void);
 void do_init_instance(void);
 void do_init_instance(void);
 void do_final_instance(void);
 void do_final_instance(void);