#include "Varargs.h"
#include "TQConnection.h"
#include "TROOT.h"
#include "TRefCnt.h"
#include "TClass.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TDataType.h"
#include "Api.h"
#include "G__ci.h"
#include "Riostream.h"
#include "TVirtualMutex.h"
#include "THashTable.h"
#include "TCint.h"
ClassImpQ(TQConnection)
char *gTQSlotParams; 
class TQSlot : public TObject, public TRefCnt {
protected:
   G__CallFunc   *fFunc;      
   G__ClassInfo  *fClass;     
   TFunction     *fMethod;    
   Long_t         fOffset;    
   TString        fName;      
   Int_t          fExecuting; 
public:
   TQSlot(TClass *cl, const char *method, const char *funcname);
   TQSlot(const char *class_name, const char *funcname);
   virtual ~TQSlot();
   const char *GetName() const { return fName.Data(); }
   void ExecuteMethod(void *object);
   void ExecuteMethod(void *object, Int_t nargs, va_list ap);
   void ExecuteMethod(void *object, Long_t param);
   void ExecuteMethod(void *object, Long64_t param);
   void ExecuteMethod(void *object, Double_t param);
   void ExecuteMethod(void *object, const char *params);
   void ExecuteMethod(void *object, Long_t *paramArr, Int_t nparam = -1);
   void Print(Option_t *opt= "") const;
   void ls(Option_t *opt= "") const { Print(opt); }
   Bool_t IsExecuting() const { return fExecuting > 0; }
};
TQSlot::TQSlot(TClass *cl, const char *method_name,
               const char *funcname) : TObject(), TRefCnt()
{
   
   
   
   
   
   
   
   
   fFunc      = 0;
   fClass     = 0;
   fOffset    = 0;
   fMethod    = 0;
   fName      = "";
   fExecuting = 0;
   
   fName = method_name;
   char *method = new char[strlen(method_name)+1];
   if (method) strcpy(method, method_name);
   char *proto;
   char *tmp;
   char *params = 0;
   
   if ((proto = strchr(method,'('))) {
      
      *proto++ = '\0';
      
      if ((tmp = strrchr(proto,')'))) *tmp = '\0';
      if ((params = strchr(proto,'='))) *params = ' ';
   }
   R__LOCKGUARD2(gCINTMutex);
   fFunc = new G__CallFunc;
   
   
   if (cl) {
      if (params) {
         fFunc->SetFunc(cl->GetClassInfo(), method, params, &fOffset);
         fMethod = cl->GetMethod(method, params);
      } else {
         fFunc->SetFuncProto(cl->GetClassInfo(), method, proto, &fOffset);
         fMethod = cl->GetMethodWithPrototype(method, proto);
      }
   } else {
      fClass = new G__ClassInfo();
      if (params) {
         fFunc->SetFunc(fClass, (char*)funcname, params, &fOffset);
         fMethod = gROOT->GetGlobalFunction(funcname, params, kTRUE);
      } else {
         fFunc->SetFuncProto(fClass, (char*)funcname, proto, &fOffset);
         fMethod = gROOT->GetGlobalFunctionWithPrototype(funcname, proto, kTRUE);
      }
   }
   
   delete [] method;
}
TQSlot::TQSlot(const char *class_name, const char *funcname) :
   TObject(), TRefCnt()
{
   
   
   
   
   
   
   
   
   
   fFunc      = 0;
   fClass     = 0;
   fOffset    = 0;
   fMethod    = 0;
   fName      = funcname;
   fExecuting = 0;
   char *method = new char[strlen(funcname)+1];
   if (method) strcpy(method, funcname);
   char *proto;
   char *tmp;
   char *params = 0;
   
   if ((proto =  strchr(method,'('))) {
      *proto++ = '\0';
      if ((tmp = strrchr(proto,')'))) *tmp  = '\0';
      if ((params = strchr(proto,'='))) *params = ' ';
   }
   R__LOCKGUARD2(gCINTMutex);
   fFunc = new G__CallFunc;
   fClass = new G__ClassInfo();
   TClass *cl = 0;
   if (!class_name)
      ;                       
   else {
      fClass->Init(class_name);   
      cl = TClass::GetClass(class_name);
   }
   if (params) {
      fFunc->SetFunc(fClass, method, params, &fOffset);
      if (cl)
         fMethod = cl->GetMethod(method, params);
      else
         fMethod = gROOT->GetGlobalFunction(method, params, kTRUE);
   } else {
      fFunc->SetFuncProto(fClass, method, proto , &fOffset);
      if (cl)
         fMethod = cl->GetMethodWithPrototype(method, proto);
      else
         fMethod = gROOT->GetGlobalFunctionWithPrototype(method, proto, kTRUE);
   }
   delete [] method;
}
TQSlot::~TQSlot()
{
   
   
   if (!fExecuting) {
      delete fFunc;
      delete fClass;
   }
}
inline void TQSlot::ExecuteMethod(void *object)
{
   
   
   void *address = 0;
   if (object) address = (void*)((Long_t)object + fOffset);
   R__LOCKGUARD2(gCINTMutex);
   fExecuting++;
   fFunc->Exec(address);
   fExecuting--;
   if (!TestBit(kNotDeleted) && !fExecuting)
      delete fFunc;
}
inline void TQSlot::ExecuteMethod(void *object, Int_t nargs, va_list ap)
{
   
   
   if (!fMethod) {
      Error("ExecuteMethod", "method %s not found,"
            "\n(note: interpreted methods are not supported with varargs)",
            fName.Data());
      return;
   }
   if (nargs < fMethod->GetNargs() - fMethod->GetNargsOpt() ||
       nargs > fMethod->GetNargs()) {
      Error("ExecuteMethod", "nargs (%d) not consistent with expected number of arguments ([%d-%d])",
            nargs, fMethod->GetNargs() - fMethod->GetNargsOpt(),
            fMethod->GetNargs());
      return;
   }
   void *address = 0;
   R__LOCKGUARD2(gCINTMutex);
   fFunc->ResetArg();
   if (nargs > 0) {
      TIter next(fMethod->GetListOfMethodArgs());
      TMethodArg *arg;
      for (int i = 0; i < nargs; i++) {
         arg = (TMethodArg*) next();
         TString type = arg->GetFullTypeName();
         TDataType *dt = gROOT->GetType(type);
         if (dt)
            type = dt->GetFullTypeName();
         if (arg->Property() & (kIsPointer | kIsArray | kIsReference))
            fFunc->SetArg((Long_t) va_arg(ap, void*));
            
         else if (type == "bool")
            fFunc->SetArg((Long_t) va_arg(ap, int));  
            
         else if (type == "char" || type == "unsigned char")
            fFunc->SetArg((Long_t) va_arg(ap, int));  
            
         else if (type == "short" || type == "unsigned short")
            fFunc->SetArg((Long_t) va_arg(ap, int));  
            
         else if (type == "int" || type == "unsigned int")
            fFunc->SetArg((Long_t) va_arg(ap, int));
            
         else if (type == "long" || type == "unsigned long")
            fFunc->SetArg((Long_t) va_arg(ap, long));
            
         else if (type == "long long")
            fFunc->SetArg((Long64_t) va_arg(ap, Long64_t));
            
         else if (type == "unsigned long long")
            fFunc->SetArg((ULong64_t) va_arg(ap, ULong64_t));
            
         else if (type == "float")
            fFunc->SetArg((Double_t) va_arg(ap, double));  
            
         else if (type == "double")
            fFunc->SetArg((Double_t) va_arg(ap, double));
            
      }
   }
   if (object) address = (void*)((Long_t)object + fOffset);
   fExecuting++;
   fFunc->Exec(address);
   fExecuting--;
   if (!TestBit(kNotDeleted) && !fExecuting)
      delete fFunc;
}
inline void TQSlot::ExecuteMethod(void *object, Long_t param)
{
   
   
   void *address = 0;
   R__LOCKGUARD2(gCINTMutex);
   fFunc->ResetArg();
   fFunc->SetArg(param);
   if (object) address = (void*)((Long_t)object + fOffset);
   fExecuting++;
   fFunc->Exec(address);
   fExecuting--;
   if (!TestBit(kNotDeleted) && !fExecuting)
      delete fFunc;
}
inline void TQSlot::ExecuteMethod(void *object, Long64_t param)
{
   
   
   void *address = 0;
   R__LOCKGUARD2(gCINTMutex);
   fFunc->ResetArg();
   fFunc->SetArg(param);
   if (object) address = (void*)((Long_t)object + fOffset);
   fExecuting++;
   fFunc->Exec(address);
   fExecuting--;
   if (!TestBit(kNotDeleted) && !fExecuting)
      delete fFunc;
}
inline void TQSlot::ExecuteMethod(void *object, Double_t param)
{
   
   
   void *address = 0;
   R__LOCKGUARD2(gCINTMutex);
   fFunc->ResetArg();
   fFunc->SetArg(param);
   if (object) address = (void*)((Long_t)object + fOffset);
   fExecuting++;
   fFunc->Exec(address);
   fExecuting--;
   if (!TestBit(kNotDeleted) && !fExecuting)
      delete fFunc;
}
inline void TQSlot::ExecuteMethod(void *object, const char *param)
{
   
   void *address = 0;
   R__LOCKGUARD2(gCINTMutex);
   gTQSlotParams = (char*)param;
   fFunc->SetArgs("gTQSlotParams");
   if (object) address = (void*)((Long_t)object + fOffset);
   fExecuting++;
   fFunc->Exec(address);
   fExecuting--;
   if (!TestBit(kNotDeleted) && !fExecuting)
      delete fFunc;
}
inline void TQSlot::ExecuteMethod(void *object, Long_t *paramArr, Int_t nparam)
{
   
   
   
   
   
   
   
   void *address = 0;
   R__LOCKGUARD2(gCINTMutex);
   fFunc->SetArgArray(paramArr, nparam);
   if (object) address = (void*)((Long_t)object + fOffset);
   fExecuting++;
   fFunc->Exec(address);
   fExecuting--;
   if (!TestBit(kNotDeleted) && !fExecuting)
      delete fFunc;
}
void TQSlot::Print(Option_t *) const
{
   
   cout <<IsA()->GetName() << "\t" << GetName() << "\t"
   << "Number of Connections = " << References() << endl;
}
class TQSlotPool : public THashTable {
public:
   TQSlotPool() : THashTable(50) { }
   virtual ~TQSlotPool() { Clear("nodelete"); }
   TQSlot  *New(const char *class_name, const char *funcname);
   TQSlot  *New(TClass *cl, const char *method, const char *func);
   void     Free(TQSlot *slot);
};
TQSlot *TQSlotPool::New(const char *class_name, const char *funcname)
{
   
   TString name = class_name;
   name += "::";
   name += funcname;
   TQSlot *slot = (TQSlot*)FindObject(name.Data());
   if (!slot) {
      slot = new TQSlot(class_name, funcname);
      Add(slot);
   }
   slot->AddReference();
   return slot;
}
TQSlot *TQSlotPool::New(TClass *cl, const char *method, const char *func)
{
   
   TString name;
   if (cl) {
      name = cl->GetName();
      name += "::";
      name += method;
   } else {
      name = "::";
      name += func;
   }
   TQSlot *slot = (TQSlot*)FindObject(name.Data());
   if (!slot) {
      slot = new TQSlot(cl, method, func);
      Add(slot);
   }
   slot->AddReference();
   return slot;
}
void TQSlotPool::Free(TQSlot *slot)
{
   
   slot->RemoveReference();  
   if (slot->References() <= 0) {
      Remove(slot);
      if (!slot->IsExecuting()) SafeDelete(slot);
   }
}
static TQSlotPool gSlotPool;  
TQConnection::TQConnection() : TList(), TQObject()
{
   
   fReceiver = 0;
   fSlot     = 0;
}
TQConnection::TQConnection(TClass *cl, void *receiver, const char *method_name)
   : TList(), TQObject()
{
   
   
   
   
   char *funcname = 0;
   fReceiver = receiver;      
   if (!cl) {
      funcname = G__p2f2funcname(fReceiver);
      if (!funcname)
         Warning("TQConnection", "%s cannot be compiled", method_name);
   }
   if (cl) fClassName = cl->GetName();
   fSlot = gSlotPool.New(cl, method_name, funcname);
}
TQConnection::TQConnection(const char *class_name, void *receiver,
                           const char *funcname) : TList(), TQObject()
{
   
   
   
   fClassName = class_name;
   fSlot = gSlotPool.New(class_name, funcname);  
   fReceiver = receiver;      
}
TQConnection::TQConnection(const TQConnection &con): TList(), TQObject()
{
   
   fClassName = con.fClassName;
   fSlot = con.fSlot;
   fSlot->AddReference();
   fReceiver = con.fReceiver;
}
TQConnection::~TQConnection()
{
   
   
   
   
   TIter next(this);
   register TList *list;
   while ((list = (TList*)next())) {
      list->Remove(this);
      if (list->IsEmpty()) delete list;   
   }
   Clear("nodelete");
   if (!fSlot) return;
   gSlotPool.Free(fSlot);
}
const char *TQConnection::GetName() const
{
   
   return fSlot->GetName();
}
void TQConnection::Destroyed()
{
   
   MakeZombie();
   Emit("Destroyed()");
}
void TQConnection::ls(Option_t *option) const
{
   
   
   cout << "\t" <<  IsA()->GetName() << "\t" << GetName() << endl;
   ((TQConnection*)this)->R__FOR_EACH(TList,ls)(option);
}
void TQConnection::Print(Option_t *) const
{
   
   
   cout <<  "\t\t\t" << IsA()->GetName() << "\t" << fReceiver <<
            "\t" << GetName() << endl;
}
void TQConnection::ExecuteMethod()
{
   
   
   
   
   TQSlot *s = fSlot;
   fSlot->ExecuteMethod(fReceiver);
   if (s->References() <= 0) delete s;
}
void TQConnection::ExecuteMethod(Int_t nargs, va_list va)
{
   
   
   
   
   
   TQSlot *s = fSlot;
   fSlot->ExecuteMethod(fReceiver, nargs, va);
   if (s->References() <= 0) delete s;
}
void TQConnection::ExecuteMethod(Long_t param)
{
   
   
   
   
   
   TQSlot *s = fSlot;
   fSlot->ExecuteMethod(fReceiver, param);
   if (s->References() <= 0) delete s;
}
void TQConnection::ExecuteMethod(Long64_t param)
{
   
   
   
   
   
   TQSlot *s = fSlot;
   fSlot->ExecuteMethod(fReceiver, param);
   if (s->References() <= 0) delete s;
}
void TQConnection::ExecuteMethod(Double_t param)
{
   
   
   
   
   
   TQSlot *s = fSlot;
   fSlot->ExecuteMethod(fReceiver, param);
   if (s->References() <= 0) delete s;
}
void TQConnection::ExecuteMethod(Long_t *params, Int_t nparam)
{
   
   
   
   
   
   TQSlot *s = fSlot;
   fSlot->ExecuteMethod(fReceiver, params, nparam);
   if (s->References() <= 0) delete s;
}
void TQConnection::ExecuteMethod(const char *param)
{
   
   
   
   
   
   TQSlot *s = fSlot;
   fSlot->ExecuteMethod(fReceiver, param);
   if (s->References() <= 0) delete s;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.