#include "protocol.h"
#include "buffer.h"
#include "generic.h"
#include <stdio.h>
#include <unistd.h>
#include <odb/odatabase.h>
#include <odb/odbadbinary.h>
Go to the source code of this file.
Compounds | |
struct | Position |
Functions | |
void* | MatrixThread ( void* ) |
The Matrix Thread The Matrix Thread is the heart of both the server and the client. It is the interface to the database. It can just be accessed by the databaseAccess Class. More... | |
Variables | |
Buffer* | matrixBufIn = 0 |
the incoming buffer of the matrixThread. More... | |
map<int,Buffer*> | clientBufferIn |
the buffers the matrixThread uses to send its replies. More... |
|
The Matrix Thread The Matrix Thread is the heart of both the server and the client. It is the interface to the database. It can just be accessed by the databaseAccess Class.
Definition at line 58 of file matrixThread.cpp.
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 }
|
the buffers the matrixThread uses to send its replies.
Definition at line 33 of file matrixThread.cpp.
|
the incoming buffer of the matrixThread.
Definition at line 32 of file matrixThread.cpp.