From GlueXWiki
// Example shows how to receive serialized root object via cMsg
// and deserialize into real root object
//
// Elliott Wolin, JLab, 26-jan-2009
// include files
#include <iostream>
#include <iomanip>
#include <string>
#include <stdlib.h>
// for cMsg
#include "cMsg.hxx"
// root include files
#include "TCanvas.h"
#include "TH1.h"
#include "TMessage.h"
using namespace std;
using namespace cmsg;
// misc variables */
static string url = "cMsg://localhost/cMsg";
static TCanvas *canvas = NULL;
static int hcount = 0;
static int debug = 0;
static int done = 0;
// prototypes */
void decode_command_line(int argc, char **argv);
//----------------------------------------------------------------
//----------------------------------------------------------------
// needed to expose protected TMessage constructor
class MyTMessage : public TMessage {
public:
MyTMessage(void *buf, Int_t len) : TMessage(buf, len) { }
};
//----------------------------------------------------------------
//----------------------------------------------------------------
// callback class receives cMsg message and deserializes root object
class rootCallback : public cMsgCallback {
public:
void callback(cMsgMessage *msg, void *userObject) {
hcount++;
// create input root message object from cMsg byte array
MyTMessage *myTM = new MyTMessage(msg->getByteArray(),msg->getByteArrayLength());
// get object class name
TNamed *namedObj = (TNamed*)myTM->ReadObject(myTM->GetClass());
string className = namedObj->ClassName();
cout << "Received object ClassName is: " << className << endl;
// how to get the object directly if you already know what type it is
// TH1F *hist = (TH1F*)myTM->ReadObject(myTM->GetClass());
// how to cast TNamed object to subclass
// if(className=="TH1F") {
// TH1F *fhist = (TH1F*)namedObj;
// }
// cast to histogram base class TH1
TH1 *hist = dynamic_cast<TH1*>(namedObj);
if(hist!=NULL) {
// print hist info
hist->Print();
// save hist as gif file
canvas->Clear();
hist->Draw();
canvas->SaveAs("hist.gif");
cout << endl;
cout << endl;
} else {
cerr << "?not a TH1 object" << endl;
}
delete(msg);
}
};
//----------------------------------------------------------------
//----------------------------------------------------------------
int main (int argc, char **argv) {
// decode command line
decode_command_line(argc,argv);
try {
// connect to cMsg server, create subscriptions and start receiving
cMsg c(url,"hconsumer","histogram consumer");
c.connect();
c.subscribe("root","hist",new rootCallback(),NULL);
c.start();
// create root canvas
canvas = new TCanvas("canvas");
// wait for messages
while(!done) {
done=hcount>=10;
sleep(1);
}
// done
c.stop();
c.disconnect();
} catch(cMsgException &e) {
cout << "?cMsg exception: " << e.what() << endl;
exit(EXIT_FAILURE);
} catch(...) {
cout << "?unknown exception" << endl;
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
//----------------------------------------------------------------
void decode_command_line(int argc, char**argv) {
const char *help =
"\nusage:\n\n analysis [-url url] [-debug]\n";
int i;
// loop over arguments */
i=1;
while (i<argc) {
if (strncasecmp(argv[i],"-h",2)==0) {
printf("%s\n",help);
exit(EXIT_SUCCESS);
} else if (strncasecmp(argv[i],"-url",4)==0) {
url=string(argv[i+1]);
i=i+2;
} else if (strncasecmp(argv[i],"-debug",6)==0) {
debug=1;
i=i+1;
} else if (strncasecmp(argv[i],"-",1)==0) {
printf("\n ?unknown command line arg: %s\n\n",argv[i]);
exit(EXIT_FAILURE);
} else {
break;
}
}
return;
}
//----------------------------------------------------------------