00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4Slot.h"
00015
00016 #include <stdio.h>
00017 #include <string.h>
00018 #include <stdlib.h>
00019 #include "TROOT.h"
00020 #include "TClass.h"
00021
00022 #include "TGo4Iter.h"
00023 #include "TGo4ObjectProxy.h"
00024
00025 class TGo4SlotIter : public TGo4LevelIter {
00026 public:
00027 TGo4SlotIter() : TGo4LevelIter(), fSlot(0), fIndex(-1) {}
00028
00029 TGo4SlotIter(const TGo4Slot* slot) : TGo4LevelIter(), fSlot(slot), fIndex(-1) {}
00030
00031 virtual ~TGo4SlotIter() {}
00032
00033 virtual Bool_t next()
00034 { return (fSlot!=0) && (++fIndex<fSlot->NumChilds()); }
00035
00036 virtual Bool_t isfolder() { return curSlot()->HasSubLevels(); }
00037
00038 virtual Bool_t isslotsfolder() { return curSlot()->HasSlotsSubLevels(); }
00039
00040 virtual TGo4LevelIter* subiterator() { return curSlot()->MakeLevelIter(); }
00041
00042 virtual TGo4Slot* getslot() { return curSlot(); }
00043
00044 virtual const char* name() { return curSlot()->GetName(); }
00045
00046 virtual const char* info() { return curSlot()->GetInfo(); }
00047
00048 virtual Int_t sizeinfo() { return curSlot()->GetSizeInfo(); }
00049
00050 virtual Int_t GetKind() { return curSlot()->GetSlotKind(); }
00051
00052 virtual const char* GetClassName() { return curSlot()->GetSlotClassName(); }
00053
00054 protected:
00055 TGo4Slot* curSlot() const { return fSlot->GetChild(fIndex); }
00056
00057 const TGo4Slot* fSlot;
00058 Int_t fIndex;
00059 };
00060
00061
00062
00063
00064 TGo4Slot::TGo4Slot() :
00065 TNamed(),
00066 fParent(0),
00067 fChilds(0),
00068 fPars(),
00069 fProxy(0),
00070 fAssignFlag(-1)
00071 {
00072 SetBit(kStartDelete, kFALSE);
00073 }
00074
00075 TGo4Slot::TGo4Slot(TGo4Slot* parent) :
00076 TNamed(),
00077 fParent(parent),
00078 fChilds(0),
00079 fPars(),
00080 fProxy(0),
00081 fAssignFlag(-1)
00082 {
00083 SetBit(kStartDelete, kFALSE);
00084
00085 if (parent!=0)
00086 parent->AddChild(this);
00087
00088 Event(this, evCreate);
00089 }
00090
00091 TGo4Slot::TGo4Slot(TGo4Slot* parent, const char* name, const char* title) :
00092 TNamed(name, title),
00093 fParent(parent),
00094 fChilds(0),
00095 fPars(),
00096 fProxy(0),
00097 fAssignFlag(-1)
00098 {
00099 SetBit(kStartDelete, kFALSE);
00100
00101 if (parent!=0)
00102 parent->AddChild(this);
00103
00104 Event(this, evCreate);
00105 }
00106
00107 TGo4Slot::~TGo4Slot()
00108 {
00109
00110
00111
00112
00113
00114
00115 if (gDebug>1) Info("~TGo4Slot","%p Starting name = %s", this, GetFullName().Data());
00116
00117 SetBit(kStartDelete, kTRUE);
00118
00119 if (gDebug>1) Info("~TGo4Slot","%p CleanProxy()", this);
00120 CleanProxy();
00121
00122 if (gDebug>1) Info("~TGo4Slot","%p Event(this, evDelete)", this);
00123 Event(this, evDelete);
00124
00125 if (gDebug>1) Info("~TGo4Slot","%p DeleteChilds()", this);
00126 DeleteChilds();
00127
00128 if (gDebug>1) Info("~TGo4Slot","%p Detach from parent", this);
00129 if (fParent!=0) {
00130 fParent->RemoveChild(this);
00131 fParent = 0;
00132 }
00133
00134 if (gDebug>1) Info("~TGo4Slot","%p fPars.Delete()", this);
00135 fPars.Delete();
00136
00137 if (fChilds!=0) {
00138 if (gDebug>1) Info("~TGo4Slot","%p Detach rest children", this);
00139 for (Int_t n=0;n<=fChilds->GetLast();n++) {
00140 TGo4Slot* child = (TGo4Slot*) fChilds->At(n);
00141 if (child==0) continue;
00142 child->fParent = 0;
00143 fChilds->Remove(child);
00144 }
00145
00146 delete fChilds;
00147 fChilds = 0;
00148 }
00149
00150 if (gDebug>1) Info("~TGo4Slot","%p Finish", this);
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 }
00186
00187 void TGo4Slot::Delete(Option_t *)
00188 {
00189 if (DoingDelete()) return;
00190
00191 delete this;
00192 }
00193
00194 Bool_t TGo4Slot::IsParent(const TGo4Slot* slot) const
00195 {
00196 TGo4Slot* parent = GetParent();
00197 while (parent!=0) {
00198 if (parent==slot) return kTRUE;
00199 parent = parent->GetParent();
00200 }
00201 return kFALSE;
00202 }
00203
00204 void TGo4Slot::DeleteChild(const char* name)
00205 {
00206 TGo4Slot* child = FindChild(name);
00207 if (child==0) return;
00208
00209 if (!child->DoingDelete())
00210 delete child;
00211
00212 if ((NumChilds()==0) && (fChilds!=0)) {
00213 delete fChilds;
00214 fChilds = 0;
00215 }
00216 }
00217
00218 void TGo4Slot::DeleteChilds(const char* startedwith)
00219 {
00220 UInt_t len = startedwith==0 ? 0 : strlen(startedwith);
00221
00222 for(Int_t n = NumChilds()-1; n>=0; n--) {
00223 TGo4Slot* child = GetChild(n);
00224 if (child==0) continue;
00225
00226 Bool_t flag = (len==0) ||
00227 ((len<strlen(child->GetName())) &&
00228 (strncmp(child->GetName(), startedwith, len)==0));
00229
00230 if (!flag) continue;
00231
00232 if (!child->DoingDelete())
00233 delete child;
00234 }
00235
00236 if ((fChilds!=0) && (NumChilds()==0)) {
00237 delete fChilds;
00238 fChilds = 0;
00239 }
00240 }
00241
00242 Int_t TGo4Slot::GetIndexOf(TGo4Slot* child)
00243 {
00244 if (child==0) return -1;
00245 for(int n=0;n<NumChilds();n++)
00246 if (GetChild(n)==child) return n;
00247 return -1;
00248 }
00249
00250
00251 TGo4Slot* TGo4Slot::GetNextChild(TGo4Slot* child)
00252 {
00253 if (child==0) return 0;
00254 for(int n=0;n<NumChilds()-1;n++)
00255 if (GetChild(n)==child) return GetChild(n+1);
00256 return 0;
00257 }
00258
00259 TGo4Slot* TGo4Slot::FindChild(const char* name)
00260 {
00261 if ((name==0) || (*name==0)) return 0;
00262 Int_t num = NumChilds();
00263 for(Int_t n=0;n<num;n++) {
00264 TGo4Slot* slot = GetChild(n);
00265 if (strcmp(slot->GetName(), name)==0) return slot;
00266 }
00267 return 0;
00268 }
00269
00270
00271 TGo4Slot* TGo4Slot::GetNext()
00272 {
00273 TGo4Slot* parent = GetParent();
00274 return (parent==0) ? 0 : parent->GetNextChild(this);
00275 }
00276
00277 void TGo4Slot::ProduceFullName(TString& name, TGo4Slot* toparent)
00278 {
00279 if ((GetParent()!=0) && (GetParent()!=toparent)) {
00280 GetParent()->ProduceFullName(name, toparent);
00281 if (name.Length()>0) name += "/";
00282 name+=GetName();
00283 } else
00284 name = GetName();
00285 }
00286
00287 TString TGo4Slot::GetFullName(TGo4Slot* toparent)
00288 {
00289 TString res;
00290 ProduceFullName(res, toparent);
00291 return res;
00292 }
00293
00294
00295 TGo4ObjectManager* TGo4Slot::GetOM() const
00296 {
00297 return GetParent() ? GetParent()->GetOM() : 0;
00298 }
00299
00300 void TGo4Slot::CleanProxy()
00301 {
00302 if (fProxy!=0) {
00303
00304 fProxy->Finalize(this);
00305 delete fProxy;
00306 fProxy = 0;
00307 }
00308 }
00309
00310 void TGo4Slot::SetProxy(TGo4Proxy* cont)
00311 {
00312 CleanProxy();
00313
00314 fProxy = cont;
00315
00316 const char* contclass = (fProxy!=0) ? fProxy->ClassName() : 0;
00317
00318 SetPar("::ProxyClass", contclass);
00319
00320 if (fProxy!=0) {
00321 fProxy->Initialize(this);
00322 Event(this, evContAssigned);
00323 }
00324 }
00325
00326 const char* TGo4Slot::GetInfo()
00327 {
00328 const char* info = 0;
00329 if (fProxy!=0)
00330 info = fProxy->GetContainedObjectInfo();
00331 if (info==0) info = GetTitle();
00332 return info;
00333 }
00334
00335 Int_t TGo4Slot::GetSizeInfo()
00336 {
00337 Int_t sz = -1;
00338 if (fProxy!=0)
00339 sz = fProxy->GetObjectSizeInfo();
00340 return sz;
00341 }
00342
00343 Int_t TGo4Slot::GetSlotKind() const
00344 {
00345 return (fProxy!=0) ? fProxy->GetObjectKind() : TGo4Access::kndFolder;
00346 }
00347
00348 const char* TGo4Slot::GetSlotClassName() const
00349 {
00350 return (fProxy!=0) ? fProxy->GetContainedClassName() : 0;
00351 }
00352
00353 Bool_t TGo4Slot::IsAcceptObject(TClass* cl)
00354 {
00355 return fProxy!=0 ? fProxy->IsAcceptObject(cl) : kFALSE;
00356 }
00357
00358 Bool_t TGo4Slot::AssignObject(TObject* obj, Bool_t owner)
00359 {
00360 fAssignFlag = kFALSE;
00361 if (fProxy!=0)
00362 fAssignFlag = fProxy->AssignObject(this, obj, owner);
00363 else
00364 if (owner) delete obj;
00365
00366 return (fAssignFlag == (Int_t) kTRUE);
00367 }
00368
00369 TObject* TGo4Slot::GetAssignedObject()
00370 {
00371 if (fProxy==0) return 0;
00372 return fProxy->GetAssignedObject();
00373 }
00374
00375 void TGo4Slot::Update(Bool_t strong)
00376 {
00377 if (fProxy!=0)
00378 fProxy->Update(this, strong);
00379
00380 for(int n=0;n<NumChilds();n++)
00381 GetChild(n)->Update(strong);
00382 }
00383
00384
00385 Bool_t TGo4Slot::HasSubLevels() const
00386 {
00387 if ((fProxy!=0) && fProxy->Use()) return fProxy->HasSublevels();
00388
00389 return HasSlotsSubLevels();
00390 }
00391
00392 Bool_t TGo4Slot::HasSlotsSubLevels() const
00393 {
00394 return NumChilds()>0;
00395 }
00396
00397 TGo4LevelIter* TGo4Slot::MakeLevelIter() const
00398 {
00399 TGo4LevelIter* res = 0;
00400
00401 if ((fProxy!=0) && fProxy->Use())
00402 res = fProxy->MakeIter();
00403
00404 if ((res==0) && (NumChilds() > 0)) res = new TGo4SlotIter(this);
00405
00406 return res;
00407 }
00408
00409 TGo4Access* TGo4Slot::ProvideSlotAccess(const char* name)
00410 {
00411
00412
00413
00414 if ((fProxy!=0) && fProxy->Use())
00415 return fProxy->MakeProxy(name);
00416
00417 if ((name==0) || (*name==0)) return new TGo4ObjectAccess(this);
00418
00419 const char* subname = 0;
00420
00421 TGo4Slot* subslot = DefineSubSlot(name, subname);
00422
00423 return (subslot==0) ? 0 : subslot->ProvideSlotAccess(subname);
00424 }
00425
00426 void TGo4Slot::SaveData(TDirectory* dir, Bool_t onlyobjs)
00427 {
00428 if (fProxy!=0)
00429 fProxy->WriteData(this, dir, onlyobjs);
00430 }
00431
00432 void TGo4Slot::ReadData(TDirectory* dir)
00433 {
00434 CleanProxy();
00435
00436 const char* contclass = GetPar("::ProxyClass");
00437 TClass* cl = (contclass==0) ? 0 : gROOT->GetClass(contclass);
00438 if (cl==0) return;
00439
00440 TGo4Proxy* cont = (TGo4Proxy*) cl->New();
00441
00442 cont->ReadData(this, dir);
00443
00444 SetProxy(cont);
00445 }
00446
00447 TGo4Slot* TGo4Slot::DefineSubSlot(const char* name, const char* &subname) const
00448 {
00449 Int_t len = 0;
00450
00451 const char* spos = strchr(name,'/');
00452
00453 if (spos==0) { len = strlen(name); subname=0; }
00454 else { len = spos-name; subname=spos+1; }
00455 UInt_t ulen = (UInt_t) len;
00456
00457 Int_t num = NumChilds();
00458 for(int n=0;n<num;n++) {
00459 TGo4Slot* slot = GetChild(n);
00460 const char* slotname = slot->GetName();
00461 if ((strlen(slotname)==ulen) && (strncmp(slotname, name, len)==0)) return slot;
00462 }
00463
00464 return 0;
00465 }
00466
00467 TGo4Slot* TGo4Slot::GetSlot(const char* name, Bool_t force)
00468 {
00469 if ((name==0) || (*name==0)) return this;
00470
00471 const char* subname = 0;
00472
00473 TGo4Slot* subslot = DefineSubSlot(name, subname);
00474
00475 if ((subslot==0) && force) {
00476 TString newname;
00477 if (subname==0) newname = name;
00478 else newname.Append(name, subname-name-1);
00479 subslot = new TGo4Slot(this, newname.Data(), "folder");
00480 }
00481
00482 return subslot==0 ? 0 : subslot->GetSlot(subname, force);
00483 }
00484
00485 TGo4Slot* TGo4Slot::FindSlot(const char* fullpath, const char** subname)
00486 {
00487
00488 while ((fullpath!=0) && (strlen(fullpath)>2)) {
00489
00490 if (strncmp(fullpath, "./", 2) == 0) { fullpath += 2; continue; }
00491
00492
00493 if ((strncmp(fullpath, "../", 3) == 0) && GetParent())
00494 return GetParent()->FindSlot(fullpath + 3, subname);
00495
00496 break;
00497 }
00498
00499 TGo4Slot* slot = GetSlot(fullpath);
00500 if (slot!=0) {
00501 if (subname!=0) *subname = 0;
00502 return slot;
00503 }
00504
00505 const char* curname = fullpath;
00506 TGo4Slot* curslot = this;
00507
00508 while (curslot!=0) {
00509 const char* nextname = 0;
00510 TGo4Slot* nextslot = curslot->DefineSubSlot(curname, nextname);
00511 if (nextslot==0) break;
00512 curslot = nextslot;
00513 curname = nextname;
00514 }
00515
00516 if (subname!=0) *subname = curname;
00517 return curslot;
00518 }
00519
00520
00521 Bool_t TGo4Slot::ShiftSlotBefore(TGo4Slot* slot, TGo4Slot* before)
00522 {
00523 if (fChilds==0) return kFALSE;
00524 Int_t indx1 = (before==0) ? -1 : fChilds->IndexOf(before);
00525 Int_t indx2 = (slot==0) ? -1 : fChilds->IndexOf(slot);
00526 if ((indx1<0) || (indx2<0) || (indx1>indx2)) return kFALSE;
00527 if (indx1==indx2) return kTRUE;
00528
00529 for (int n=indx2;n>indx1;n--)
00530 (*fChilds)[n] = (*fChilds)[n-1];
00531
00532 (*fChilds)[indx1] = slot;
00533
00534 return kTRUE;
00535 }
00536
00537 Bool_t TGo4Slot::ShiftSlotAfter(TGo4Slot* slot, TGo4Slot* after)
00538 {
00539 if (fChilds==0) return kFALSE;
00540 Int_t indx1 = (slot==0) ? -1 : fChilds->IndexOf(slot);
00541 Int_t indx2 = (after==0) ? -1 : fChilds->IndexOf(after);
00542 if ((indx1<0) || (indx2<0) || (indx1>indx2)) return kFALSE;
00543
00544 if (indx1==indx2) return kTRUE;
00545
00546 for (int n=indx1;n<indx2;n++)
00547 (*fChilds)[n] = (*fChilds)[n+1];
00548 (*fChilds)[indx2] = slot;
00549
00550 return kTRUE;
00551 }
00552
00553 void TGo4Slot::AddChild(TGo4Slot* child)
00554 {
00555 if (child==0) return;
00556 if (fChilds==0) fChilds = new TObjArray;
00557 fChilds->Add(child);
00558 }
00559
00560 void TGo4Slot::RemoveChild(TGo4Slot* child)
00561 {
00562 if ((child==0) || (fChilds==0)) return;
00563 fChilds->Remove(child);
00564 fChilds->Compress();
00565 if (fChilds->GetLast()<0) {
00566 delete fChilds;
00567 fChilds = 0;
00568 }
00569 }
00570
00571 void TGo4Slot::Event(TGo4Slot* source, Int_t id, void* param)
00572 {
00573 Bool_t doforward = kTRUE;
00574
00575 if (fProxy!=0)
00576 doforward = fProxy->ProcessEvent(this, source, id, param);
00577
00578 if (doforward) ForwardEvent(source, id, param);
00579 }
00580
00581 void TGo4Slot::ForwardEvent(TGo4Slot* source, Int_t id, void* param)
00582 {
00583
00584
00585
00586 if (GetParent()!=0)
00587 GetParent()->Event(source, id, param);
00588 }
00589
00590 void TGo4Slot::RecursiveRemove(TObject* obj)
00591 {
00592 if (fProxy!=0)
00593 if (fProxy->RemoveRegisteredObject(obj))
00594 delete this;
00595 }
00596
00597 void TGo4Slot::Print(Option_t* option) const
00598 {
00599 TGo4Iter iter((TGo4Slot*) this);
00600 while (iter.next()) {
00601 printf("%*c%s%s - %s\n", (iter.level()+1)*2, ' ', iter.getname(), (iter.isfolder() ? "/" : ""), iter.getinfo());
00602 }
00603 }
00604
00605 void TGo4Slot::SetPar(const char* name, const char* value)
00606 {
00607 if ((name==0) || (*name==0)) return;
00608 if (value==0) { RemovePar(name); return; }
00609
00610 TNamed* par = (TNamed*) fPars.FindObject(name);
00611 if (par!=0)
00612 par->SetTitle(value);
00613 else
00614 fPars.Add(new TNamed(name,value));
00615 }
00616
00617 const char* TGo4Slot::GetPar(const char* name) const
00618 {
00619 if ((name==0) || (*name==0)) return 0;
00620 TNamed* par = (TNamed*) fPars.FindObject(name);
00621 return (par!=0) ? par->GetTitle() : 0;
00622 }
00623
00624 void TGo4Slot::RemovePar(const char* name)
00625 {
00626 if ((name==0) || (*name==0)) return;
00627 TNamed* par = (TNamed*) fPars.FindObject(name);
00628 if (par!=0) {
00629 fPars.Remove(par);
00630 fPars.Compress();
00631 delete par;
00632 }
00633 }
00634
00635 void TGo4Slot::SetIntPar(const char* name, Int_t value)
00636 {
00637 TString buf;
00638 buf.Form("%d",value);
00639 SetPar(name, buf.Data());
00640 }
00641
00642 Bool_t TGo4Slot::GetIntPar(const char* name, Int_t& value)
00643 {
00644 const char* strvalue = GetPar(name);
00645 if (strvalue==0) return kFALSE;
00646 value = atoi(strvalue);
00647 return kTRUE;
00648 }
00649
00650 void TGo4Slot::PrintPars(Int_t level)
00651 {
00652 for (int n=0;n<=fPars.GetLast();n++) {
00653 TNamed* par = (TNamed*) fPars.At(n);
00654 if (par!=0)
00655 printf("%*c%s = %s\n", level, ' ', par->GetName(), par->GetTitle());
00656 }
00657 }
00658
00659 const char* TGo4Slot::FindFolderSeparator(const char* name)
00660 {
00661 return name==0 ? 0 : strrchr(name,'/');
00662 }
00663
00664 void TGo4Slot::ProduceFolderAndName(const char* fullname, TString& foldername, TString& objectname)
00665 {
00666 const char* rslash = FindFolderSeparator(fullname);
00667 foldername = "";
00668
00669 if (rslash==0) {
00670 objectname = fullname;
00671 } else {
00672 foldername.Append(fullname, rslash-fullname);
00673 objectname = (rslash+1);
00674 }
00675 }