74 #include "RConfigure.h"
80 Bool_t TQObject::fgAllSignalsBlocked = kFALSE;
84 ClassImpQ(TQObjSender)
100 TString TQObject::CompressName(const
char *method_name)
102 TString res(method_name);
107 static TVirtualMutex * lock = 0;
110 static TPMERegexp *constRe = 0, *wspaceRe = 0;
112 constRe =
new TPMERegexp(
"(?<=\\(|\\s|,|&|\\*)const(?=\\s|,|\\)|&|\\*)",
"go");
113 wspaceRe =
new TPMERegexp(
"\\s+(?=([^\"]*\"[^\"]*\")*[^\"]*$)",
"go");
115 constRe ->Substitute(res,
"");
116 wspaceRe->Substitute(res,
"");
119 TStringToken methargs(res,
"\\(|\\)", kTRUE);
121 methargs.NextToken();
125 methargs.NextToken();
126 TStringToken arg(methargs,
",");
127 while (arg.NextToken())
129 Int_t pri = arg.Length() - 1;
131 if (arg[pri] ==
'*' || arg[pri] ==
'&') {
135 TDataType *dt = gROOT->GetType(arg.Data());
137 res += dt->GetFullTypeName();
142 if (!arg.AtEnd()) res +=
",";
153 TMethod *GetMethodWithPrototype(TClass *cl,
const char *method,
154 const char *proto, Int_t &nargs)
158 if (!gInterpreter || cl == 0)
return 0;
160 TMethod *m = cl->GetMethodWithPrototype(method,proto);
161 if (m) nargs = m->GetNargs();
168 static TMethod *GetMethod(TClass *cl,
const char *method,
const char *params)
170 if (!gInterpreter || cl == 0)
return 0;
171 return cl->GetMethod(method,params);
181 Int_t TQObject::CheckConnectArgs(TQObject *sender,
182 TClass *sender_class,
const char *signal,
183 TClass *receiver_class,
const char *slot)
185 char *signal_method =
new char[strlen(signal)+1];
186 if (signal_method) strcpy(signal_method, signal);
191 if ((signal_proto = strchr(signal_method,
'('))) {
193 *signal_proto++ =
'\0';
195 if ((tmp = strrchr(signal_proto,
')'))) *tmp =
'\0';
198 if (!signal_proto) signal_proto = (
char*)
"";
201 if (sender && sender_class == TQObjSender::Class()) {
202 sender_class = TClass::GetClass(sender->GetSenderClassName());
204 ::Error(
"TQObject::CheckConnectArgs",
"for signal/slot consistency\n"
205 "checking need to specify class name as argument to "
207 delete [] signal_method;
213 TMethod *signalMethod = GetMethodWithPrototype(sender_class,
218 ::Error(
"TQObject::CheckConnectArgs",
"signal %s::%s(%s) does not exist",
219 sender_class->GetName(), signal_method, signal_proto);
220 delete [] signal_method;
223 Int_t nsigargs = nargs;
225 #if defined(CHECK_COMMENT_STRING)
226 const char *comment = 0;
227 if (signalMethod != (TMethod *) -1)
228 comment = signalMethod->GetCommentString();
230 if (!comment || !comment[0] || strstr(comment,
"*SIGNAL")){
231 ::Error(
"TQObject::CheckConnectArgs",
232 "signal %s::%s(%s), to declare signal use comment //*SIGNAL*",
233 sender_class->GetName(), signal_method, signal_proto);
234 delete [] signal_method;
240 delete [] signal_method;
242 char *slot_method =
new char[strlen(slot)+1];
243 if (slot_method) strcpy(slot_method, slot);
246 char *slot_params = 0;
248 if ((slot_proto = strchr(slot_method,
'('))) {
251 *slot_proto++ =
'\0';
254 if ((tmp = strrchr(slot_proto,
')'))) *tmp =
'\0';
257 if (!slot_proto) slot_proto = (
char*)
"";
258 if ((slot_params = strchr(slot_proto,
'='))) *slot_params =
' ';
260 TFunction *slotMethod = 0;
261 if (!receiver_class) {
263 slotMethod = gROOT->GetGlobalFunction(slot_method,0,kFALSE);
265 slotMethod = !slot_params ?
266 GetMethodWithPrototype(receiver_class,
270 GetMethod(receiver_class,
271 slot_method, slot_params);
276 ::Error(
"TQObject::CheckConnectArgs",
"slot %s(%s) does not exist",
277 receiver_class ? Form(
"%s::%s", receiver_class->GetName(),
278 slot_method) : slot_method, slot_proto);
280 ::Error(
"TQObject::CheckConnectArgs",
"slot %s(%s) does not exist",
281 receiver_class ? Form(
"%s::%s", receiver_class->GetName(),
282 slot_method) : slot_method, slot_params);
284 delete [] slot_method;
288 #if defined(CHECK_ARGS_NUMBER)
289 if (slotMethod != (TMethod *) -1 && slotMethod->GetNargsOpt() >= 0 &&
290 nsigargs < (slotMethod->GetNargs() - slotMethod->GetNargsOpt())) {
291 ::Error(
"TQObject::CheckConnectArgs",
292 "inconsistency in numbers of arguments");
293 delete [] slot_method;
299 delete [] slot_method;
309 class TQConnectionList :
public TList {
315 TQConnectionList(
const char *name, Int_t nsigargs) : TList()
316 { fName = name; fSignalArgs = nsigargs; }
317 virtual ~TQConnectionList();
319 Bool_t Disconnect(
void *receiver=0,
const char *slot_name=0);
320 Int_t GetNargs()
const {
return fSignalArgs; }
321 void ls(Option_t *option =
"")
const;
327 TQConnectionList::~TQConnectionList()
330 TQConnection *connection;
332 while ((connection = (TQConnection*)next())) {
334 connection->Remove(
this);
335 if (connection->IsEmpty())
delete connection;
344 Bool_t TQConnectionList::Disconnect(
void *receiver,
const char *slot_name)
346 TQConnection *connection = 0;
347 Bool_t return_value = kFALSE;
349 TObjLink *lnk = FirstLink();
353 connection = (TQConnection*)lnk->GetObject();
354 const char *name = connection->GetName();
355 void *obj = connection->GetReceiver();
357 if (!slot_name || !slot_name[0]
358 || !strcmp(name,slot_name)) {
360 if (!receiver || (receiver == obj)) {
361 return_value = kTRUE;
362 savlnk = lnk->Next();
365 connection->Remove(
this);
366 if (connection->IsEmpty()) SafeDelete(connection);
378 void TQConnectionList::ls(Option_t *option)
const
380 std::cout <<
"TQConnectionList:" <<
"\t" << GetName() << std::endl;
381 ((TQConnectionList*)
this)->R__FOR_EACH(TQConnection,Print)(option);
396 fListOfConnections = 0;
397 fSignalsBlocked = kFALSE;
404 TQObject::~TQObject()
410 if (fListOfSignals) {
411 fListOfSignals->Delete();
412 SafeDelete(fListOfSignals);
416 if (fListOfConnections) {
417 TIter next_connection(fListOfConnections);
418 TQConnection *connection;
420 while ((connection = (TQConnection*)next_connection())) {
421 TIter next_list(connection);
422 TQConnectionList *list;
423 while ((list = (TQConnectionList*)next_list())) {
424 list->Remove(connection);
425 if (list->IsEmpty()) SafeDelete(list);
428 SafeDelete(fListOfConnections);
435 TList *TQObject::GetListOfClassSignals()
const
439 qcl =
dynamic_cast<TQClass*
>(IsA());
441 return qcl ? qcl->fListOfSignals : 0;
451 void TQObject::CollectClassSignalLists(TList& list, TClass* cls)
453 TQClass *qcl =
dynamic_cast<TQClass*
>(cls);
456 if (qcl->fListOfSignals)
457 list.Add(qcl->fListOfSignals);
460 TIter next_base_class(cls->GetListOfBases());
462 while ((base = (TBaseClass*) next_base_class()))
464 CollectClassSignalLists(list, base->GetClassPointer());
477 void TQObject::HighPriority(
const char *signal_name,
const char *slot_name)
479 TQConnectionList *clist = (TQConnectionList*)
480 fListOfSignals->FindObject(signal_name);
484 fListOfSignals->Remove(clist);
485 fListOfSignals->AddFirst(clist);
488 TQConnection *con = (TQConnection*) clist->FindObject(slot_name);
491 clist->AddFirst(con);
503 void TQObject::LowPriority(
const char *signal_name,
const char *slot_name)
505 TQConnectionList *clist = (TQConnectionList*)
506 fListOfSignals->FindObject(signal_name);
510 fListOfSignals->Remove(clist);
511 fListOfSignals->AddLast(clist);
514 TQConnection *con = (TQConnection*) clist->FindObject(slot_name);
525 Bool_t TQObject::HasConnection(
const char *signal_name)
const
530 TString signal = CompressName(signal_name);
532 return (fListOfSignals->FindObject(signal) != 0);
539 Int_t TQObject::NumberOfSignals()
const
542 return fListOfSignals->GetSize();
549 Int_t TQObject::NumberOfConnections()
const
551 if (fListOfConnections)
552 return fListOfConnections->GetSize();
561 Bool_t TQObject::ConnectToClass(TQObject *sender,
568 if (!sender->IsA()->InheritsFrom(TQObject::Class()))
572 TString signal_name = CompressName(signal);
573 TString slot_name = CompressName(slot);
577 if ((nsigargs = CheckConnectArgs(sender, sender->IsA(), signal_name, cl, slot_name)) == -1)
580 if (!sender->fListOfSignals)
581 sender->fListOfSignals =
new THashList();
583 TQConnectionList *clist = (TQConnectionList*)
584 sender->fListOfSignals->FindObject(signal_name);
587 clist =
new TQConnectionList(signal_name, nsigargs);
588 sender->fListOfSignals->Add(clist);
592 TQConnection *connection = 0;
594 while ((connection = (TQConnection*)next())) {
595 if (!strcmp(slot_name,connection->GetName()) &&
596 (receiver == connection->GetReceiver()))
break;
600 connection =
new TQConnection(cl, receiver, slot_name);
603 if (!clist->FindObject(connection)) {
604 clist->Add(connection);
605 if (!connection->FindObject(clist)) connection->Add(clist);
606 sender->Connected(signal_name);
617 Bool_t TQObject::ConnectToClass(
const char *class_name,
623 TClass *sender = TClass::GetClass(class_name);
626 if (!sender || !sender->IsA()->InheritsFrom(TQObject::Class()))
629 TList *slist = ((TQClass*)sender)->fListOfSignals;
630 TString signal_name = CompressName(signal);
631 TString slot_name = CompressName(slot);
635 if ((nsigargs = CheckConnectArgs(0, sender, signal_name, cl, slot_name)) == -1)
639 ((TQClass*)sender)->fListOfSignals = slist =
new THashList();
641 TQConnectionList *clist = (TQConnectionList*) slist->FindObject(signal_name);
644 clist =
new TQConnectionList(signal_name, nsigargs);
648 TQConnection *connection = 0;
651 while ((connection = (TQConnection*)next())) {
652 if (!strcmp(slot_name,connection->GetName()) &&
653 (receiver == connection->GetReceiver()))
break;
657 connection =
new TQConnection(cl, receiver, slot_name);
660 if (!clist->FindObject(connection)) {
661 clist->Add(connection);
662 if (!connection->FindObject(clist)) connection->Add(clist);
663 ((TQClass*)sender)->Connected(signal_name);
701 Bool_t TQObject::Connect(TQObject *sender,
708 TClass *rcv_cl = TClass::GetClass(cl);
709 if (rcv_cl)
return ConnectToClass(sender, signal, rcv_cl, receiver, slot);
716 if (!sender->IsA()->InheritsFrom(TQObject::Class()))
720 TString signal_name = CompressName(signal);
721 TString slot_name = CompressName(slot);
725 if ((nsigargs = CheckConnectArgs(sender, sender->IsA(), signal_name, 0, slot_name)) == -1)
728 if (!sender->fListOfSignals) sender->fListOfSignals =
new THashList();
730 TQConnectionList *clist = (TQConnectionList*)
731 sender->fListOfSignals->FindObject(signal_name);
734 clist =
new TQConnectionList(signal_name, nsigargs);
735 sender->fListOfSignals->Add(clist);
738 TQConnection *connection = 0;
741 while ((connection = (TQConnection*)next())) {
742 if (!strcmp(slot_name,connection->GetName()) &&
743 (receiver == connection->GetReceiver()))
break;
747 connection =
new TQConnection(cl, receiver, slot_name);
750 if (!clist->FindObject(connection)) {
751 clist->Add(connection);
752 if (!connection->FindObject(clist)) connection->Add(clist);
753 sender->Connected(signal_name);
793 Bool_t TQObject::Connect(
const char *class_name,
800 TClass *rcv_cl = TClass::GetClass(cl);
801 if (rcv_cl)
return ConnectToClass(class_name, signal, rcv_cl, receiver,
808 TClass *sender = TClass::GetClass(class_name);
811 if (!sender || !sender->IsA()->InheritsFrom(TQObject::Class()))
814 TList *slist = ((TQClass*)sender)->fListOfSignals;
816 TString signal_name = CompressName(signal);
817 TString slot_name = CompressName(slot);
821 if ((nsigargs = CheckConnectArgs(0, sender, signal_name, 0, slot_name)) == -1)
825 slist = ((TQClass*)sender)->fListOfSignals =
new THashList();
828 TQConnectionList *clist = (TQConnectionList*)
829 slist->FindObject(signal_name);
832 clist =
new TQConnectionList(signal_name, nsigargs);
836 TQConnection *connection = 0;
839 while ((connection = (TQConnection*)next())) {
840 if (!strcmp(slot_name,connection->GetName()) &&
841 (receiver == connection->GetReceiver()))
break;
845 connection =
new TQConnection(cl, receiver, slot_name);
848 if (!clist->FindObject(connection)) {
849 clist->Add(connection);
850 if (!connection->FindObject(clist)) connection->Add(clist);
851 ((TQClass*)sender)->Connected(signal_name);
867 Bool_t TQObject::Connect(
const char *signal,
868 const char *receiver_class,
873 TString signal_name = CompressName(signal);
874 TString slot_name = CompressName(slot);
879 cl = TClass::GetClass(receiver_class);
881 if ((nsigargs = CheckConnectArgs(
this, IsA(), signal_name, cl, slot_name)) == -1)
884 if (!fListOfSignals) fListOfSignals =
new THashList();
886 TQConnectionList *clist = (TQConnectionList*)
887 fListOfSignals->FindObject(signal_name);
890 clist =
new TQConnectionList(signal_name, nsigargs);
891 fListOfSignals->Add(clist);
895 TQConnection *connection = 0;
897 while ((connection = (TQConnection*)next())) {
898 if (!strcmp(slot_name,connection->GetName()) &&
899 (receiver == connection->GetReceiver()))
break;
903 connection =
new TQConnection(receiver_class, receiver, slot_name);
906 if (!clist->FindObject(connection)) {
907 clist->Add(connection);
908 if (!connection->FindObject(clist)) connection->Add(clist);
909 Connected(signal_name);
958 Bool_t TQObject::Disconnect(TQObject *sender,
963 Bool_t return_value = kFALSE;
964 Bool_t next_return = kFALSE;
966 if (!sender->GetListOfSignals())
return kFALSE;
968 TString signal_name = CompressName(signal);
969 TString slot_name = CompressName(slot);
971 TQConnectionList *slist = 0;
972 TIter next_signal(sender->GetListOfSignals());
974 while ((slist = (TQConnectionList*)next_signal())) {
975 if (!signal || signal_name.IsNull()) {
976 next_return = slist->Disconnect(receiver,slot_name);
977 return_value = return_value || next_return;
979 if (slist->IsEmpty()) {
980 sender->GetListOfSignals()->Remove(slist);
983 }
else if (signal && !strcmp(signal_name,slist->GetName())) {
984 next_return = slist->Disconnect(receiver,slot_name);
985 return_value = return_value || next_return;
987 if (slist->IsEmpty()) {
988 sender->GetListOfSignals()->Remove(slist);
995 if (sender->GetListOfSignals() && sender->GetListOfSignals()->IsEmpty()) {
996 SafeDelete(sender->fListOfSignals);
1006 Bool_t TQObject::Disconnect(
const char *class_name,
1011 TClass *sender = TClass::GetClass(class_name);
1014 if (!sender || !sender->IsA()->InheritsFrom(TQObject::Class()))
1017 TQClass *qcl = (TQClass*)sender;
1018 return Disconnect(qcl, signal, receiver, slot);
1025 Bool_t TQObject::Disconnect(
const char *signal,
1029 return Disconnect(
this, signal, receiver, slot);
1035 void TQObject::Streamer(TBuffer &R__b)
1037 if (R__b.IsReading()) {
1047 Bool_t TQObject::AreAllSignalsBlocked()
1049 return fgAllSignalsBlocked;
1055 Bool_t TQObject::BlockAllSignals(Bool_t b)
1057 Bool_t ret = fgAllSignalsBlocked;
1058 fgAllSignalsBlocked = b;
1067 Bool_t ConnectCINT(TQObject *sender,
const char *signal,
const char *slot)
1069 TString str =
"ProcessLine(=";
1074 return TQObject::Connect(sender, signal,
"TInterpreter",
1075 gInterpreter, str.Data());