Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

cluster_pack_unpack.H

Go to the documentation of this file.
00001 // pack_unpack.H
00002 
00003 #ifndef PACK_UNPACK_H
00004 #define PACK_UNPACK_H
00005 
00006 #include "std/hash.H"
00007 #include "dev/room6d.H"
00008 #include "dev/buttons.H"
00009 #include "dev/dev2d.H"
00010 #include "dev/wall_clock.H"
00011 #include "mlib/transf3d.H"
00012 #include "mlib/points.H"
00013 #include "asciinet/asciinet.H"
00014 
00015 enum { END = 0, EVT_ROOM6D, EVT_BTN, EVT_2D, EVT_ASCII, EVT_WALLCLOCKMSG };
00016 
00017 int packings = 0;
00018 
00019 
00020 /*****************************************************************************
00021  * Function: pack_one_event_into_buffer
00022  * Params:   A buffer of char to pack into. An int telling us how much space is 
00023  *           in the buffer. And a ptr to an event that is to be packed.
00024  * Returns:  The amount of space the new event used. Returns -1 if there wasn't
00025  *           enough space to pack the event.
00026  ******************************************************************************/
00027 int 
00028 pack_one_event_into_buffer( char *buf, int bufSize, cEVENTptr &evt )
00029 {
00030   // Keep track of how much space this event will use
00031   int eventLen = 0;
00032   
00033   /**************************************************************************
00034    * Room 6D Events
00035    *   - These have a source name, a current transform, a previous transform,
00036    *     and a time. 
00037    **************************************************************************/
00038   if ( evt->class_name() == "EVENTroom6d" ) {
00039 
00040     // Test to see if there's enough room in the buffer for this event
00041     eventLen = 1 + 16 * sizeof(Greal) + 16 * sizeof(Greal) + sizeof(double) 
00042       + strlen(**evt->source()->evt_name()) + 1;
00043       
00044     // If there's enough room then serialize the event into the buffer
00045     if ( eventLen < bufSize ) {
00046       
00047       // The first byte is the event type
00048       buf[0] = EVT_ROOM6D;
00049       buf++;
00050       
00051       // Then the name of the source 
00052       strcpy( buf, **evt->source()->evt_name() );
00053       buf += strlen(**evt->source()->evt_name()) + 1;
00054         
00055       // Then the current transform of this event
00056       Wtransf curr_xf = EVENTroom6d::cast( evt )->cur();
00057       memcpy( buf, (char *)curr_xf.matrix(), 16 * sizeof(Greal) );
00058       buf += 16 * sizeof(Greal);
00059 
00060       // Then the previous transform of this event
00061       Wtransf prev_xf = EVENTroom6d::cast( evt )->old();
00062       memcpy( buf, (char *)prev_xf.matrix(), 16 * sizeof(Greal) );
00063       buf += 16 * sizeof(Greal);
00064 
00065       // Then the time that the event occurred
00066       double t = evt->time();
00067       memcpy( buf, (char *)&t, sizeof(double) );
00068       buf += sizeof(double);
00069       
00070     } 
00071     // Otherwise, if there isn't enough room, print an error and don't touch the buffer
00072     else {
00073     cerr << "Not enough room to pack event: " << evt->source()->evt_name() << endl;
00074     return -1;
00075     }
00076   }
00077   
00078   /**************************************************************
00079    * 2D Events
00080    *   - These are generated by the various joysticks. They have
00081    *     a name, a current (x,y), an old (x,y)
00082    **************************************************************/
00083   else if ( evt->class_name() == "EVENT2d" ) {
00084     
00085     // Test to see if there's enough room in the buffer
00086     eventLen = 1 + 4*sizeof(double) + strlen(**evt->source()->evt_name()) + 1;
00087     
00088     if ( eventLen < bufSize ) {
00089 
00090       // Event type indicator
00091       buf[0] = EVT_2D;
00092       buf++;
00093       
00094       // The name of the event source
00095       strcpy( buf, **evt->source()->evt_name() );
00096       buf += strlen(**evt->source()->evt_name() ) + 1;
00097       
00098       // The old (x,y)
00099       double old_x = EVENT2d::cast( evt )->old()[0];
00100       memcpy( buf, (char*)&old_x, sizeof(double) );
00101       buf += sizeof(double);
00102       double old_y = EVENT2d::cast( evt )->old()[1];
00103       memcpy( buf, (char*)&old_y, sizeof(double) );
00104       buf += sizeof(double);
00105 
00106       // The current (x,y)
00107       double cur_x = EVENT2d::cast( evt )->cur()[0];
00108       memcpy( buf, (char*)&cur_x, sizeof(double) );
00109       buf += sizeof(double);
00110       double cur_y = EVENT2d::cast( evt )->cur()[1];
00111       memcpy( buf, (char*)&cur_y, sizeof(double) );
00112       buf += sizeof(double);
00113     }
00114     // Otherwise, if there isn't enough room, print an error and don't touch the buffer
00115     else {
00116     cerr << "Not enough room to pack event: " << evt->source()->evt_name() << endl;
00117     return -1;
00118     }
00119     
00120   }
00121   
00122   /**************************************************************
00123    * Button Change Events 
00124    *   - These have a source name, a boolean state, and a time
00125    *     NOTE: THE TIME ISN'T USED???
00126    **************************************************************/
00127   else if ( evt->class_name() == "EVENTbtn" ) {
00128       
00129     // Test to see if there's enough room in the buffer
00130     eventLen = 1 + sizeof(bool) + sizeof(double) 
00131       + strlen(**evt->source()->evt_name()) + 1;
00132     
00133     if ( eventLen < bufSize ) {      
00134       // Event type indicator
00135       buf[0] = EVT_BTN;
00136       buf++;
00137 
00138       // The name of the event
00139       strcpy( buf, **evt->source()->evt_name() );
00140       buf += strlen(**evt->source()->evt_name() ) + 1;
00141       
00142       // The boolean indicating button state
00143       bool buttonState = EVENTbtn::cast( evt )->transition();
00144       memcpy( buf, (char*)&buttonState, sizeof(bool) );
00145       buf += sizeof(bool);
00146       
00147       // The time that this happened
00148       double t = evt->time();
00149       memcpy( buf, (char *)&t, sizeof(double) );
00150       buf += sizeof(double);
00151       
00152     } 
00153     // Otherwise, if there isn't enough room, print an error and don't touch the buffer
00154     else {
00155     cerr << "Not enough room to pack event: " << evt->source()->evt_name() << endl;
00156     return -1;
00157     }
00158   }
00159   
00160   /**************************************************************
00161    * ASCII Events
00162    *   - These have a message name and that's it.
00163    **************************************************************/
00164   else if ( evt->class_name() == "EVENTascii" ) {
00165     
00166     // Test to see if there's enough room in the buffer
00167     eventLen = 1 + strlen( **(EVENTascii::cast(evt)->text()) ) + 1;
00168     
00169     if ( eventLen < bufSize ) {
00170       
00171       // Event type indicator
00172       buf[0] = EVT_ASCII;
00173       buf++;
00174       
00175       // The message
00176       strcpy( buf, **(EVENTascii::cast(evt)->text()) );
00177       buf +=  strlen( **(EVENTascii::cast(evt)->text()) ) + 1;
00178       
00179     }
00180     // Otherwise, if there isn't enough room, print an error and don't touch the buffer
00181     else {
00182     cerr << "Not enough room to pack event: " << evt->source()->evt_name() << endl;
00183     return -1;
00184     }
00185   }
00186 
00187   /********************************************************************************
00188    * Wall Clock Events
00189    *   - These are for giving a sync'd time to simulations running on the cluster
00190    ********************************************************************************/
00191   else if ( evt->class_name() == "EVENTWallClockmsg" ) {
00192     
00193     // Test to see if there's enough room in the buffer
00194     eventLen = 1 + sizeof(double);
00195     
00196     if ( eventLen < bufSize ) {
00197       
00198       // Event type indicator
00199       buf[0] = EVT_WALLCLOCKMSG;
00200       buf++;
00201             
00202       // The time 
00203       double t = EVENTWallClockmsg::cast(evt)->msg_time();
00204       memcpy( buf, (char *)&t, sizeof(double) );
00205       buf += sizeof(double);
00206     }
00207     // Otherwise, if there isn't enough room, print an error and don't touch the buffer
00208     else {
00209     cerr << "Not enough room to pack event: " << evt->source()->evt_name() << endl;
00210     return -1;
00211     }
00212   }
00213 
00214 
00215   /*********************************************************************
00216    * Unknown Event Types
00217    *   - Just don't touch the buffer and print an error message
00218    *********************************************************************/
00219   else {
00220       cerr << "*** Tried to pack unknown type: " << evt->class_name() << endl;
00221   }
00222 
00223   // Finally return the length of the event that we just packed into the buffer
00224   return eventLen;
00225 }
00226 
00227 int unpackings = 0;
00228 
00229 void unpack_buffer( char *buf )
00230 {
00231   char *ptr = buf;
00232 
00233 
00234   int evtCount = 0;
00235 
00236   while( 1 ) {
00237     if (ptr[0] == END)
00238       break;
00239 
00240     evtCount++;
00241     
00242       
00243     /*****************************************************
00244      * Room 6d Events
00245      *****************************************************/
00246     if ( ptr[0] == EVT_ROOM6D ) {
00247       ptr++;  // (skip past type byte)
00248 
00249       str_ptr evt_name = ptr;
00250       ptr += strlen(ptr) + 1;
00251 
00252       EVENTsource *src = new EVENTsource(evt_name);
00253 
00254       Wtransf cur;
00255       memcpy((char *)cur.matrix(), ptr, 16 * sizeof(Greal));
00256       ptr += 16 * sizeof(Greal);
00257 
00258       Wtransf old;
00259       memcpy((char *)old.matrix(), ptr, 16 * sizeof(Greal));
00260       ptr += 16 * sizeof(Greal);
00261 
00262       double t;
00263       memcpy((char *)&t, ptr, sizeof(t));
00264       ptr += sizeof(t);
00265 
00266       EVENTroom6dptr e = new EVENTroom6d(src, old, cur, t);
00267       EVENTmgr::distrib(e);
00268 
00269     } 
00270     
00271     /*****************************************************
00272      * Button Events
00273      *****************************************************/
00274     else if ( ptr[0] == EVT_BTN ) {
00275 
00276       // Skip to the name
00277       ptr++;  
00278 
00279       // Get the name
00280       str_ptr evt_name = ptr;
00281       ptr += strlen(ptr) + 1;
00282 
00283       EVENTsource *src = new EVENTsource(evt_name);
00284       
00285       bool buttonTransition;
00286       memcpy( (char*)&buttonTransition, ptr, sizeof(bool) );
00287 
00288       ptr += sizeof(bool);
00289 
00290       double t;
00291       memcpy((char *)&t, ptr, sizeof(t));
00292       ptr += sizeof(t);
00293 
00294       EVENTbtnptr e = new EVENTbtn(src, buttonTransition);//, t);
00295       EVENTmgr::distrib( e );
00296     }
00297 
00298     /*****************************************************
00299      * 2D Events
00300      *****************************************************/
00301     else if ( ptr[0] == EVT_2D ) {
00302       
00303       // Skip to the name 
00304       ptr++;
00305 
00306       // Get the name
00307       str_ptr evt_name = ptr;
00308       ptr += strlen(ptr) + 1;
00309       
00310       // Get the old and current (x,y)
00311       double coord_array[4];
00312       memcpy( (char*)coord_array, ptr, 4*sizeof(double) );
00313 
00314       // Make the event and distribute
00315       EVENT2dptr e = new EVENT2d( evt_name, 
00316                   XYpt(coord_array[0],coord_array[1]),
00317                   XYpt(coord_array[2],coord_array[3]) );
00318       EVENTmgr::distrib( e );
00319     }
00320 
00321     /*****************************************************
00322      * ASCII Events
00323      *****************************************************/
00324     else if ( ptr[0] == EVT_ASCII ) {
00325       
00326       // Skip past the type indicator
00327       ptr++;
00328       
00329       // Get the message
00330       str_ptr msg = ptr;
00331       ptr += strlen(ptr) + 1;
00332       
00333       // Make the event and distribute
00334       EVENTasciiptr e = new EVENTascii( msg );
00335       EVENTmgr::distrib( e );
00336     } 
00337 
00338     /*****************************************************
00339      * Wall Clock Events
00340      *****************************************************/
00341     else if ( ptr[0] == EVT_WALLCLOCKMSG ) {
00342       
00343       // Skip past the type indicator
00344       ptr++;
00345       
00346       // Get the time
00347       double t;
00348       memcpy( (char *)&t, ptr, sizeof(double) );
00349       ptr += sizeof(double);
00350       
00351       // Make the event and distribute
00352       EVENTWallClockmsgptr e = new EVENTWallClockmsg( t );
00353       EVENTmgr::distrib( e );
00354     } 
00355 
00356 
00357 
00358     
00359     /*****************************************************
00360      * ERROR Condition... If we end up here, that's bad.
00361      *****************************************************/
00362     else {
00363       cerr << "Event Type: " << ptr[0] << endl;
00364       cerr << "ERROR! Trying to unpack but got weird value as event type." << endl;
00365       exit(0);
00366     }
00367   }
00368   
00369   //cerr << "Unpacked " << evtCount << " for\t" << (++unpackings) << endl;
00370 
00371 }
00372 
00373 #endif

Generated on Mon Sep 15 16:25:56 2003 for gluebase by doxygen1.2.18