// @(#)root/base:$Name: $:$Id: TQConnection.cxx,v 1.13 2003/05/11 14:09:10 rdm Exp $
// Author: Valeriy Onuchin & Fons Rademakers 15/10/2000
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// TQConnection class is an internal class, used in the object //
// communication mechanism. //
// //
// TQConnection: //
// - is a list of signal_lists containing pointers //
// to this connection //
// - receiver is the object to which slot-method is applied //
// //
// This implementation is provided by //
// Valeriy Onuchin (onuchin@sirius.ihep.su). //
// //
//////////////////////////////////////////////////////////////////////////
#include "TQConnection.h"
#include "TRefCnt.h"
#include "TClass.h"
#include "Api.h"
#include "G__ci.h"
#include "Riostream.h"
#include "TVirtualMutex.h"
ClassImpQ(TQConnection)
char *gTQSlotParams; // used to pass string parameter
//////////////////////////////////////////////////////////////////////////
// //
// TQSlot = slightly modified TMethodCall class //
// used in the object communication mechanism //
// //
//////////////////////////////////////////////////////////////////////////
class TQSlot : public TObject, public TRefCnt {
protected:
G__CallFunc *fFunc; // CINT method invocation environment
Long_t fOffset; // offset added to object pointer
TString fName; // full name of method
Int_t fExecuting; // true if one of this slot's ExecuteMethod methods is being called
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, Long_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); }
};
//______________________________________________________________________________
TQSlot::TQSlot(TClass *cl, const char *method_name,
const char *funcname) : TObject(), TRefCnt()
{
// Create the method invocation environment. Necessary input
// information: the class, full method name with prototype
// string of the form: method(char*,int,float).
// To initialize class method with default arguments, method
// string with default parameters should be of the form:
// method(="ABC",1234,3.14) (!! parameter string should
// consists of '=').
// To execute the method call TQSlot::ExecuteMethod(object,...).
fFunc = 0;
fOffset = 0;
fName = "";
fExecuting = 0;
// cl==0, is the case of interpreted function.
fName = method_name;
char *method = new char[strlen(method_name)+1];
if (method) strcpy(method, method_name);
char *proto;
char *tmp;
char *params = 0;
// separate method and protoype strings
if ((proto = strchr(method,'('))) {
// substitute first '(' symbol with '0'
*proto++ = '0';
// last ')' symbol with '0'
if ((tmp = strrchr(proto,')'))) *tmp = '0';
if ((params = strchr(proto,'='))) *params = ' ';
}
R__LOCKGUARD(gCINTMutex);
fFunc = new G__CallFunc;
// initiate class method (function) with proto
// or with default params
if (cl) {
params ?
fFunc->SetFunc(cl->GetClassInfo(), method, params, &fOffset) :
fFunc->SetFuncProto(cl->GetClassInfo(), method, proto, &fOffset);
} else {
G__ClassInfo gcl;
params ?
fFunc->SetFunc(&gcl, (char*)funcname, params, &fOffset) :
fFunc->SetFuncProto(&gcl, (char*)funcname, proto, &fOffset);
}
// cleaning
delete [] method;
}
//______________________________________________________________________________
TQSlot::TQSlot(const char *class_name, const char *funcname) :
TObject(), TRefCnt()
{
// Create the method invocation environment. Necessary input
// information: the name of class (could be interpreted class),
// full method name with prototype or parameter string
// of the form: method(char*,int,float).
// To initialize class method with default arguments, method
// string with default parameters should be of the form:
// method(="ABC",1234,3.14) (!! parameter string should
// consists of '=').
// To execute the method call TQSlot::ExecuteMethod(object,...).
fFunc = 0;
fOffset = 0;
fName = funcname;
fExecuting = 0;
char *method = new char[strlen(funcname)+1];
if (method) strcpy(method, funcname);
char *proto;
char *tmp;
char *params = 0;
// separate method and protoype strings
if ((proto = strchr(method,'('))) {
*proto++ = '0';
if ((tmp = strrchr(proto,')'))) *tmp = '0';
if ((params = strchr(proto,'='))) *params = ' ';
}
R__LOCKGUARD(gCINTMutex);
fFunc = new G__CallFunc;
G__ClassInfo gcl;
if (!class_name)
; // function
else
gcl.Init(class_name); // class
if (params)
fFunc->SetFunc(&gcl, method, params, &fOffset);
else
fFunc->SetFuncProto(&gcl, method, proto , &fOffset);
delete [] method;
return;
}
//______________________________________________________________________________
TQSlot::~TQSlot()
{
// TQSlot dtor.
// don't delete executing environment of a slot that is being executed
if (!fExecuting)
delete fFunc;
}
//______________________________________________________________________________
inline void TQSlot::ExecuteMethod(void *object)
{
// ExecuteMethod the method (with preset arguments) for
// the specified object.
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
R__LOCKGUARD(gCINTMutex);
fExecuting++;
fFunc->Exec(address);
fExecuting--;
if (!TestBit(kNotDeleted) && !fExecuting)
delete fFunc;
}
//______________________________________________________________________________
inline void TQSlot::ExecuteMethod(void *object, Long_t param)
{
// ExecuteMethod the method for the specified object and
// with single argument value.
void *address = 0;
R__LOCKGUARD(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)
{
// ExecuteMethod the method for the specified object and
// with single argument value.
void *address = 0;
R__LOCKGUARD(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)
{
// ExecuteMethod the method for the specified object and text param.
void *address = 0;
gTQSlotParams = (char*)param;
R__LOCKGUARD(gCINTMutex);
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)
{
// ExecuteMethod the method for the specified object and with
// several argument values.
// ParamArr is an array containing the function argument values.
// If nparam = -1 then paramArr must contain values for all function
// arguments, otherwise Nargs-NargsOpt <= nparam <= Nargs, where
// Nargs is the number of all arguments and NargsOpt is the number
// of default arguments.
void *address = 0;
R__LOCKGUARD(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
{
// Print info about slot.
cout <<IsA()->GetName() << "t" << GetName() << "t"
<< "Number of Connections = " << References() << endl;
}
//______________________________________________________________________________
TQConnection::TQConnection() : TList(), TQObject()
{
// Default constructor.
fReceiver = 0;
fSlot = 0;
}
//______________________________________________________________________________
TQConnection::TQConnection(TClass *cl, void *receiver, const char *method_name)
: TList(), TQObject()
{
// TQConnection ctor.
// cl != 0 - connection to object == receiver of class == cl
// and method == method_name
// cl == 0 - connection to function with name == method_name
char *funcname = 0;
fReceiver = receiver; // fReceiver is pointer to receiver
if (!cl) {
funcname = G__p2f2funcname(fReceiver);
if (!funcname)
Warning("TQConnection", "%s cannot be compiled", method_name);
}
fSlot = new TQSlot(cl, method_name, funcname);
fSlot->AddReference(); //update counter of references to slot
}
//______________________________________________________________________________
TQConnection::TQConnection(const char *class_name, void *receiver,
const char *funcname) : TList(), TQObject()
{
// TQConnection ctor.
// Creates connection to method of class specified by name,
// it could be interpreted class and with method == funcname.
fSlot = new TQSlot(class_name, funcname); // new slot-method
fSlot->AddReference(); // update counter of references to slot
fReceiver = receiver; // fReceiver is pointer to receiver
}
//______________________________________________________________________________
TQConnection::~TQConnection()
{
// TQConnection dtor.
// - remove this connection from all signal lists
// - we do not delete fSlot if it has other connections,
// TQSlot::fCounter > 0 .
TIter next(this);
register TList *list;
while ((list = (TList*)next())) {
list->Remove(this);
if (list->IsEmpty()) delete list; // delete empty list
}
Clear("nodelete");
if (!fSlot) return;
fSlot->RemoveReference(); // decrease references to slot
if (fSlot->References() <= 0) {
SafeDelete(fSlot);
}
}
//______________________________________________________________________________
const char *TQConnection::GetName() const
{
// Returns name of connection
return fSlot->GetName();
}
//______________________________________________________________________________
void TQConnection::Destroyed()
{
// Signal Destroyed tells that connection is destroyed.
MakeZombie();
Emit("Destroyed()");
}
//______________________________________________________________________________
void TQConnection::ls(Option_t *option) const
{
// List TQConnection full method name and list all signals
// connected to this connection.
cout << "t" << IsA()->GetName() << "t" << GetName() << endl;
((TQConnection*)this)->ForEach(TList,ls)(option);
}
//______________________________________________________________________________
void TQConnection::Print(Option_t *) const
{
// Print TQConnection full method name and print all
// signals connected to this connection.
cout << "t\tt" << IsA()->GetName() << "t" << fReceiver <<
"t" << GetName() << endl;
}
//______________________________________________________________________________
void TQConnection::ExecuteMethod()
{
// Apply slot-method to the fReceiver object without arguments.
fSlot->ExecuteMethod(fReceiver);
}
//______________________________________________________________________________
void TQConnection::ExecuteMethod(Long_t param)
{
// Apply slot-method to the fReceiver object with
// single argument value.
fSlot->ExecuteMethod(fReceiver, param);
}
//______________________________________________________________________________
void TQConnection::ExecuteMethod(Double_t param)
{
// Apply slot-method to the fReceiver object with
// single argument value.
fSlot->ExecuteMethod(fReceiver, param);
}
//______________________________________________________________________________
void TQConnection::ExecuteMethod(Long_t *params, Int_t nparam)
{
// Apply slot-method to the fReceiver object with variable
// number of argument values.
fSlot->ExecuteMethod(fReceiver, params, nparam);
}
//______________________________________________________________________________
void TQConnection::ExecuteMethod(const char *param)
{
// Apply slot-method to the fReceiver object and
// with string parameter.
fSlot->ExecuteMethod(fReceiver, param);
}
ROOT page - Class index - Top of the page
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.