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