00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4ObjectManager.h"
00015
00016 #include "TROOT.h"
00017 #include "TSystem.h"
00018 #include "TFile.h"
00019 #include "TTree.h"
00020 #include "TString.h"
00021 #include "TTimer.h"
00022
00023 #include "TGo4ObjectProxy.h"
00024 #include "TGo4Iter.h"
00025 #include "TGo4DirProxy.h"
00026 #include "TGo4TreeProxy.h"
00027 #include "TGo4FolderProxy.h"
00028 #include "TGo4LinkProxy.h"
00029
00030 class TGo4ObjManLink : public TObject {
00031 public:
00032 TGo4ObjManLink(TGo4Slot* source, TGo4Slot* target, Bool_t expandchilds) :
00033 TObject(),
00034 fxSource(source),
00035 fxTarget(target),
00036 fbExapndChilds(expandchilds)
00037 {
00038 }
00039
00040 Bool_t CheckEventSource(const TGo4Slot* evtsource)
00041 {
00042 if (evtsource==fxSource) return kTRUE;
00043 if (fbExapndChilds && evtsource->IsParent(fxSource)) return kTRUE;
00044 return kFALSE;
00045 }
00046
00047 TGo4Slot* GetSource() const { return fxSource; }
00048 TGo4Slot* GetTarget() const { return fxTarget; }
00049 Bool_t DoChildsExpand() const { return fbExapndChilds; }
00050
00051 protected:
00052 TGo4Slot* fxSource;
00053 TGo4Slot* fxTarget;
00054 Bool_t fbExapndChilds;
00055 };
00056
00057 class TGo4ObjManCleanup : public TObject {
00058 public:
00059 TGo4ObjManCleanup(TObject* obj, TGo4Slot* slot) :
00060 TObject(),
00061 fObject(obj),
00062 fSlot(slot)
00063 {
00064 }
00065 TObject* GetObject() const { return fObject; }
00066 TGo4Slot* GetSlot() const { return fSlot; }
00067 protected:
00068 TObject* fObject;
00069 TGo4Slot* fSlot;
00070 };
00071
00072
00073
00074
00075 TGo4ObjectManager::TGo4ObjectManager() :
00076 TGo4Slot(),
00077 fLinks(),
00078 fCleanups()
00079 {
00080 gROOT->GetListOfCleanups()->Add(this);
00081 }
00082
00083 TGo4ObjectManager::TGo4ObjectManager(const char* name, const char* title) :
00084 TGo4Slot(0, name, title),
00085 fLinks(),
00086 fCleanups()
00087 {
00088 gROOT->GetListOfCleanups()->Add(this);
00089 }
00090
00091 TGo4ObjectManager::~TGo4ObjectManager()
00092 {
00093 DeleteChilds();
00094
00095 fLinks.Delete();
00096
00097 fCleanups.Delete();
00098
00099 gROOT->GetListOfCleanups()->Remove(this);
00100 }
00101
00102 void TGo4ObjectManager::ProduceFullName(TString& name, TGo4Slot* toparent)
00103 {
00104 name = "";
00105 }
00106
00107 TGo4ObjectManager* TGo4ObjectManager::GetOM() const
00108 {
00109 return (TGo4ObjectManager*) this;
00110 }
00111
00112 void TGo4ObjectManager::MakeFolder(const char* pathname)
00113 {
00114 if ((pathname!=0) && (*pathname!=0))
00115 GetSlot(pathname, kTRUE);
00116 }
00117
00118 TGo4Slot* TGo4ObjectManager::Add(const char* pathname, TObject* obj, Bool_t owner, Bool_t canrename)
00119 {
00120 if (obj==0) return 0;
00121
00122 TGo4Slot* slot = MakeObjSlot(pathname, obj->GetName(), obj->ClassName());
00123
00124 if (slot!=0) {
00125 if (canrename && (strcmp(obj->GetName(),slot->GetName())!=0)) {
00126 TNamed* n = dynamic_cast<TNamed*> (obj);
00127 if (n!=0) n->SetName(slot->GetName());
00128 }
00129
00130 slot->SetProxy(new TGo4ObjectProxy(obj, owner));
00131 }
00132
00133 return slot;
00134 }
00135
00136 void TGo4ObjectManager::AddFile(const char* pathname, const char* filename)
00137 {
00138 AddDir(pathname, TFile::Open(filename), kTRUE, kTRUE);
00139 }
00140
00141 void TGo4ObjectManager::CloseFiles(const char* pathname)
00142 {
00143 TGo4Slot* slot = GetSlot(pathname);
00144 if (slot==0) return;
00145 for(int n=slot->NumChilds()-1;n>=0;n--) {
00146 TGo4Slot* subslot = slot->GetChild(n);
00147 TGo4DirProxy* dirproxy = dynamic_cast<TGo4DirProxy*> (subslot->GetProxy());
00148 if (dirproxy!=0)
00149 if (dirproxy->IsFile())
00150 delete subslot;
00151 }
00152 }
00153
00154
00155 void TGo4ObjectManager::AddDir(const char* pathname, TDirectory* dir, Bool_t owner, Bool_t readright)
00156 {
00157 if (dir==0) return;
00158
00159 const char* name = (dir->InheritsFrom(TFile::Class())) ?
00160 gSystem->BaseName(dir->GetName()) : dir->GetName();
00161
00162 TGo4Slot* slot = MakeObjSlot(pathname, name, dir->ClassName());
00163
00164 if (slot!=0)
00165 slot->SetProxy(new TGo4DirProxy(dir, readright, owner));
00166 }
00167
00168
00169 void TGo4ObjectManager::AddTree(const char* pathname, TTree* tree, Bool_t owner)
00170 {
00171 if (tree==0) return;
00172
00173 TGo4Slot* slot = MakeObjSlot(pathname, tree->GetName(), tree->ClassName());
00174
00175 if (slot!=0)
00176 slot->SetProxy(new TGo4TreeProxy(tree, owner));
00177 }
00178
00179 void TGo4ObjectManager::AddFolder(const char* pathname, TFolder* f, Bool_t owner)
00180 {
00181 if (f==0) return;
00182
00183 TGo4Slot* slot = MakeObjSlot(pathname, f->GetName(), f->ClassName());
00184 if (slot!=0)
00185 slot->SetProxy(new TGo4FolderProxy(f, owner, ""));
00186 }
00187
00188 void TGo4ObjectManager::AddROOTFolder(const char* pathname, const char* foldername)
00189 {
00190 TFolder* f = TGo4FolderProxy::LocateROOTFolder(foldername);
00191 if (f==0) return;
00192
00193 TGo4Slot* slot = MakeObjSlot(pathname, f->GetName(), f->ClassName());
00194
00195 if (slot!=0)
00196 slot->SetProxy(new TGo4FolderProxy(f, kFALSE, foldername));
00197 }
00198
00199 void TGo4ObjectManager::AddROOTFolders(const char* pathname, Bool_t selected)
00200 {
00201 if (selected) {
00202 TString name(pathname);
00203 if (name.Length()>0) name+="/root";
00204 else name="root";
00205 TGo4Slot* slot = GetSlot(name, kTRUE);
00206 if (slot==0) return;
00207 slot->SetTitle("ROOT folders");
00208 AddROOTFolder(name, "//root/Canvases");
00209 AddROOTFolder(name, "//root/Functions");
00210 AddROOTFolder(name, "//root/Tasks");
00211 AddROOTFolder(name, "//root/Specials");
00212 AddROOTFolder(name, "//root/ROOT Memory");
00213 AddROOTFolder(name, "//root/ROOT Files");
00214
00215 } else
00216 AddROOTFolder(pathname, "//root/");
00217 }
00218
00219 void TGo4ObjectManager::AddProxy(const char* pathname, TGo4Proxy* cont, const char* name, const char* title)
00220 {
00221 TGo4Slot* slot = MakeObjSlot(pathname, name, title);
00222 if (slot!=0) slot->SetProxy(cont);
00223 else delete cont;
00224 }
00225
00226 TGo4Proxy* TGo4ObjectManager::GetProxy(const char* name)
00227 {
00228 TGo4Slot* slot = GetSlot(name);
00229 return slot==0 ? 0 : slot->GetProxy();
00230 }
00231
00232
00233 TGo4Slot* TGo4ObjectManager::MakeObjSlot(const char* foldername, const char* name, const char* title)
00234 {
00235 TGo4Slot* folder = GetSlot(foldername, kTRUE);
00236 if (folder==0) return 0;
00237 if (folder->FindChild(name)==0)
00238 return new TGo4Slot(folder, name, title);
00239
00240 TString extraname;
00241 Int_t cycle = 1;
00242
00243 do {
00244 extraname.Form("%s_v%d", name, cycle++);
00245 } while (folder->FindChild(extraname.Data())!=0);
00246
00247 return new TGo4Slot(folder, extraname.Data(), title);
00248 }
00249
00250
00251 TGo4Slot* TGo4ObjectManager::AddLink(TGo4Slot* source, const char* pathname, const char* linkname, const char* linktitle)
00252 {
00253 if (source==0) return 0;
00254
00255 TGo4Slot* slot = MakeObjSlot(pathname, linkname, linktitle);
00256
00257
00258
00259 if (slot!=0)
00260 slot->SetProxy(new TGo4LinkProxy(source));
00261
00262 for(Int_t indx=fLinks.GetLast(); indx>=0; indx--) {
00263 TGo4ObjManLink* link = (TGo4ObjManLink*) fLinks.At(indx);
00264 if (link==0) continue;
00265
00266 TString namesrc, nametgt;
00267 link->GetSource()->ProduceFullName(namesrc);
00268 link->GetTarget()->ProduceFullName(nametgt);
00269
00270
00271
00272 }
00273
00274 return slot;
00275 }
00276
00277
00278 TGo4Slot* TGo4ObjectManager::AddLink(TGo4Slot* source, const char* pathname)
00279 {
00280
00281 if (source==0) return 0;
00282
00283 TGo4Slot* slot = MakeObjSlot(pathname, source->GetName(), source->GetTitle());
00284
00285
00286
00287
00288
00289
00290 if (slot!=0)
00291 slot->SetProxy(new TGo4LinkProxy(source));
00292
00293 return slot;
00294 }
00295
00296 TGo4Slot* TGo4ObjectManager::AddLink(const char* sourcename, const char* pathname)
00297 {
00298 return AddLink(GetSlot(sourcename), pathname);
00299 }
00300
00301 TGo4Slot* TGo4ObjectManager::GetLinked(TGo4Slot* link)
00302 {
00303 TGo4LinkProxy* linkcont = (link==0) ? 0 :
00304 dynamic_cast<TGo4LinkProxy*> (link->GetProxy());
00305
00306 return (linkcont!=0) ? linkcont->GetLink() : 0;
00307 }
00308
00309
00310 void TGo4ObjectManager::RegisterLink(TGo4Slot* source, TGo4Slot* target, Bool_t exapndchilds)
00311 {
00312 fLinks.Add(new TGo4ObjManLink(source, target, exapndchilds));
00313 }
00314
00315 void TGo4ObjectManager::UnregisterLink(TGo4Slot* target)
00316 {
00317 RemoveFromLinks(target);
00318 }
00319
00320 void TGo4ObjectManager::RemoveFromLinks(const TGo4Slot* slot)
00321 {
00322 Bool_t docompress = kFALSE;
00323 for (Int_t n=0;n<=fLinks.GetLast();n++) {
00324 TGo4ObjManLink* link = (TGo4ObjManLink*) fLinks[n];
00325 if ((link->GetTarget()==slot) || (link->GetSource()==slot)) {
00326 fLinks.Remove(link);
00327 delete link;
00328 docompress = kTRUE;
00329 }
00330 }
00331 if (docompress)
00332 fLinks.Compress();
00333 }
00334
00335 void TGo4ObjectManager::RetranslateEvent(TGo4Slot* source, Int_t id, void* param)
00336 {
00337 if (source==0) return;
00338
00339 for(Int_t indx=fLinks.GetLast(); indx>=0; indx--) {
00340 TGo4ObjManLink* link = (TGo4ObjManLink*) fLinks.At(indx);
00341 if (link==0) continue;
00342
00343 if (link->CheckEventSource(source)) {
00344 TGo4Slot* target = link->GetTarget();
00345
00346 if (gDebug>2)
00347 Info("RetranslateEvent","src = %p %s tgt = %p %s id = %d", source, source->GetFullName().Data(), target, target->GetFullName().Data(), id);
00348
00349 target->Event(source, id, param);
00350 }
00351 }
00352 }
00353
00354 void TGo4ObjectManager::Event(TGo4Slot* source, Int_t id, void* param)
00355 {
00356 if (gDebug>2)
00357 Info("Event","src %s id %d", source->GetFullName().Data(), id);
00358
00359 RetranslateEvent(source, id, param);
00360
00361 if (id==evDelete) {
00362 RemoveFromLinks(source);
00363 UnregisterObject(0, (TGo4Slot*) source);
00364 }
00365
00366 TGo4Slot::Event(source, id, param);
00367 }
00368
00369 void TGo4ObjectManager::SaveDataToFile(TFile* f, Bool_t onlyobjs, TGo4Slot* startslot)
00370 {
00371 Bool_t usefile = (f!=0);
00372
00373 TDirectory* olddir = gDirectory;
00374
00375 TDirectory* curdir = f;
00376
00377 if (startslot==0) startslot = this;
00378
00379 TGo4Iter iter(startslot, kTRUE);
00380
00381 bool isxml = (f!=0) && f->InheritsFrom("TXMLFile");
00382
00383 while (iter.next()) {
00384
00385 if (usefile && !isxml) {
00386 Int_t levelchange = iter.levelchange();
00387
00388 while ((levelchange++<0) && (curdir!=0)) {
00389 curdir = dynamic_cast<TDirectory*> (curdir->GetMother());
00390 }
00391 if (curdir==0) break;
00392
00393 if (iter.isfolder()) {
00394 curdir = curdir->mkdir(iter.getname(),"subdirectory");
00395 }
00396 if (curdir==0) break;
00397 }
00398
00399 TGo4Slot* slot = iter.getslot();
00400 if (slot!=0)
00401 slot->SaveData(curdir, onlyobjs);
00402 }
00403
00404 if (olddir!=0) olddir->cd();
00405 }
00406
00407 void TGo4ObjectManager::ReadDataFromFile(TFile* f)
00408 {
00409 Bool_t usefile = (f!=0);
00410
00411 TDirectory* olddir = gDirectory;
00412
00413 TDirectory* curdir = f;
00414
00415 TGo4Iter iter(this, kTRUE);
00416
00417 while (iter.next()) {
00418 if (usefile) {
00419 Int_t levelchange = iter.levelchange();
00420 while ((levelchange++<0) && (curdir!=0))
00421 curdir = dynamic_cast<TDirectory*> (curdir->GetMother());
00422 if (curdir==0) break;
00423 if (iter.isfolder())
00424 curdir->GetObject(iter.getname(), curdir);
00425 if (curdir==0) break;
00426 }
00427
00428 TGo4Slot* slot = iter.getslot();
00429 if (slot!=0)
00430 slot->ReadData(curdir);
00431 }
00432
00433 if (olddir!=0) olddir->cd();
00434 }
00435
00436 void TGo4ObjectManager::RegisterObjectWith(TObject* obj, TGo4Slot* slot)
00437 {
00438 if (obj==0) return;
00439 fCleanups.Add(new TGo4ObjManCleanup(obj, slot));
00440 obj->SetBit(kMustCleanup);
00441 }
00442
00443 void TGo4ObjectManager::UnregisterObject(TObject* obj, TGo4Slot* slot)
00444 {
00445 Bool_t compress = kFALSE;
00446 for(int indx=fCleanups.GetLast();indx>=0;indx--) {
00447 TGo4ObjManCleanup* entry = (TGo4ObjManCleanup*) fCleanups.At(indx);
00448 if (entry->GetSlot()!=slot) continue;
00449 if ((obj==0) || (entry->GetObject()==obj)) {
00450 fCleanups.Remove(entry);
00451 delete entry;
00452 compress = kTRUE;
00453 }
00454 }
00455 if (compress)
00456 fCleanups.Compress();
00457 }
00458
00459 void TGo4ObjectManager::RecursiveRemove(TObject* obj)
00460 {
00461 if ((obj==0) || (obj==this)) return;
00462
00463 Bool_t compress = kFALSE;
00464 for(int indx=fCleanups.GetLast();indx>=0;indx--) {
00465 TGo4ObjManCleanup* entry = (TGo4ObjManCleanup*) fCleanups.At(indx);
00466 if (entry==0) continue;
00467 if (entry->GetObject()==obj) {
00468
00469 fCleanups.Remove(entry);
00470
00471 entry->GetSlot()->RecursiveRemove(obj);
00472
00473 entry->GetSlot()->ForwardEvent(entry->GetSlot(), evObjDeleted, obj);
00474 delete entry;
00475 compress = kTRUE;
00476 }
00477 }
00478 if (compress)
00479 fCleanups.Compress();
00480 }
00481
00482 void TGo4ObjectManager::PrintSlots()
00483 {
00484 TGo4Iter iter(this, kTRUE);
00485 while (iter.next()) {
00486
00487 printf("%*c%s\n", (iter.level()+1)*2, ' ', iter.getname());
00488
00489
00490
00491 }
00492 }
00493
00494 Int_t TGo4ObjectManager::IterateSlots()
00495 {
00496 TGo4Iter iter(this);
00497 Int_t cnt = 0;
00498 while (iter.next()) cnt++;
00499 return cnt;
00500 }
00501
00502 void TGo4ObjectManager::DeleteSlot(const char* pathname)
00503 {
00504 TGo4Slot* slot = (TGo4Slot*) GetSlot(pathname);
00505 if (slot!=0) delete slot;
00506 }
00507
00508 Int_t TGo4ObjectManager::RequestObject(const char* source, const char* targetslot, Int_t waittime_millisec)
00509
00510
00511
00512 {
00513 TGo4Slot* tgtslot = GetSlot(targetslot);
00514 if (tgtslot==0) return 0;
00515
00516 TGo4Access* proxy = ProvideSlotAccess(source);
00517 if (proxy==0) return 0;
00518
00519 TClass* cl = proxy->GetObjectClass();
00520 if (cl==0) return 0;
00521
00522 tgtslot->ResetAssignFlag();
00523
00524 Int_t res = proxy->AssignObjectTo(this, targetslot);
00525
00526 if (res<2) delete proxy;
00527
00528 if ((res==2) && (waittime_millisec>0)) {
00529
00530 gSystem->ProcessEvents();
00531
00532 while ((tgtslot->GetAssignFlag()<0) && (waittime_millisec>0)) {
00533 gSystem->Sleep(10);
00534 waittime_millisec-=10;
00535 gSystem->ProcessEvents();
00536 }
00537
00538 res = (tgtslot->GetAssignFlag() == (Int_t) kTRUE) ? 1 : 0;
00539 }
00540
00541 return res;
00542 }
00543
00544 Bool_t TGo4ObjectManager::AssignObject(const char* path, TObject* obj, Bool_t ownership)
00545 {
00546 Bool_t res = kFALSE;
00547 TGo4Slot* tgtslot = GetSlot(path);
00548 if (tgtslot!=0) res = tgtslot->AssignObject(obj, ownership);
00549 else if (ownership) delete obj;
00550 return res;
00551 }