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

TGo4Slot.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 "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    // sequence of calls here is very important
00113    // First, we emit message from slot itself to inform all dependent slots
00114    // that we intend to delete our objects. After that all depenedent slots
00115    // are informed and we can remove object (with clean proxy), delete childs
00116    // and remove parameters
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 //  This is new sequence, but also has a problems
00158 //   SetBit(kStartDelete, kTRUE);
00159 
00160 //   Info("~TGo4Slot","DeleteChilds() %x", this);
00161 //   DeleteChilds();
00162 
00163 //   Info("~TGo4Slot","Event(this, evDelete) %x %s", this, GetFullName().Data());
00164 //   Event(this, evDelete);
00165 
00166 //   Info("~TGo4Slot","CleanProxy() %x", this);
00167 //   CleanProxy();
00168 
00169 //   Info("~TGo4Slot","Dettach from parent %x", this);
00170 //   if (fParent!=0) {
00171 //      fParent->RemoveChild(this);
00172 //      fParent = 0;
00173 //   }
00174 
00175 //   Info("~TGo4Slot","fPars.Delete() %x", this);
00176 //   fPars.Delete();
00177 
00178 
00179 
00180 
00181 // *********************************************************************
00182 //   This is old sequence. CleanProxy() breaks all dependency and delete objects first
00183 //   before message can be distributed over dependent slots
00184 //   CleanProxy();
00185 //   DeleteChilds();
00186 //   Event(this, evDelete);
00187 //   fPars.Delete();
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 //       Info("CleanProxy","Proxy %s", fProxy->ClassName());
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 //   cout << " TGo4Slot::GetSlotProxy " << name << "  slot = " << GetName()
00406 //        << " cont = " << (fProxy ? fProxy->ClassName() : "null") << endl;
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 //  cout << "ForwardEvent " << id <<" from " << GetName() << " to "
00566 //       << ((GetParent()!=0) ? GetParent()->GetName() : "null") << endl;
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 //----------------------------END OF GO4 SOURCE FILE ---------------------

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