Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

TGo4ObjectManager.cxx

Go to the documentation of this file.
00001 //-------------------------------------------------------------
00002 //        Go4 Release Package v3.04-01 (build 30401)
00003 //                      28-November-2008
00004 //---------------------------------------------------------------
00005 //   The GSI Online Offline Object Oriented (Go4) Project
00006 //   Experiment Data Processing at EE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
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 //      AddDir(name, gROOT, kFALSE);
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 //   cout << "TGo4ObjectManager::AddLink in " << pathname << " source = " << source->GetFullName() << endl;
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 //      cout << "indx = " << indx
00272 //          << "  source = " << namesrc << " target = " << nametgt << endl;
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 //   cout << "Make link in path " << pathname << " with name " << source->GetName() << endl;
00287 
00288 //   if (slot!=0) cout << " slot = " << slot->GetName() <<
00289 //                        "  parent = " << slot->GetParent()->GetName() << endl;
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          // first
00470          fCleanups.Remove(entry);
00471 
00472          entry->GetSlot()->RecursiveRemove(obj);
00473 //         cout << "TGo4ObjectManager::RecursiveRemove " << entry->GetSlot()->GetFullName() << "  " << obj->GetName() << endl;
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 //      if (iter.getslot()!=0)
00491 //          iter.getslot()->PrintPars((iter.level()+1)*2 + 3);
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 // returns 0 when error
00511 //         1 when object assigned immidiatly
00512 //         2 when object will be obtained later
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 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Fri Nov 28 12:59:27 2008 for Go4-v3.04-1 by  doxygen 1.4.2