37 ClassImpQ(TQConnection)
45 class TQSlot : public TObject, public TRefCnt {
55 TQSlot(TClass *cl,
const char *method,
const char *funcname);
56 TQSlot(
const char *class_name,
const char *funcname);
59 Bool_t CheckSlot(Int_t nargs)
const;
60 Long_t GetOffset()
const {
return fOffset; }
61 CallFunc_t *StartExecuting();
62 CallFunc_t *GetFunc()
const {
return fFunc; }
65 const char *GetName()
const {
69 Int_t GetMethodNargs() {
return fMethod->GetNargs(); }
71 void ExecuteMethod(
void *
object, Int_t nargs, va_list ap) =
delete;
72 void ExecuteMethod(
void *
object);
73 void ExecuteMethod(
void *
object, Long_t param);
74 void ExecuteMethod(
void *
object, Long64_t param);
75 void ExecuteMethod(
void *
object, Double_t param);
76 void ExecuteMethod(
void *
object,
const char *params);
77 void ExecuteMethod(
void *
object, Long_t *paramArr, Int_t nparam = -1);
78 void Print(Option_t *opt =
"")
const;
79 void ls(Option_t *opt =
"")
const {
83 Bool_t IsExecuting()
const {
84 return fExecuting > 0;
101 TQSlot::TQSlot(TClass *cl,
const char *method_name,
102 const char *funcname) : TObject(), TRefCnt()
115 char *method =
new char[strlen(method_name) + 1];
116 if (method) strcpy(method, method_name);
124 if ((proto = strchr(method,
'('))) {
130 if ((tmp = strrchr(proto,
')'))) * tmp =
'\0';
131 if ((params = strchr(proto,
'='))) * params =
' ';
134 R__LOCKGUARD(gInterpreterMutex);
135 fFunc = gCling->CallFunc_Factory();
142 gCling->CallFunc_SetFunc(fFunc, cl->GetClassInfo(), method, params, &fOffset);
143 fMethod = cl->GetMethod(method, params);
145 gCling->CallFunc_SetFuncProto(fFunc, cl->GetClassInfo(), method, proto, &fOffset);
146 fMethod = cl->GetMethodWithPrototype(method, proto);
149 fClass = gCling->ClassInfo_Factory();
151 gCling->CallFunc_SetFunc(fFunc, fClass, (
char *)funcname, params, &fOffset);
152 fMethod = gROOT->GetGlobalFunction(funcname, params, kFALSE);
154 gCling->CallFunc_SetFuncProto(fFunc, fClass, (
char *)funcname, proto, &fOffset);
155 fMethod = gROOT->GetGlobalFunctionWithPrototype(funcname, proto, kFALSE);
176 TQSlot::TQSlot(
const char *class_name,
const char *funcname) :
186 char *method =
new char[strlen(funcname) + 1];
187 if (method) strcpy(method, funcname);
195 if ((proto = strchr(method,
'('))) {
197 if ((tmp = strrchr(proto,
')'))) * tmp =
'\0';
198 if ((params = strchr(proto,
'='))) * params =
' ';
201 R__LOCKGUARD(gInterpreterMutex);
202 fFunc = gCling->CallFunc_Factory();
203 gCling->CallFunc_IgnoreExtraArgs(fFunc,
true);
205 fClass = gCling->ClassInfo_Factory();
211 gCling->ClassInfo_Init(fClass, class_name);
212 cl = TClass::GetClass(class_name);
216 gCling->CallFunc_SetFunc(fFunc, fClass, method, params, &fOffset);
218 fMethod = cl->GetMethod(method, params);
220 fMethod = gROOT->GetGlobalFunction(method, params, kTRUE);
222 gCling->CallFunc_SetFuncProto(fFunc, fClass, method, proto , &fOffset);
224 fMethod = cl->GetMethodWithPrototype(method, proto);
226 fMethod = gROOT->GetGlobalFunctionWithPrototype(method, proto, kTRUE);
239 gCling->CallFunc_Delete(fFunc);
240 gCling->ClassInfo_Delete(fClass);
248 inline void TQSlot::ExecuteMethod(
void *
object)
250 ExecuteMethod(
object, (Long_t*)
nullptr, 0);
258 inline Bool_t TQSlot::CheckSlot(Int_t nargs)
const
261 Error(
"ExecuteMethod",
"method %s not found,"
262 "\n(note: interpreted methods are not supported with varargs)",
267 if (nargs < fMethod->GetNargs() - fMethod->GetNargsOpt() ||
268 nargs > fMethod->GetNargs()) {
269 Error(
"ExecuteMethod",
"nargs (%d) not consistent with expected number of arguments ([%d-%d])",
270 nargs, fMethod->GetNargs() - fMethod->GetNargsOpt(),
271 fMethod->GetNargs());
281 CallFunc_t *TQSlot::StartExecuting() {
289 void TQSlot::EndExecuting() {
291 if (!TestBit(kNotDeleted) && !fExecuting)
292 gCling->CallFunc_Delete(fFunc);
299 inline void TQSlot::ExecuteMethod(
void *
object, Long_t param)
301 ExecuteMethod(
object, ¶m, 1);
309 inline void TQSlot::ExecuteMethod(
void *
object, Long64_t param)
311 Long_t *arg =
reinterpret_cast<Long_t *
>(¶m);
312 ExecuteMethod(
object, arg, 1);
320 inline void TQSlot::ExecuteMethod(
void *
object, Double_t param)
322 Long_t *arg =
reinterpret_cast<Long_t *
>(¶m);
323 ExecuteMethod(
object, arg, 1);
330 inline void TQSlot::ExecuteMethod(
void *
object,
const char *param)
332 Long_t arg =
reinterpret_cast<Long_t
>(param);
333 ExecuteMethod(
object, &arg, 1);
346 inline void TQSlot::ExecuteMethod(
void *
object, Long_t *paramArr, Int_t nparam)
349 R__LOCKGUARD(gInterpreterMutex);
350 if (paramArr) gCling->CallFunc_SetArgArray(fFunc, paramArr, nparam);
351 if (
object) address = (
void *)((Long_t)
object + fOffset);
353 gCling->CallFunc_Exec(fFunc, address);
355 if (!TestBit(kNotDeleted) && !fExecuting)
356 gCling->CallFunc_Delete(fFunc);
362 void TQSlot::Print(Option_t *)
const
364 std::cout << IsA()->GetName() <<
"\t" << GetName() <<
"\t"
365 <<
"Number of Connections = " << References() << std::endl;
375 fTable =
new THashTable(50);
377 virtual ~TQSlotPool() {
378 fTable->Clear(
"nodelete");
381 TQSlot *New(
const char *class_name,
const char *funcname);
382 TQSlot *New(TClass *cl,
const char *method,
const char *func);
383 void Free(TQSlot *slot);
389 TQSlot *TQSlotPool::New(
const char *class_name,
const char *funcname)
391 TString name = class_name;
395 TQSlot *slot = (TQSlot *)fTable->FindObject(name.Data());
398 slot =
new TQSlot(class_name, funcname);
401 slot->AddReference();
408 TQSlot *TQSlotPool::New(TClass *cl,
const char *method,
const char *func)
413 name = cl->GetName();
421 TQSlot *slot = (TQSlot *)fTable->FindObject(name.Data());
424 slot =
new TQSlot(cl, method, func);
427 slot->AddReference();
434 void TQSlotPool::Free(TQSlot *slot)
436 slot->RemoveReference();
438 if (slot->References() <= 0) {
439 fTable->Remove(slot);
440 if (!slot->IsExecuting()) SafeDelete(slot);
444 static TQSlotPool gSlotPool;
446 void TQConnection::SetArg(
const Long_t *params, Int_t nparam) {
448 nparam = fSlot->GetMethodNargs();
452 gInterpreter->CallFunc_SetArgArray(fSlot->GetFunc(),
const_cast<Long_t*
>(params), nparam);
462 TQConnection::TQConnection(TClass *cl,
void *receiver,
const char *method_name)
465 const char *funcname = 0;
466 fReceiver = receiver;
469 Error(
"SetFCN",
"Not used anymore.");
477 if (cl) fClassName = cl->GetName();
478 fSlot = gSlotPool.New(cl, method_name, funcname);
486 TQConnection::TQConnection(
const char *class_name,
void *receiver,
487 const char *funcname) : TQObject()
489 fClassName = class_name;
490 fSlot = gSlotPool.New(class_name, funcname);
491 fReceiver = receiver;
497 TQConnection::TQConnection(
const TQConnection &con) : TQObject()
499 fClassName = con.fClassName;
501 fSlot->AddReference();
502 fReceiver = con.fReceiver;
511 TQConnection::~TQConnection()
516 while ((list = (TList *)next())) {
518 if (list->IsEmpty())
delete list;
523 gSlotPool.Free(fSlot);
529 const char *TQConnection::GetName()
const
531 return fSlot->GetName();
537 void TQConnection::Destroyed()
547 void TQConnection::ls(Option_t *option)
const
549 std::cout <<
"\t" << IsA()->GetName() <<
"\t" << GetName() << std::endl;
550 ((TQConnection *)
this)->R__FOR_EACH(TList, ls)(option);
557 void TQConnection::PrintCollectionHeader(Option_t *)
const
559 TROOT::IndentLevel();
560 std::cout << IsA()->GetName() <<
"\t" << fReceiver <<
"\t" << GetName() << std::endl;
566 void TQConnection::ExecuteMethod()
572 fSlot->ExecuteMethod(fReceiver);
573 if (s->References() <= 0)
delete s;
580 void TQConnection::ExecuteMethod(Long_t param)
586 fSlot->ExecuteMethod(fReceiver, param);
587 if (s->References() <= 0)
delete s;
594 void TQConnection::ExecuteMethod(Long64_t param)
600 fSlot->ExecuteMethod(fReceiver, param);
601 if (s->References() <= 0)
delete s;
608 void TQConnection::ExecuteMethod(Double_t param)
614 fSlot->ExecuteMethod(fReceiver, param);
615 if (s->References() <= 0)
delete s;
622 void TQConnection::ExecuteMethod(Long_t *params, Int_t nparam)
628 fSlot->ExecuteMethod(fReceiver, params, nparam);
629 if (s->References() <= 0)
delete s;
636 void TQConnection::ExecuteMethod(
const char *param)
642 fSlot->ExecuteMethod(fReceiver, param);
643 if (s->References() <= 0)
delete s;
650 Bool_t TQConnection::CheckSlot(Int_t nargs)
const {
651 return fSlot->CheckSlot(nargs);
657 void *TQConnection::GetSlotAddress()
const {
658 if (fReceiver)
return (
void *)((Long_t)fReceiver + fSlot->GetOffset());
665 CallFunc_t *TQConnection::LockSlot()
const {
666 if (gInterpreterMutex) gInterpreterMutex->Lock();
667 return fSlot->StartExecuting();
673 void TQConnection::UnLockSlot(TQSlot *s)
const {
675 if (s->References() <= 0)
delete s;
676 if (gInterpreterMutex) gInterpreterMutex->UnLock();
679 CallFunc_t* TQConnection::GetSlotCallFunc()
const {
680 return fSlot->GetFunc();