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