diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2009-01-31 15:48:04 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2009-01-31 15:48:04 +0000 |
commit | 64b6e20b84aa3dca07228df923e73c0703b3d5af (patch) | |
tree | 013b60c9e17b9bf6819a0da06feda229adc78b3d /src/map/map.c | |
parent | 4dbc7922cdb25fcedc9ca39fc72ddca926e61efe (diff) | |
download | hercules-64b6e20b84aa3dca07228df923e73c0703b3d5af.tar.gz hercules-64b6e20b84aa3dca07228df923e73c0703b3d5af.tar.bz2 hercules-64b6e20b84aa3dca07228df923e73c0703b3d5af.tar.xz hercules-64b6e20b84aa3dca07228df923e73c0703b3d5af.zip |
objects[] array removal (bugreport:2559)
- Removed the 2 MB wide static array in favor of a general-purpose DBMap (id_db for now).
- Inlined functions map_addobject, map_delobject and map_delobjectnofree into their callers' code.
- Replaced the free id lookup algorithm from ancient jathena with something more efficient.
- Moved the algorithm to map_get_new_object_id() (similar idea as r13481).
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13503 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/map.c')
-rw-r--r-- | src/map/map.c | 146 |
1 files changed, 26 insertions, 120 deletions
diff --git a/src/map/map.c b/src/map/map.c index c732e2d55..372647088 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -102,8 +102,6 @@ static DBMap* charid_db=NULL; // int char_id -> struct map_session_data* static DBMap* regen_db=NULL; // int id -> struct block_list* (status_natural_heal processing) static int map_users=0; -static struct block_list *objects[MAX_FLOORITEM]; -static int first_free_object_id=0,last_object_id=0; #define block_free_max 1048576 struct block_list *block_free[block_free_max]; @@ -1129,124 +1127,38 @@ int map_foreachinmap(int (*func)(struct block_list*,va_list), int m, int type,.. return returnCount; } -/*========================================== - * 床アイテムやエフェクト用の一三bj割り?て - * object[]への保存とid_db登?まで - * - * bl->idもこの中で設定して問題無い? - *------------------------------------------*/ -int map_addobject(struct block_list *bl) + +/// Generates a new flooritem object id from the interval [MIN_FLOORITEM, MAX_FLOORITEM). +/// Used for floor items, skill units and chatroom objects. +/// @return The new object id +int map_get_new_object_id(void) { + static int last_object_id = MIN_FLOORITEM - 1; int i; - if( bl == NULL ){ - ShowWarning("map_addobject nullpo?\n"); - return 0; - } - if(first_free_object_id<2 || first_free_object_id>=MAX_FLOORITEM) - first_free_object_id=2; - for(i=first_free_object_id;i<MAX_FLOORITEM && objects[i];i++); - if(i>=MAX_FLOORITEM){ - ShowWarning("no free object id\n"); - return 0; - } - first_free_object_id=i; - if(last_object_id<i) - last_object_id=i; - objects[i]=bl; - idb_put(id_db,i,bl); - return i; -} -/*========================================== - * 一三bjectの解放 - * map_delobjectのfreeしないバ?ジョン - *------------------------------------------*/ -int map_delobjectnofree(int id) -{ - if( id < 0 || id >= MAX_FLOORITEM ) + // find a free id + i = last_object_id + 1; + while( i != last_object_id ) { - ShowError("map_delobjectnofree: invalid object id '%d'!\n", id); - return 0; - } - - if(objects[id]==NULL) - return 0; - - map_delblock(objects[id]); - idb_remove(id_db,id); - objects[id]=NULL; - - if(first_free_object_id>id) - first_free_object_id=id; - - while(last_object_id>2 && objects[last_object_id]==NULL) - last_object_id--; + if( i == MAX_FLOORITEM ) + i = MIN_FLOORITEM; - return 0; -} - -/*========================================== - * 一三bjectの解放 - * block_listからの削除、id_dbからの削除 - * object dataのfree、object[]へのNULL代入 - * - * addとの??性が無いのが?になる - *------------------------------------------*/ -int map_delobject(int id) -{ - struct block_list* bl; + if( idb_get(id_db, i) == NULL ) + break; - if( id < 0 || id >= MAX_FLOORITEM ) - { - ShowError("map_delobject: invalid object id '%d'!\n", id); - return 0; + ++i; } - if(objects[id]==NULL) + if( i == last_object_id ) + { + ShowError("map_addobject: no free object id!\n"); return 0; - - bl = objects[id]; - map_delobjectnofree(id); - map_freeblock(bl); - - return 0; -} - -/*========================================== - * 全一三bj相手にfuncを呼ぶ - * - *------------------------------------------*/ -void map_foreachobject(int (*func)(struct block_list*,va_list),int type,...) -{ - int i; - int blockcount=bl_list_count; - - for(i=2;i<=last_object_id;i++){ - if(objects[i]){ - if(!(objects[i]->type==type)) // Fixed [Lance] - continue; - if(bl_list_count>=BL_LIST_MAX) { - ShowWarning("map_foreachobject: too many blocks !\n"); - break; - } - bl_list[bl_list_count++]=objects[i]; - } } - map_freeblock_lock(); - - for(i=blockcount;i<bl_list_count;i++) - if( bl_list[i]->prev || bl_list[i]->next ) - { - va_list ap; - va_start(ap, type); - func(bl_list[i], ap); - va_end(ap); - } - - map_freeblock_unlock(); + // update cursor + last_object_id = i; - bl_list_count = blockcount; + return i; } /*========================================== @@ -1259,9 +1171,7 @@ void map_foreachobject(int (*func)(struct block_list*,va_list),int type,...) *------------------------------------------*/ int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr data) { - struct flooritem_data *fitem=NULL; - - fitem = (struct flooritem_data *)objects[id]; + struct flooritem_data* fitem = idb_get(id_db, id); if(fitem==NULL || fitem->bl.type!=BL_ITEM || (!data && fitem->cleartimer != tid)){ ShowError("map_clearflooritem_timer : error\n"); return 1; @@ -1271,7 +1181,8 @@ int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr data) else if(fitem->item_data.card[0] == CARD0_PET) intif_delete_petdata( MakeDWord(fitem->item_data.card[1],fitem->item_data.card[2]) ); clif_clearflooritem(fitem,0); - map_delobject(fitem->bl.id); + map_delblock(&fitem->bl); + map_freeblock(&fitem->bl); return 0; } @@ -1414,7 +1325,7 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int fir fitem->bl.m=m; fitem->bl.x=x; fitem->bl.y=y; - fitem->bl.id = map_addobject(&fitem->bl); + fitem->bl.id = map_get_new_object_id(); if(fitem->bl.id==0){ aFree(fitem); return 0; @@ -1433,6 +1344,7 @@ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int fir fitem->suby=((r>>2)&3)*3+3; fitem->cleartimer=add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0); + map_addiddb(&fitem->bl); map_addblock(&fitem->bl); clif_dropflooritem(fitem); @@ -1765,13 +1677,7 @@ struct map_session_data * map_nick2sd(const char *nick) *------------------------------------------*/ struct block_list * map_id2bl(int id) { - struct block_list *bl; - if(id >= 0 && id < ARRAYLENGTH(objects)) - bl = objects[id]; - else - bl = (struct block_list*)idb_get(id_db,id); - - return bl; + return (struct block_list*)idb_get(id_db,id); } /*========================================== |