#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.
1.1.2 written by Dimitri van Heesch,
© 1997-2000