CMsgRootConsumer.cc
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; } //----------------------------------------------------------------