Virtual U.org
Get Personal Training on VU Today
    
Top shadow
 
 register/help
User Name:

Password:

ODYNARRB.CPP Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

ODYNARRB.CPP

Go to the documentation of this file.
00001 //Filename    : ODYNARRB.CPP
00002 //Description : Object Dynamic Array Version B
00003 
00004 #include <OINFO.H>
00005 #include <ODYNARRB.H>
00006 #include <OFILE.H>
00007 
00008 //----------------------------------------------------------//
00009 //
00010 // Version B is different from Version A as :
00011 //
00012 // - when linkout() it doesn't not physically shift the memory
00013 //   upwards.
00014 //
00015 // - when linkin() it will search for empty rooms in the array
00016 //   before appending space at the end of the array.
00017 //
00018 //----------------------------------------------------------//
00019 
00020 #define EMPTY_ROOM_ALLOC_STEP    5
00021 
00022 //--------- BEGIN OF FUNCTION DynArrayB::DynArrayB -------//
00023 //
00024 // <int> eleSize  = size of each element
00025 // [int] blockNum = number of entity of each block of element
00026 //                       increased ( default : 30 )
00027 // [int] reuseIntervalDays = no. of game days deleted records needed to be kept before reusing them.
00028 //                                                                        (default: 0)
00029 //
00030 DynArrayB::DynArrayB(int eleSize,int blockNum,int reuseIntervalDays) : DynArray(eleSize, blockNum) {
00031     empty_room_array = NULL;
00032     empty_room_num   = 0;
00033     empty_room_count = 0;
00034 
00035     reuse_interval_days = reuseIntervalDays;
00036 }
00037 
00038 //----------- END OF FUNCTION DynArrayB::DynArrayB -----//
00039 
00040 //--------- BEGIN OF FUNCTION DynArrayB::~DynArrayB -------//
00041 //
00042 DynArrayB::~DynArrayB() {
00043     if( empty_room_array )
00044         mem_del( empty_room_array );
00045 }
00046 
00047 //----------- END OF FUNCTION DynArrayB::DynArrayB -----//
00048 
00049 //---------- BEGIN OF FUNCTION DynArrayB::linkin -----------//
00050 //
00051 // <void*> ent
00052 // <int>
00053 //
00054 // - when linkin() it will search for empty rooms in the array
00055 //   before appending space at the end of the array.
00056 //
00057 // - If found, then it will use that room
00058 //
00059 // - Otherwise, it will link a record at the END of the array
00060 //
00061 // WARNING : After calling linkin() all pointers to the linklist body
00062 //           should be updated, because mem_resize() will move the body memory
00063 //
00064 void DynArrayB::linkin(void* ent) {
00065     //------- detect for empty rooms --------//
00066 
00067     int reusedFlag=0;
00068 
00069     if( empty_room_count > 0 ) {
00070         if( reuse_interval_days ) {
00071             //------ first in, first out approach -----//
00072 
00073             if( info.game_date >= empty_room_array[0].deleted_game_date + reuse_interval_days ) {
00074                 cur_pos = empty_room_array[0].recno;
00075 
00076                 memmove( empty_room_array, empty_room_array+1, sizeof(empty_room_array[0]) * (empty_room_count-1) );
00077 
00078                 empty_room_count--;
00079                 reusedFlag = 1;
00080             }
00081         }
00082         else {
00083             //------ last in, first out approach -----//
00084 
00085             cur_pos = empty_room_array[empty_room_count-1].recno;
00086 
00087             empty_room_count--;
00088             reusedFlag = 1;
00089         }
00090     }
00091 
00092     if( !reusedFlag ) {
00093         last_ele++;
00094         cur_pos=last_ele;
00095     }
00096 
00097     //---------- regular link in -----------//
00098 
00099     if ( last_ele > ele_num )                       // not enough empty element left to hold the new entity
00100         resize( ele_num + block_num );
00101 
00102     if ( ent )
00103         memcpy(body_buf+(cur_pos-1)*ele_size, ent, ele_size );
00104     else
00105         *(body_buf+(cur_pos-1)*ele_size) = NULL;
00106 }
00107 
00108 //---------- END OF FUNCTION DynArrayB::linkin ------------//
00109 
00110 //----------- BEGIN OF FUNCTION DynArrayB::linkout ---------//
00111 //
00112 // - when linkout() it doesn't not physically shift the memory
00113 //   upwards.
00114 //
00115 // - it record the address of this empty room at empty room list
00116 //
00117 // [int] delPos = the position (recno) of the item to be deleted
00118 //                ( default : recno() current record no. )
00119 //
00120 void DynArrayB::linkout(int delPos) {
00121     if( delPos < 0 )
00122         delPos = cur_pos;
00123 
00124     if( delPos == 0 || delPos > last_ele )
00125         return;
00126 
00127     //-------- add to the empty room list ---------//
00128 
00129     if( ++empty_room_count > empty_room_num ) {
00130         empty_room_array = (EmptyRoom*) mem_resize( empty_room_array,
00131                                                     (empty_room_num+EMPTY_ROOM_ALLOC_STEP) * sizeof(*empty_room_array) );
00132 
00133         empty_room_num  += EMPTY_ROOM_ALLOC_STEP;
00134     }
00135 
00136     empty_room_array[empty_room_count-1].recno = delPos;
00137     empty_room_array[empty_room_count-1].deleted_game_date = info.game_date;
00138 
00139     memset( body_buf+(delPos-1)*ele_size, 0, ele_size );
00140 }
00141 
00142 //------------ END OF FUNCTION DynArrayB::linkout ----------//
00143 
00144 //---------- Begin of function DynArrayB::write_file -------------//
00154 int DynArrayB::write_file(File* filePtr) {
00155     if( !filePtr->file_write( this, sizeof(DynArray) ) )
00156         return 0;
00157 
00158     //---------- write body_buf ---------//
00159 
00160     if( last_ele > 0 ) {
00161         if( !filePtr->file_write( body_buf, ele_size*last_ele ) )
00162             return 0;
00163     }
00164 
00165     //---------- write empty_room_array ---------//
00166 
00167     write_empty_room(filePtr);
00168 
00169     return 1;
00170 }
00171 
00172 //------------- End of function DynArrayB::write_file --------------//
00173 
00174 //---------- Begin of function DynArrayB::read_file -------------//
00183 int DynArrayB::read_file(File* filePtr) {
00184     char* bodyBuf = body_buf;                       // preserve body_buf which has been allocated
00185 
00186     if( !filePtr->file_read( this, sizeof(DynArray) ) )
00187         return 0;
00188 
00189     //---------- read body_buf ---------//
00190 
00191     body_buf = mem_resize( bodyBuf, ele_size*ele_num );
00192 
00193     if( last_ele > 0 ) {
00194         if( !filePtr->file_read( body_buf, ele_size*last_ele ) )
00195             return 0;
00196     }
00197 
00198     //---------- read empty_room_array ---------//
00199 
00200     read_empty_room(filePtr);
00201 
00202     //------------------------------------------//
00203 
00204     start();                                        // go top
00205 
00206     return 1;
00207 }
00208 
00209 //------------- End of function DynArrayB::read_file --------------//
00210 
00211 //---------- Begin of function DynArrayB::write_empty_room -------------//
00221 int DynArrayB::write_empty_room(File* filePtr) {
00222     filePtr->file_put_short( empty_room_count );
00223 
00224     //---------- write empty_room_array ---------//
00225 
00226     if( empty_room_count > 0 ) {
00227         if( !filePtr->file_write( empty_room_array,
00228                                   sizeof(EmptyRoom) * empty_room_count ) ) {
00229             return 0;
00230         }
00231     }
00232 
00233     return 1;
00234 }
00235 
00236 //------------- End of function DynArrayB::write_empty_room --------------//
00237 
00238 //---------- Begin of function DynArrayB::read_empty_room -------------//
00247 int DynArrayB::read_empty_room(File* filePtr) {
00248     // set both to the same
00249     empty_room_num = empty_room_count = filePtr->file_get_short();
00250 
00251     //---------- read empty_room_array ---------//
00252 
00253     if( empty_room_count > 0 ) {
00254         empty_room_array = (EmptyRoom*) mem_resize( empty_room_array,
00255                                                     sizeof(EmptyRoom) * empty_room_count );
00256 
00257         if( !filePtr->file_read( empty_room_array,
00258                                  sizeof(*empty_room_array) * empty_room_count ) ) {
00259             return 0;
00260         }
00261     }
00262     else {                                          // when empty_room_count == 0
00263         if( empty_room_array ) {
00264             mem_del( empty_room_array );
00265             empty_room_array = NULL;
00266         }
00267     }
00268 
00269     //------------------------------------------//
00270 
00271     return 1;
00272 }
00273 
00274 //------------- End of function DynArrayB::read_empty_room --------------//
00275 
00276 //---------- Begin of function DynArrayB::packed_recno -------------//
00287 int DynArrayB::packed_recno(int recNo) {
00288     int i, packedRecno = recNo;
00289 
00290     for( i=0 ; i<empty_room_count ; i++ ) {
00291         if( empty_room_array[i].recno < recNo )
00292             packedRecno--;
00293     }
00294 
00295     return packedRecno;
00296 }
00297 
00298 //------------- End of function DynArrayB::packed_recno --------------//
00299 
00300 //---------- Begin of function DynArrayB::zap -------------//
00304 void DynArrayB::zap() {
00305     DynArray::zap();
00306 
00307     empty_room_count=0;                             // reset empty rooms
00308 }
00309 
00310 //------------- End of function DynArrayB::zap --------------//
00311 
00312 //-------- Start of function DynArrayB::write_ptr_array --------//
00313 //
00314 // Write a DynArrayB with pointer data elements.
00315 //
00316 // <File*> filePtr       - pointer to the file object.
00317 // <int>   objectSize - size of the objects pointed to by the pointers.
00318 //
00319 int DynArrayB::write_ptr_array(File* filePtr, int objectSize) {
00320     int   i;
00321     char* elePtr;
00322 
00323     filePtr->file_put_short( size() );
00324 
00325     for( i=1; i<=size() ; i++ ) {
00326         elePtr = (char*) get_ptr(i);
00327 
00328         //----- write 0 if the monster is deleted -----//
00329 
00330         if( !elePtr ) {                               // the monster is deleted
00331             filePtr->file_put_short(0);
00332         }
00333         else {
00334             filePtr->file_put_short(1);                 // the monster exists
00335 
00336             if( !filePtr->file_write(elePtr, objectSize) )
00337                 return 0;
00338         }
00339     }
00340 
00341     //------- write empty room array --------//
00342 
00343     write_empty_room(filePtr);
00344 
00345     return 1;
00346 }
00347 
00348 //--------- End of function DynArrayB::write_ptr_array ---------------//
00349 
00350 //-------- Start of function DynArrayB::read_ptr_array -------------//
00351 //
00352 // Read a DynArrayB with pointer data elements previously saved by
00353 // write_ptr_array().
00354 //
00355 // <File*> filePtr                               - pointer to the file object.
00356 // <int>   objectSize                    - size of the objects pointed to by the pointers.
00357 // <CreateEleFP> createEleFunc - function for creating a blank object.
00358 //
00359 int DynArrayB::read_ptr_array(File* filePtr, int objectSize, CreateEleFP createEleFunc) {
00360     int   i;
00361     char* elePtr;
00362 
00363     int eleCount = filePtr->file_get_short();       // get no. of monsters from file
00364 
00365     for( i=1 ; i<=eleCount ; i++ ) {
00366         if( filePtr->file_get_short()==0 ) {          // the monster has been deleted
00367             add_blank(1);                               // it's a DynArrayB function
00368         }
00369         else {
00370             elePtr = (*createEleFunc)();
00371 
00372             if( !filePtr->file_read(elePtr, objectSize) )
00373                 return 0;
00374         }
00375     }
00376 
00377     //-------- linkout() those record added by add_blank() ----------//
00378     //-- So they will be marked deleted in DynArrayB and can be -----//
00379     //-- undeleted and used when a new record is going to be added --//
00380 
00381     for( i=size() ; i>0 ; i-- ) {
00382         DynArrayB::go(i);                             // since DynArrayB has its own go() which will call GroupArray::go()
00383 
00384         if( get_ptr() == NULL )                       // add_blank() record
00385             linkout();
00386     }
00387 
00388     //------- read empty room array --------//
00389 
00390     read_empty_room(filePtr);
00391 
00392     return 1;
00393 }
00394 
00395 //--------- End of function DynArrayB::read_ptr_array ---------------//

Generated on Fri Aug 23 01:37:26 2002 for VirtualU by doxygen1.2.17