GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4ObjectManager.cxx
Go to the documentation of this file.
1 // $Id$
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4ObjectManager.h"
15 
16 #include "TROOT.h"
17 #include "TSystem.h"
18 #include "TFile.h"
19 #include "TTree.h"
20 #include "TFolder.h"
21 
22 #include "TGo4ObjectProxy.h"
23 #include "TGo4Iter.h"
24 #include "TGo4DirProxy.h"
25 #include "TGo4TreeProxy.h"
26 #include "TGo4FolderProxy.h"
27 #include "TGo4LinkProxy.h"
28 
29 class TGo4ObjManLink : public TObject {
30  public:
31  TGo4ObjManLink(TGo4Slot *source, TGo4Slot *target, Bool_t expandchilds) :
32  TObject(),
33  fxSource(source),
34  fxTarget(target),
35  fbExapndChilds(expandchilds)
36  {
37  }
38 
39  Bool_t CheckEventSource(const TGo4Slot *evtsource)
40  {
41  if (evtsource==fxSource) return kTRUE;
42  if (fbExapndChilds && evtsource->IsParent(fxSource)) return kTRUE;
43  return kFALSE;
44  }
45 
46  TGo4Slot *GetSource() const { return fxSource; }
47  TGo4Slot *GetTarget() const { return fxTarget; }
48  Bool_t DoChildsExpand() const { return fbExapndChilds; }
49 
50  protected:
51  TGo4Slot * fxSource{nullptr};
52  TGo4Slot * fxTarget{nullptr};
53  Bool_t fbExapndChilds{kFALSE};
54 };
55 
56 class TGo4ObjManCleanup : public TObject {
57  public:
58  TGo4ObjManCleanup(TObject *obj, TGo4Slot *slot) :
59  TObject(),
60  fObject(obj),
61  fSlot(slot)
62  {
63  }
64  TObject *GetObject() const { return fObject; }
65  TGo4Slot *GetSlot() const { return fSlot; }
66  protected:
67  TObject *fObject{nullptr};
68  TGo4Slot *fSlot{nullptr};
69 };
70 
71 
72 // ********************************************************************
73 
75  TGo4Slot(),
76  fLinks(),
77  fCleanups()
78 {
79  gROOT->GetListOfCleanups()->Add(this);
80 }
81 
82 TGo4ObjectManager::TGo4ObjectManager(const char *name, const char *title) :
83  TGo4Slot(nullptr, name, title),
84  fLinks(),
85  fCleanups()
86 {
87  gROOT->GetListOfCleanups()->Add(this);
88 }
89 
91 {
92  DeleteChilds();
93 
94  fLinks.Delete();
95 
96  fCleanups.Delete();
97 
98  gROOT->GetListOfCleanups()->Remove(this);
99 }
100 
101 void TGo4ObjectManager::ProduceFullName(TString &name, TGo4Slot *toparent)
102 {
103  name = "";
104 }
105 
107 {
108  return (TGo4ObjectManager*) this;
109 }
110 
111 void TGo4ObjectManager::MakeFolder(const char *pathname)
112 {
113  if (pathname && (*pathname != 0))
114  GetSlot(pathname, kTRUE);
115 }
116 
117 TGo4Slot *TGo4ObjectManager::Add(const char *pathname, TObject *obj, Bool_t owner, Bool_t canrename)
118 {
119  if (!obj) return nullptr;
120 
121  TGo4Slot *slot = MakeObjSlot(pathname, obj->GetName(), obj->ClassName());
122 
123  if (slot) {
124  if (canrename && (strcmp(obj->GetName(),slot->GetName()) != 0)) {
125  TNamed *n = dynamic_cast<TNamed*> (obj);
126  if (n) n->SetName(slot->GetName());
127  }
128 
129  slot->SetProxy(new TGo4ObjectProxy(obj, owner));
130  }
131 
132  return slot;
133 }
134 
135 void TGo4ObjectManager::AddFile(const char *pathname, const char *filename)
136 {
137  AddDir(pathname, TFile::Open(filename), kTRUE, kTRUE);
138 }
139 
140 void TGo4ObjectManager::CloseFiles(const char *pathname)
141 {
142  TGo4Slot *slot = GetSlot(pathname);
143  if (!slot) return;
144  for (int n = slot->NumChilds() - 1; n >= 0; n--) {
145  TGo4Slot *subslot = slot->GetChild(n);
146  TGo4DirProxy* dirproxy = dynamic_cast<TGo4DirProxy*> (subslot->GetProxy());
147  if (dirproxy)
148  if (dirproxy->IsFile())
149  delete subslot;
150  }
151 }
152 
153 
154 void TGo4ObjectManager::AddDir(const char *pathname, TDirectory *dir, Bool_t owner, Bool_t readright)
155 {
156  if (!dir) return;
157 
158  const char *name = (dir->InheritsFrom(TFile::Class())) ?
159  gSystem->BaseName(dir->GetName()) : dir->GetName();
160 
161  TGo4Slot *slot = MakeObjSlot(pathname, name, dir->ClassName());
162 
163  if (slot)
164  slot->SetProxy(new TGo4DirProxy(dir, readright, owner));
165 }
166 
167 
168 void TGo4ObjectManager::AddTree(const char *pathname, TTree *tree, Bool_t owner)
169 {
170  if (!tree) return;
171 
172  TGo4Slot *slot = MakeObjSlot(pathname, tree->GetName(), tree->ClassName());
173 
174  if (slot)
175  slot->SetProxy(new TGo4TreeProxy(tree, owner));
176 }
177 
178 void TGo4ObjectManager::AddFolder(const char *pathname, TFolder *f, Bool_t owner)
179 {
180  if (!f) return;
181 
182  TGo4Slot *slot = MakeObjSlot(pathname, f->GetName(), f->ClassName());
183  if (slot)
184  slot->SetProxy(new TGo4FolderProxy(f, owner, ""));
185 }
186 
187 void TGo4ObjectManager::AddROOTFolder(const char *pathname, const char *foldername)
188 {
189  TFolder *f = TGo4FolderProxy::LocateROOTFolder(foldername);
190  if (!f) return;
191 
192  TGo4Slot *slot = MakeObjSlot(pathname, f->GetName(), f->ClassName());
193 
194  if (slot)
195  slot->SetProxy(new TGo4FolderProxy(f, kFALSE, foldername));
196 }
197 
198 void TGo4ObjectManager::AddROOTFolders(const char *pathname, Bool_t selected)
199 {
200  if (selected) {
201  TString name(pathname);
202  if (name.Length()>0) name+="/root";
203  else name="root";
204  TGo4Slot *slot = GetSlot(name, kTRUE);
205  if (!slot) return;
206  slot->SetTitle("ROOT folders");
207  AddROOTFolder(name, "//root/Canvases");
208  AddROOTFolder(name, "//root/Functions");
209  AddROOTFolder(name, "//root/Tasks");
210  AddROOTFolder(name, "//root/Specials");
211  AddROOTFolder(name, "//root/ROOT Memory");
212  AddROOTFolder(name, "//root/ROOT Files");
213 // AddDir(name, gROOT, kFALSE);
214  } else
215  AddROOTFolder(pathname, "//root/");
216 }
217 
218 void TGo4ObjectManager::AddProxy(const char *pathname, TGo4Proxy* cont, const char *name, const char *title)
219 {
220  TGo4Slot *slot = MakeObjSlot(pathname, name, title);
221  if (slot) slot->SetProxy(cont);
222  else delete cont;
223 }
224 
226 {
227  TGo4Slot *slot = GetSlot(name);
228  return !slot ? nullptr : slot->GetProxy();
229 }
230 
231 TGo4Slot *TGo4ObjectManager::MakeObjSlot(const char *foldername, const char *name, const char *title)
232 {
233  TGo4Slot *folder = GetSlot(foldername, kTRUE);
234  if (!folder) return nullptr;
235  if (!folder->FindChild(name))
236  return new TGo4Slot(folder, name, title);
237 
238  TString extraname;
239  Int_t cycle = 1;
240 
241  do {
242  extraname.Form("%s_v%d", name, cycle++);
243  } while (folder->FindChild(extraname.Data()));
244 
245  return new TGo4Slot(folder, extraname.Data(), title);
246 }
247 
248 
249 TGo4Slot *TGo4ObjectManager::AddLink(TGo4Slot *source, const char *pathname, const char *linkname, const char *linktitle)
250 {
251  if (!source) return nullptr;
252 
253  TGo4Slot *slot = MakeObjSlot(pathname, linkname, linktitle);
254 
255  if (slot)
256  slot->SetProxy(new TGo4LinkProxy(source));
257 
258  for (Int_t indx = fLinks.GetLast(); indx >= 0; indx--) {
259  TGo4ObjManLink *link = (TGo4ObjManLink *)fLinks.At(indx);
260  if (!link)
261  continue;
262 
263  TString namesrc, nametgt;
264  link->GetSource()->ProduceFullName(namesrc);
265  link->GetTarget()->ProduceFullName(nametgt);
266  }
267 
268  return slot;
269 }
270 
271 TGo4Slot *TGo4ObjectManager::AddLink(TGo4Slot *source, const char *pathname)
272 {
273  if (!source) return nullptr;
274 
275  TGo4Slot *slot = MakeObjSlot(pathname, source->GetName(), source->GetTitle());
276 
277  if (slot)
278  slot->SetProxy(new TGo4LinkProxy(source));
279 
280  return slot;
281 }
282 
283 TGo4Slot *TGo4ObjectManager::AddLink(const char *sourcename, const char *pathname)
284 {
285  return AddLink(GetSlot(sourcename), pathname);
286 }
287 
289 {
290  TGo4LinkProxy* linkcont = !link ? nullptr :
291  dynamic_cast<TGo4LinkProxy*> (link->GetProxy());
292 
293  return linkcont ? linkcont->GetLink() : nullptr;
294 }
295 
296 
297 void TGo4ObjectManager::RegisterLink(TGo4Slot *source, TGo4Slot *target, Bool_t exapndchilds)
298 {
299  fLinks.Add(new TGo4ObjManLink(source, target, exapndchilds));
300 }
301 
303 {
304  RemoveFromLinks(target);
305 }
306 
308 {
309  Bool_t docompress = kFALSE;
310  for (Int_t n = 0; n <= fLinks.GetLast(); n++) {
311  TGo4ObjManLink *link = (TGo4ObjManLink *)fLinks[n];
312  if ((link->GetTarget() == slot) || (link->GetSource() == slot)) {
313  fLinks.Remove(link);
314  delete link;
315  docompress = kTRUE;
316  }
317  }
318  if (docompress)
319  fLinks.Compress();
320 }
321 
322 void TGo4ObjectManager::RetranslateEvent(TGo4Slot *source, Int_t id, void *param)
323 {
324  if (!source) return;
325 
326  for (Int_t indx = fLinks.GetLast(); indx >= 0; indx--) {
327  TGo4ObjManLink *link = (TGo4ObjManLink *)fLinks.At(indx);
328  if (!link) continue;
329 
330  if (link->CheckEventSource(source)) {
331  TGo4Slot *target = link->GetTarget();
332 
333  if (gDebug > 2)
334  Info("RetranslateEvent","src = %p %s tgt = %p %s id = %d", source, source->GetFullName().Data(), target, target->GetFullName().Data(), id);
335 
336  target->Event(source, id, param);
337  }
338  }
339 }
340 
341 void TGo4ObjectManager::Event(TGo4Slot *source, Int_t id, void *param)
342 {
343  if (gDebug>2)
344  Info("Event","src %s id %d", source->GetFullName().Data(), id);
345 
346  RetranslateEvent(source, id, param);
347 
348  if (id==evDelete) {
349  RemoveFromLinks(source);
350  UnregisterObject(nullptr, (TGo4Slot *) source);
351  }
352 
353  TGo4Slot::Event(source, id, param);
354 }
355 
356 void TGo4ObjectManager::SaveDataToFile(TFile *f, Bool_t onlyobjs, TGo4Slot *startslot)
357 {
358  Bool_t usefile = (f != nullptr);
359 
360  TDirectory *olddir = gDirectory;
361 
362  TDirectory *curdir = f;
363 
364  if (!startslot) startslot = this;
365 
366  TGo4Iter iter(startslot, kTRUE);
367 
368  bool isxml = f && f->InheritsFrom("TXMLFile");
369 
370  while (iter.next()) {
371 
372  if (usefile && !isxml) {
373  Int_t levelchange = iter.levelchange();
374 
375  while ((levelchange++<0) && curdir) {
376  curdir = dynamic_cast<TDirectory *> (curdir->GetMother());
377  }
378  if (!curdir) break;
379 
380  if (iter.isfolder()) {
381  curdir = curdir->mkdir(iter.getname(),"subdirectory");
382  }
383  if (!curdir) break;
384  }
385 
386  TGo4Slot *slot = iter.getslot();
387  if (slot)
388  slot->SaveData(curdir, onlyobjs);
389  }
390 
391  if (olddir) olddir->cd();
392 }
393 
395 {
396  Bool_t usefile = (f != nullptr);
397 
398  TDirectory *olddir = gDirectory;
399 
400  TDirectory *curdir = f;
401 
402  TGo4Iter iter(this, kTRUE);
403 
404  while (iter.next()) {
405  if (usefile) {
406  Int_t levelchange = iter.levelchange();
407  while ((levelchange++<0) && curdir)
408  curdir = dynamic_cast<TDirectory *> (curdir->GetMother());
409  if (!curdir) break;
410  if (iter.isfolder())
411  curdir->GetObject(iter.getname(), curdir);
412  if (!curdir) break;
413  }
414 
415  TGo4Slot *slot = iter.getslot();
416  if (slot)
417  slot->ReadData(curdir);
418  }
419 
420  if (olddir) olddir->cd();
421 }
422 
424 {
425  if (!obj) return;
426  fCleanups.Add(new TGo4ObjManCleanup(obj, slot));
427  obj->SetBit(kMustCleanup);
428 }
429 
431 {
432  Bool_t compress = kFALSE;
433  for (int indx = fCleanups.GetLast(); indx >= 0; indx--) {
434  TGo4ObjManCleanup *entry = (TGo4ObjManCleanup *)fCleanups.At(indx);
435  if (entry->GetSlot()!=slot) continue;
436  if (!obj || (entry->GetObject() == obj)) {
437  fCleanups.Remove(entry);
438  delete entry;
439  compress = kTRUE;
440  }
441  }
442  if (compress)
443  fCleanups.Compress();
444 }
445 
447 {
448  if (!obj || (obj == this)) return;
449 
450  Bool_t compress = kFALSE;
451  for (int indx = fCleanups.GetLast(); indx >= 0; indx--) {
452  TGo4ObjManCleanup *entry = (TGo4ObjManCleanup *)fCleanups.At(indx);
453  if (!entry) continue;
454  if (entry->GetObject() == obj) {
455  // first
456  fCleanups.Remove(entry);
457 
458  entry->GetSlot()->RecursiveRemove(obj);
459  entry->GetSlot()->ForwardEvent(entry->GetSlot(), evObjDeleted, obj);
460  delete entry;
461  compress = kTRUE;
462  }
463  }
464  if (compress)
465  fCleanups.Compress();
466 }
467 
469 {
470  TGo4Iter iter(this, kTRUE);
471  while (iter.next()) {
472  printf("%*c%s\n", (iter.level()+1)*2, ' ', iter.getname());
473 // if (iter.getslot())
474 // iter.getslot()->PrintPars((iter.level()+1)*2 + 3);
475  }
476 }
477 
479 {
480  TGo4Iter iter(this);
481  Int_t cnt = 0;
482  while (iter.next()) cnt++;
483  return cnt;
484 }
485 
486 void TGo4ObjectManager::DeleteSlot(const char *pathname)
487 {
488  TGo4Slot *slot = GetSlot(pathname);
489  if (slot) delete slot;
490 }
491 
492 Int_t TGo4ObjectManager::RequestObject(const char *source, const char *targetslot, Int_t waittime_millisec)
493 // returns 0 when error
494 // 1 when object assigned immediately
495 // 2 when object will be obtained later
496 {
497  TGo4Slot *tgtslot = GetSlot(targetslot);
498  if (!tgtslot) return 0;
499 
500  auto proxy = ProvideSlotAccess(source);
501  if (!proxy) return 0;
502 
503  TClass *cl = proxy->GetObjectClass();
504  if (!cl) return 0;
505 
506  tgtslot->ResetAssignFlag();
507 
508  Int_t res = proxy->AssignObjectTo(this, targetslot);
509 
510  if (res < 2)
511  proxy.reset(nullptr);
512  else
513  proxy.release(); // analysis proxy takes over ownership
514 
515  if ((res==2) && (waittime_millisec>0)) {
516 
517  gSystem->ProcessEvents();
518 
519  while ((tgtslot->GetAssignFlag()<0) && (waittime_millisec>0)) {
520  gSystem->Sleep(10);
521  waittime_millisec-=10;
522  gSystem->ProcessEvents();
523  }
524 
525  res = (tgtslot->GetAssignFlag() == (Int_t) kTRUE) ? 1 : 0;
526  }
527 
528  return res;
529 }
530 
531 Bool_t TGo4ObjectManager::AssignObject(const char *path, TObject *obj, Bool_t ownership)
532 {
533  Bool_t res = kFALSE;
534  TGo4Slot *tgtslot = GetSlot(path);
535  if (tgtslot)
536  res = tgtslot->AssignObject(obj, ownership);
537  else if (ownership)
538  delete obj;
539  return res;
540 }
TGo4ObjManCleanup(TObject *obj, TGo4Slot *slot)
TGo4Slot * GetChild(Int_t n) const
Definition: TGo4Slot.h:77
TGo4Slot * GetSlot() const
Bool_t IsParent(const TGo4Slot *slot) const
Definition: TGo4Slot.cxx:178
Int_t NumChilds() const
Definition: TGo4Slot.h:76
void SaveData(TDirectory *dir, Bool_t onlyobjs=kFALSE)
Definition: TGo4Slot.cxx:410
void UnregisterObject(TObject *obj, TGo4Slot *slot)
Bool_t IsFile() const
void SetProxy(TGo4Proxy *cont)
Definition: TGo4Slot.cxx:296
Int_t RequestObject(const char *source, const char *targetslot, Int_t waittime_millisec=0)
void AddFile(const char *pathname, const char *filename)
Bool_t isfolder()
Definition: TGo4Iter.cxx:109
void UnregisterLink(TGo4Slot *target)
TGo4Slot * FindChild(const char *name) const
Definition: TGo4Slot.cxx:245
void MakeFolder(const char *pathname)
void AddROOTFolder(const char *pathname, const char *foldername)
TGo4Proxy * GetProxy() const
Definition: TGo4Slot.h:93
void RegisterLink(TGo4Slot *source, TGo4Slot *target, Bool_t exapndchilds=kFALSE)
void ResetAssignFlag()
Definition: TGo4Slot.h:103
TGo4ObjectManager * GetOM() const override
TGo4Slot()
Definition: TGo4Slot.cxx:61
void RegisterObjectWith(TObject *obj, TGo4Slot *slot)
void ProduceFullName(TString &name, TGo4Slot *toparent=nullptr) override
TGo4Slot * getslot() const
Definition: TGo4Iter.cxx:166
void DeleteSlot(const char *pathname)
TString GetFullName(TGo4Slot *toparent=nullptr)
Definition: TGo4Slot.cxx:274
void AddFolder(const char *pathname, TFolder *folder, Bool_t owner=kFALSE)
static TFolder * LocateROOTFolder(const char *rootfolder)
virtual void Event(TGo4Slot *source, Int_t id, void *param=nullptr)
Definition: TGo4Slot.cxx:555
Int_t GetAssignFlag() const
Definition: TGo4Slot.h:102
TGo4Slot * MakeObjSlot(const char *foldername, const char *name=nullptr, const char *title=nullptr)
TGo4Slot * GetSlot(const char *name, Bool_t force=kFALSE)
Definition: TGo4Slot.cxx:451
void AddTree(const char *pathname, TTree *tree, Bool_t owner=kFALSE)
void AddROOTFolders(const char *pathname, Bool_t selected=kTRUE)
virtual Bool_t AssignObject(const char *path, TObject *obj, Bool_t ownership)
void RecursiveRemove(TObject *obj) override
Definition: TGo4Slot.cxx:571
void AddDir(const char *pathname, TDirectory *dir, Bool_t owner=kFALSE, Bool_t readright=kFALSE)
const char * getname()
Definition: TGo4Iter.cxx:115
void RetranslateEvent(TGo4Slot *source, Int_t id, void *param=nullptr)
void AddProxy(const char *pathname, TGo4Proxy *cont, const char *name, const char *title="title")
void ReadData(TDirectory *dir)
Definition: TGo4Slot.cxx:416
Int_t level() const
Definition: TGo4Iter.cxx:156
void CloseFiles(const char *pathname)
std::unique_ptr< TGo4Access > ProvideSlotAccess(const char *name)
Definition: TGo4Slot.cxx:395
void RecursiveRemove(TObject *obj) override
void SaveDataToFile(TFile *f, Bool_t onlyobjs=kFALSE, TGo4Slot *startslot=nullptr)
Bool_t AssignObject(TObject *obj, Bool_t owner)
Definition: TGo4Slot.cxx:344
void ForwardEvent(TGo4Slot *source, Int_t id, void *param=nullptr)
Definition: TGo4Slot.cxx:565
void DeleteChilds(const char *startedwith=nullptr)
Definition: TGo4Slot.cxx:202
TGo4Slot * GetLinked(TGo4Slot *link)
TObject * GetObject() const
void RemoveFromLinks(const TGo4Slot *slot)
TObjArray fCleanups
list of links between slots
TGo4Slot * Add(const char *pathname, TObject *obj, Bool_t owner=kFALSE, Bool_t canrename=kFALSE)
TGo4Slot * GetLink() const
Definition: TGo4LinkProxy.h:45
void ReadDataFromFile(TFile *f)
void Event(TGo4Slot *source, Int_t id, void *param=nullptr) override
TGo4Slot * AddLink(TGo4Slot *source, const char *pathname, const char *linkname, const char *linktitle)
Bool_t next(Bool_t goesinto=kTRUE)
Definition: TGo4Iter.cxx:44
Int_t levelchange() const
Definition: TGo4Iter.h:41
virtual void ProduceFullName(TString &name, TGo4Slot *toparent=nullptr)
Definition: TGo4Slot.cxx:264