00001 00002 00003 /******************************************************************** 00004 Description: The Matrix Thread 00005 part of the 3Dsia project 00006 created: xandi, 270300 00007 00008 History: 00009 date, name, changes, in funtion 00010 060500 xandi added Reasons 00011 280400 xandi changed the request-functions completely 00012 should be almost bugfree now 00013 230400 xandi added many odb access functions 00014 180400 StonedBones added dynamic packet length 00015 00016 ********************************************************************/ 00017 00018 00019 #include "protocol.h" 00020 #include "buffer.h" 00021 #include "generic.h" 00022 00023 //#include "frontEnd.h" 00024 00025 #include <stdio.h> 00026 #include <unistd.h> 00027 00028 #include <odb/generic.h> 00029 #include <odb/odatabase.h> 00030 #include <odb/odbadbinary.h> 00031 00032 extern Buffer* matrixBufIn; 00033 extern map<int,Buffer*> clientBufferIn; 00034 00035 /*................................................................... 00036 Description: Matrix Thread (the matrix database in fact..) 00037 Args: 00038 Returns: 00039 Created: xandi, 270300 00040 [ToDo:] 00041 Comments: 00042 Changes: 00043 code cleanup, xandi, 050400 00044 merged globalDatabaseThread with matrixThread into matrixThread, xandi, 060400 00045 added many odb access functions, xandi, 230400 00046 moved it into common/ to make it available to the client, xandi, 230400 00047 00048 -------------------------------------------------------------------*/ 00049 00051 struct Position 00052 { 00053 double X; 00054 double Y; 00055 double Z; 00056 }; 00057 00058 void* MatrixThread ( void* ) 00059 { 00060 CODatabase matrixDB; 00061 00062 map<int,CODBReason*> reasonType; 00063 map<int,CODBClass*> classT; //<------- THIS SHALL BECOME THE REAL CLASSTYPE 00064 map<int,string> classType; //<<----- AND THAT SHALL BECOME OBSOLETE! 00065 map<int,string> atomType; 00066 00067 map<int,long> atomSign; 00068 map<int,int> valueType; 00069 00070 classType[CLT_ENTITY] = "Entity"; 00071 classType[CLT_OBJECT] = "Object"; 00072 00073 classT[CLT_ENTITY] = matrixDB.NewClass (_T("Entity")); 00074 classT[CLT_OBJECT] = matrixDB.NewClass (_T("Object")); 00075 00076 matrixDB.NewClass (_T(classType[CLT_ENTITY]) ); 00077 matrixDB.NewClass (_T(classType[CLT_OBJECT]) ); 00078 00079 //the reasonTypes define with which reasons objects are bound together 00080 00081 reasonType[RT_E_PARENT_O] = matrixDB.NewReason( _T("EntityParentOfObject"), classT[CLT_ENTITY], classT[CLT_OBJECT] ); 00082 reasonType[RT_E_HOLDING_O] = matrixDB.NewReason( _T("EntityHoldsObject"), classT[CLT_ENTITY], classT[CLT_OBJECT] ); 00083 reasonType[RT_O_PARTOF_E] = matrixDB.NewReason( _T("ObjectPartOfEntity"), classT[CLT_OBJECT], classT[CLT_ENTITY] ); 00084 reasonType[RT_O_PARENT_O] = matrixDB.NewReason( _T("ObjectParentOfObject"), classT[CLT_OBJECT], classT[CLT_OBJECT] ); 00085 reasonType[RT_O_ATTACHED_O] = matrixDB.NewReason( _T("ObjectAttachedToObject"), classT[CLT_OBJECT], classT[CLT_OBJECT] ); 00086 00087 //those atomTypes are just to define the name the Atom will have - this can be _anything_ its not so important 00088 atomType[AT_USERNAME] = "Username"; 00089 atomType[AT_SOCKET] = "Socket"; 00090 atomType[AT_NETADDRESS] = "Netaddress"; //as long as we have ipv4 that will be a dotted quad 00091 atomType[AT_POSITION] = "Position"; 00092 atomType[AT_ENTITYTYPE] = "Entitytype"; 00093 atomType[AT_3DSIAGRAPH] = "3DsiaGraphical"; 00094 atomType[AT_CHATMSG] = "Chatmessage"; 00095 00096 //the atomSigns are very important. they are used to identify the type of an atom. at the moment, just one 00097 //atom in an object can have the same atomSign. 00098 atomSign[AT_USERNAME] = 0x00000001; 00099 atomSign[AT_SOCKET] = 0x00000002; 00100 atomSign[AT_NETADDRESS] = 0x00000003; 00101 atomSign[AT_POSITION] = 0x00000004; 00102 atomSign[AT_ENTITYTYPE] = 0x00000005; 00103 atomSign[AT_3DSIAGRAPH] = 0x00000006; 00104 atomSign[AT_CHATMSG] = 0x00000007; 00105 00106 //the valuetype specifies the container-type the atom will have. 00107 valueType[AT_USERNAME] = ODB_TYPE_STRING; 00108 valueType[AT_SOCKET] = ODB_TYPE_LONG; 00109 valueType[AT_NETADDRESS] = ODB_TYPE_LONG; 00110 valueType[AT_POSITION] = ODB_TYPE_BINARY; 00111 valueType[AT_ENTITYTYPE] = ODB_TYPE_STRING; 00112 valueType[AT_3DSIAGRAPH] = ODB_TYPE_BINARY; 00113 valueType[AT_CHATMSG] = ODB_TYPE_STRING; 00114 00115 long userSignSpecific = 0xFFFFFFFF; 00116 00117 cerr << "[mT] Matrix Thread started...\n"; 00118 00119 int from; 00120 00121 while (1) 00122 { 00123 if ( !matrixBufIn->isEmpty() ) 00124 { 00125 #ifdef DEBUG 00126 fprintf(stderr,"[mT] getting something\n"); 00127 #endif 00128 packet* pak = matrixBufIn->read (); 00129 from = pak->h.from; 00130 00131 #ifdef DEBUG 00132 fprintf(stderr,"[mT] and that is packet %d from %d\n",pak->h.header[0],from); 00133 #endif 00134 00135 switch (pak->h.header[0]) 00136 { 00137 case ODB_ADD_OBJECT: 00138 { 00139 /****************************************************++ 00140 Add an Object to the Database xandi, 220400 00141 ----------------------------------------------------- - 00142 header[1] the class the object shall belong to 00143 header[2] objectID (if >= 0 then try to create with this id) 00144 data objectName 00145 ++*****************************************************/ 00146 00147 #ifdef DEBUG2 00148 fprintf(stderr,"[mT] adding object %s - request by %d\n",pak->data.c_str (),from); 00149 #endif 00150 00151 long classID = pak->h.header[1]; 00152 long objectID = (long) pak->h.header[2]; 00153 00154 00155 CODBObject* poObject = 0; 00156 CODBClass* poClass = (CODBClass*) *matrixDB.GetClass ( _T(classType[classID])).begin(); //gets the pointer to the class with the name defined by classType 00157 00158 if ( objectID >= 0 ) //this is just allowed on client side: the local database of the client uses the same ID foro objects as the database on the server 00159 { 00160 #ifdef DEBUG 00161 fprintf(stderr,"[mT] ObjectID: %d - WARNING: IF ITS NOT THE CLIENT ITS A BUG!!\n",(int)objectID); 00162 #endif 00163 00164 00165 if ( !( poObject = matrixDB.Id2PtrObject ( objectID ) ) ) //Checks if that object already exists 00166 { 00167 #ifdef DEBUG 00168 fprintf(stderr,"[mT] ok, seems the object didn't exist...\n"); 00169 fprintf(stderr,"[mT] ID-src: %d, ID-dst: %d\n", objectID, (int)poObject->ID()); 00170 #endif 00171 00172 poObject = new CODBObject ( objectID, false); //creates the object with the given ID 00173 poObject = matrixDB.Add ( poObject ); //adds it to the matrix 00174 } 00175 /* 00176 else 00177 { 00178 //fprintf(stderr,"[mT] WHAT??.. [%p] [%d] this shouldn't be.. <-------------\n",poObject, (int)objectID); 00179 //or should it? 00180 } 00181 */ 00182 00183 poObject->ClassSet ( poClass ); //sets the class the object shall belong to 00184 00185 matrixDB.ChangeName ( poObject, _T(pak->data) ); //changes the name of the object 00186 00187 #ifdef DEBUG 00188 fprintf(stderr,"[mT] pak-data is %s and %d bytes long\n",pak->data.c_str(),pak->data.length() ); 00189 #endif 00190 } 00191 else 00192 { 00193 poObject = matrixDB.Add ( new CODBObject ( _T(pak->data), poClass ) ); //creates a new object with a new ID and adds it to the matrix 00194 #ifdef DEBUG 00195 fprintf(stderr,"[mT] created a new object with the ID: %d\n",(int)poObject->ID()); 00196 #endif 00197 } 00198 00199 00200 delete pak; 00201 packet* xpak = new packet; 00202 00203 xpak->h.header[0] = PROT_ADD_OBJECT_REPLY; 00204 xpak->h.header[1] = poObject->ID(); 00205 xpak->h.header[2] = classID; 00206 00207 clientBufferIn[from]->write ( xpak ); //answers the clientstub 00208 00209 #ifdef DEBUG2 00210 poObject->Dump(); //JUST FOR DEBUG, KICK ME! 00211 #endif 00212 break; 00213 } 00214 00215 00216 00217 case ODB_ADD_ATOM: 00218 { 00219 /****************************************************++ 00220 Add a new atom to an object xandi, 230400 00221 ----------------------------------------------------- - 00222 header[1] the type of atom (String, binary, c3dpoint, int..) 00223 header[2] the object the atom shall be attached to 00224 header[3] the group of atoms this one shall belong to (usersign) 00225 header[4] atomID 00226 data the value of the atom; 00227 ++*****************************************************/ 00228 00229 long objectID = (long) pak->h.header[2]; 00230 long aType = (long) pak->h.header[3]; 00231 long atomID = (long) pak->h.header[4]; 00232 00233 #ifdef DEBUG 00234 fprintf (stderr,"[mT] adding atom (type %li) to object %li - request from %d\n", aType, objectID, from ); 00235 #endif 00236 00237 CODBObject* poObject = matrixDB.Id2PtrObject(objectID); //gets the object which matches the ID 00238 00239 if ( !poObject ) //don't have that object THAT IS CONSIDERED AS A BUG IF THAT HAPPENS!! 00240 { 00241 fprintf(stderr,"[mT] requested object %d not found -- requested by (%d)\n",pak->h.header[2],from); 00242 00243 delete pak; 00244 pak = 0; 00245 // exit(1); //Actually i should do it.. don't know.. 00246 break; 00247 } 00248 00249 CVectorAtom oVA = poObject->AtomGet ( atomSign[aType], userSignSpecific ); //get the atom that matches exactly the usersign 00250 00251 CODBAtom* poAtom = 0; 00252 00253 if ( oVA.size() > 0 ) //there is already an atom with that usersign connected to that object 00254 { 00255 if ( oVA.size() != 1 ) //THIS must not be right now.. later we are planning to allow that 00256 { 00257 fprintf(stderr,"[mT] there is more than one atom of the same type in one object..!?!\n"); 00258 exit(1); //??????????? 00259 //break; 00260 } 00261 else 00262 { 00263 #ifdef DEBUG 00264 fprintf(stderr,"Ok, this atom did exist, it can be used\n"); 00265 #endif 00266 00267 CVectorAtom::iterator it = oVA.begin(); 00268 poAtom = (*it); 00269 } 00270 } 00271 else //there is no atom with that usersign yet 00272 { 00273 #ifdef DEBUG 00274 fprintf(stderr,"\n"); 00275 #endif 00276 if ( atomID >= 0 ) 00277 { 00278 #ifdef DEBUG 00279 fprintf(stderr,"[mT] If this is on server-side it must not be!!!\n"); 00280 #endif 00281 if ( ( poAtom = matrixDB.Id2PtrAtom(atomID) ) ) //checks if the atom with that ID already exists (JUST ALLOWED CLIENT-SIDE!!) 00282 { 00283 #ifdef DEBUG 00284 fprintf(stderr,"[mT] if thats on the client its all right... but if not - WTF??\n"); 00285 #endif 00286 } 00287 else 00288 { 00289 poAtom = matrixDB.Add ( new CODBAtom ( atomID ) ); //Creates an atom with a given ID and adds it to the database 00290 } 00291 } 00292 else 00293 { 00294 poAtom = matrixDB.Add ( new CODBAtom () ); //Creates an empty atom and adds it to the database - the database will assign an ID to the atom 00295 } 00296 00297 } 00298 00299 poAtom->NameSet ( _T(atomType[aType]) ); //sets the name of the atom 00300 poAtom->UserSignSet ( atomSign[aType] ); //sets the usersign 00301 00302 int containerType = valueType[aType]; 00303 00304 switch ( containerType ) 00305 { 00306 case ODB_TYPE_STRING: 00307 { 00308 *poAtom = _T(pak->data); 00309 00310 break; 00311 } 00312 00313 case ODB_TYPE_BINARY: 00314 { 00315 long temp = pak->data.length(); 00316 *poAtom = new CODBADBinary ( const_cast<char*>(pak->data.data()), temp ); 00317 break; 00318 } 00319 00320 case ODB_TYPE_LONG: 00321 { 00322 long tempLong; 00323 memcpy ( &tempLong, pak->data.data(), sizeof(long) ); 00324 *poAtom = tempLong; 00325 break; 00326 } 00327 00328 /* 00329 case ODB_TYPE_3DPOINT: 00330 { 00331 double temp[3]; 00332 memcpy ( &temp, pak->data.data() ); 00333 00334 break; 00335 } 00336 */ 00337 00338 default: 00339 { 00340 fprintf ( stderr,"[mT] adding atom of unknown containertype (%d)! not yet implemented or just a mistake by (%d)!\n",containerType,from); 00341 break; 00342 } 00343 } 00344 00345 #ifdef DEBUG 00346 fprintf(stderr,"[mT] ------------ ID of added Atom: %d\n",(int)poAtom->ID()); 00347 #endif 00348 00349 poObject->AtomAdd ( poAtom ); //adds atom to the object 00350 00351 delete pak; 00352 pak = 0; 00353 break; 00354 } 00355 00356 00357 00358 00359 case ODB_GET_ALL_CHANGED: 00360 { 00361 /****************************************************++ 00362 Request of all new/changed things, xandi, 290400 00363 those IDs are sent seperately to the clientstub 00364 ----------------------------------------------------- - 00365 header[1] nothing yet... 00366 TimeStamp the last time checked 00367 ++*****************************************************/ 00368 00369 //fprintf(stderr,"GetAllChanged: %d.%d\n",pak->h.TimeStamp.tv_sec,pak->h.TimeStamp.tv_usec); 00370 CVectorRoot oVR = matrixDB.GetThingsChanged ( pak->h.TimeStamp ); //gets all things that have changed since the last check.. 00371 00372 delete pak; 00373 00374 for ( CVectorRoot::iterator it = oVR.begin(); it != oVR.end(); ++it ) 00375 { 00376 packet* xpak = new packet; 00377 00378 long rttiInfo = (*it)->InfoGetRtti(); //gets the information which type of THING that is.. 00379 00380 switch ( rttiInfo ) 00381 { 00382 case _Object: //its an object!! ;) 00383 { 00384 CODBObject* poObject = (CODBObject*)*it; 00385 00386 #ifdef DEBUG3 00387 cerr << "[mT] rtti-info -> _Object " << poObject->ID() << "\n"; 00388 #endif 00389 00390 #ifdef DEBUG 00391 cerr << "[mT] rtti-info -> _Object\n"; 00392 poObject->Dump(); 00393 #endif 00394 00395 CODBClass* poClass = poObject->ClassGet(); //gets the pointer to the class 00396 00397 string className = poClass->NameGet(); //gets the name of the class 00398 00399 xpak->h.header[2] = -1; 00400 00401 typedef map<int,string>::const_iterator classIt; 00402 for ( classIt c = classType.begin(); c != classType.end(); ++c) //tries to find the classtype ID connected to the name 00403 { 00404 if ( c->second == className ) 00405 { 00406 xpak->h.header[2] = c->first; 00407 break; 00408 } 00409 } 00410 00411 if ( xpak->h.header[2] == -1 ) 00412 { 00413 fprintf(stderr,"[mT] The ClassType does not exist??? WTF??\n"); 00414 exit(1); 00415 } 00416 00417 xpak->h.header[0] = PROT_GET_ALL_OBJECTS_REPLY; 00418 xpak->h.header[1] = poObject->ID(); 00419 00420 clientBufferIn[from]->write ( xpak ); 00421 00422 break; 00423 } 00424 00425 case _Atom: 00426 { 00427 CODBAtom* poAtom = (CODBAtom*)*it; 00428 00429 #ifdef DEBUG2 00430 cerr << "[mT] rtti-info -> _Atom " << poAtom->ID() << "\n"; 00431 #endif 00432 00433 long atomUserSign = poAtom->UserSignGet(); 00434 00435 00436 long objectID = -1; 00437 00438 CMapReferencing& cRM = const_cast<CMapReferencing&>( poAtom->ParentGet()); 00439 00440 for ( CMapReferencing::iterator c = cRM.begin(); c != cRM.end(); ++c ) 00441 { 00442 long parentRttiInfo = c->first->InfoGetRtti (); 00443 00444 switch ( parentRttiInfo ) 00445 { 00446 case _Object: 00447 { 00448 #ifdef DEBUG2 00449 cerr << "[mT] parteninfo: _Object\n"; 00450 #endif 00451 objectID = c->first->ID(); 00452 break; 00453 } 00454 default: 00455 { 00456 cerr << "[mT] the atom has other parents than an Object - Handler not yet implemented!\n"; 00457 break; 00458 } 00459 } 00460 00461 } 00462 00463 00464 if ( objectID == -1 ) 00465 { 00466 #ifdef DEBUG2 00467 cerr << "[mT] The Atom does not have any parents at all!\n"; 00468 #endif 00469 delete xpak; 00470 break; 00471 } 00472 00473 xpak->h.header[0] = PROT_GET_ALL_ATOMS_REPLY; 00474 xpak->h.header[1] = poAtom->ID(); 00475 xpak->h.header[2] = (int) objectID; 00476 xpak->h.header[3] = -1; 00477 00478 00479 typedef map<int,long>::const_iterator atomIt; 00480 00481 for ( atomIt a = atomSign.begin(); a != atomSign.end(); ++a) 00482 { 00483 if ( a->second == atomUserSign ) 00484 { 00485 xpak->h.header[3] = a->first; 00486 break; 00487 } 00488 } 00489 if ( xpak->h.header[3] == -1 ) 00490 { 00491 fprintf(stderr,"[mT] this must not be!! there was an atom of unknown type in the database..\n"); 00492 exit(1); 00493 } 00494 00495 #ifdef DEBUG2 00496 fprintf(stderr,"[mT] Atom %d of object %d with type %d\n",xpak->h.header[1],xpak->h.header[2],xpak->h.header[3]); 00497 fprintf(stderr,"---------------[%d]-[%d]-------------\n",xpak->h.header[1],xpak->h.header[2],xpak->h.header[3]); 00498 #endif 00499 00500 clientBufferIn[from]->write ( xpak ); 00501 00502 break; 00503 } 00504 00505 00506 case _Reason: 00507 { 00508 break; 00509 } 00510 00511 default: 00512 { 00513 #ifdef DEBUG2 00514 cerr << "[mT] rtti type unknown!\n"; 00515 #endif 00516 delete xpak; 00517 break; 00518 } 00519 00520 } 00521 00522 } 00523 break; 00524 } 00525 00526 00527 case ODB_GET_OBJECT: 00528 { 00529 /****************************************************++ 00530 Request an object from the database xandi, 230400 00531 ----------------------------------------------------- - 00532 header[1] ID of object 00533 ++*****************************************************/ 00534 00535 CODBObject* poObject = matrixDB.Id2PtrObject(pak->h.header[1]); 00536 #ifdef DEBUG 00537 fprintf(stderr,"[mT] ODB_GET_OBJECT %d - %p\n",pak->h.header[1],poObject); 00538 #endif 00539 00540 pak->h.header[0] = PROT_GET_OBJECT_REPLY; 00541 pak->data = poObject->NameGet(); 00542 //anything more?? (ID is already in header[1]); 00543 00544 clientBufferIn[from]->write ( pak ); 00545 #ifdef DEBUG 00546 fprintf(stderr,"[mT] ODB_GET_OBJECT successful...\n"); 00547 #endif 00548 break; 00549 } 00550 00551 00552 00553 00554 case ODB_GET_ATOM: 00555 { 00556 /****************************************************++ 00557 Request an atom from an object xandi, 230400 00558 ----------------------------------------------------- - 00559 header[1] the ID of the Atom 00560 header[2] the ID of its Object 00561 header[3] type of atom (usersign) 00562 ++*****************************************************/ 00563 00564 long atomID = pak->h.header[1]; 00565 long objectID = pak->h.header[2]; 00566 long aType = pak->h.header[3]; 00567 00568 delete pak; 00569 pak = 0; 00570 00571 CODBAtom* poAtom = matrixDB.Id2PtrAtom(atomID); 00572 00573 if ( !poAtom ) 00574 { 00575 fprintf(stderr,"[mT] strange, the requested atom does not exsist\n"); 00576 exit(1); 00577 } 00578 else 00579 { 00580 00581 packet* xpak = new packet; 00582 00583 unsigned char* tempBuffer; 00584 long sizeOfBuffer = poAtom->BinarySizeGet(); 00585 long tempLength; 00586 00587 tempBuffer = new unsigned char[sizeOfBuffer]; //+1 oder nicht, das ist hier die frage.. 00588 00589 #ifdef DEBUG 00590 fprintf(stderr,"[mT] length of binary stream: %d\n",(int)sizeOfBuffer); 00591 #endif 00592 00593 tempLength = poAtom->BinaryDataGet ( tempBuffer, sizeOfBuffer ); 00594 00595 #ifdef DEBUG 00596 fprintf(stderr,"[mT] real length of binary stream: %d\n",(int)tempLength); 00597 #endif 00598 00599 xpak->h.header[0] = PROT_GET_ATOM_REPLY; 00600 xpak->h.header[1] = (int) objectID; 00601 xpak->h.header[2] = aType; 00602 xpak->h.header[3] = poAtom->ID(); 00603 00604 xpak->data.assign ( (char*) tempBuffer, sizeOfBuffer ); 00605 00606 #ifdef DEBUG 00607 fprintf(stderr,"[mT] content: [ %li - %d ]\n",aType,xpak->h.header[3]); 00608 #endif 00609 00610 xpak->h.header[4] = valueType[aType]; 00611 00612 clientBufferIn[from]->write ( xpak ); 00613 00614 delete tempBuffer; 00615 } 00616 break; 00617 } 00618 00619 case ODB_ADD_REASON: 00620 { 00621 /****************************************************++ 00622 Add a Reson to an object xandi, 060500 00623 ----------------------------------------------------- - 00624 header[1] the ID of the Object the reason should be attached to 00625 header[2] the ID of the Object it is bound with some reason to 00626 header[3] type of reason 00627 ++*****************************************************/ 00628 00629 long objectIDa = (long) pak->h.header[1]; 00630 long objectIDb = (long) pak->h.header[2]; 00631 int reason = pak->h.header[3]; 00632 00633 CODBObject* poObjectA = matrixDB.Id2PtrObject ( objectIDa ); 00634 CODBObject* poObjectB = matrixDB.Id2PtrObject ( objectIDb ); 00635 00636 if ( poObjectA && poObjectB ) 00637 { 00638 poObjectA->Link ( poObjectB, reasonType[reason] ); 00639 } 00640 00641 else 00642 { 00643 #ifdef DEBUG 00644 fprintf(stderr,"[mT.odbAddReason] no no no, that doesn't work.. one of the objects does not exist\n"); 00645 #endif 00646 } 00647 00648 delete pak; 00649 break; 00650 } 00651 00652 case ODB_REMOVE_REASON: 00653 { 00654 /****************************************************++ 00655 Remove a Reson from an object xandi, 060500 00656 ----------------------------------------------------- - 00657 header[1] the ID of the Object the reason should be removed from 00658 header[2] the ID of the Object it is bound with some reason to 00659 header[3] type of reason 00660 ++*****************************************************/ 00661 00662 long objectIDa = (long) pak->h.header[1]; 00663 long objectIDb = (long) pak->h.header[2]; 00664 int reason = pak->h.header[3]; 00665 00666 CODBObject* poObjectA = matrixDB.Id2PtrObject ( objectIDa ); 00667 CODBObject* poObjectB = matrixDB.Id2PtrObject ( objectIDb ); 00668 00669 if ( poObjectA && poObjectB ) 00670 { 00671 poObjectA->LinkRemove ( poObjectB, reasonType[reason] ); 00672 } 00673 00674 else 00675 { 00676 #ifdef DEBUG 00677 fprintf(stderr,"[mT.odbAddReason] no no no, that doesn't work.. one of the objects does not exist\n"); 00678 #endif 00679 } 00680 00681 delete pak; 00682 break; 00683 } 00684 00685 default: 00686 { 00687 fprintf(stderr,"CANT BE!!!!!!!!!\n"); 00688 break; 00689 } 00690 } 00691 } 00692 } 00693 } //void matrixThread ( void ) 00694 00695 00696 00697 00698 00699 /***********************************************************************************************+++ 00700 +******************************************************************************************+ 00701 +*************************************************************************************+ 00702 OBSOLETE 00703 +*************************************************************************************+ 00704 ++****************************************************************************************++ 00705 ++**********************************************************************************************+*/ 00706 00707 /* [snip] removed that :) */