]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Implemented proper reference management accross render-elements, render-element-lists...
authormtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 10 Jul 2006 17:36:03 +0000 (17:36 +0000)
committermtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 10 Jul 2006 17:36:03 +0000 (17:36 +0000)
EVE/Reve/RenderElement.cxx
EVE/Reve/RenderElement.h

index cf9e2c389320e8c1c7c3c25e1a155cf4f052e9e6..91a45ae0a18187aceb2f2fdaaea817efb6233b97 100644 (file)
@@ -8,34 +8,76 @@
 #include <TGListTree.h>
 #include <THashList.h>
 
-using namespace Reve;
 using namespace Reve;
 
 //______________________________________________________________________
-// Reve
+// RenderElement
+//
 //
 
 ClassImp(RenderElement)
 
-RenderElement::RenderElement()
-{
-  fRnrElement    = kTRUE;
-  fMainColorPtr  = 0;
-}
+RenderElement::RenderElement() :
+  fRnrElement          (kTRUE),
+  fMainColorPtr        (0),
+  fDestroyOnZeroRefCnt (kTRUE),
+  fDenyDestroy         (kFALSE)
+{}
 
-RenderElement::RenderElement(Color_t& main_color) : fMainColorPtr(&main_color)
-{
-  fRnrElement    = kTRUE;
-}
+RenderElement::RenderElement(Color_t& main_color) :
+  fRnrElement          (kTRUE),
+  fMainColorPtr        (&main_color),
+  fDestroyOnZeroRefCnt (kTRUE),
+  fDenyDestroy         (kFALSE)
+{}
 
 RenderElement::~RenderElement()
 {
+  static const Exc_t _eh("RenderElement::RenderElement ");
+
+  for(lpRE_i p=fParents.begin(); p!=fParents.end(); ++p) {
+    RenderElementListBase* l = dynamic_cast<RenderElementListBase*>(*p);
+    if(l)
+      l->RemoveElementLocal(this);
+  }
+  fParents.clear();
+
   for(sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) {
     i->fTree->DeleteItem(i->fItem);
     gClient->NeedRedraw(i->fTree);
   }
 }
 
+void RenderElement::Destroy()
+{
+  static const Exc_t eH("RenderElement::Destroy ");
+
+  if(fDenyDestroy)
+    throw(eH + "this object is protected against destruction.");
+
+  delete this;
+  gReve->Redraw3D();
+}
+
+/**************************************************************************/
+
+void RenderElement::AddParent(RenderElement* re)
+{
+  fParents.push_back(re);
+}
+
+void RenderElement::RemoveParent(RenderElement* re)
+{
+  static const Exc_t eH("RenderElement::RemoveParent ");
+
+  fParents.remove(re);
+  if(fParents.empty() && fDestroyOnZeroRefCnt) {
+    // TObject* tobj = GetObject(eH);
+    // Warning(eH.Data(), Form("auto-destructing '%s' on zero reference count.", tobj->GetName()));
+    delete this;
+  }
+}
+
 /**************************************************************************/
 
 TObject* RenderElement::GetObject(Exc_t eh)
@@ -49,14 +91,16 @@ TObject* RenderElement::GetObject(Exc_t eh)
 /**************************************************************************/
 
 TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
-                                              TGListTreeItem* parent)
+                                              TGListTreeItem* parent_lti)
 {
   static const Exc_t eH("RenderElement::AddIntoListTree ");
 
   TObject* tobj = GetObject(eH);
-  TGListTreeItem* item = ltree->AddItem(parent, tobj->GetName(), this,
+  TGListTreeItem* item = ltree->AddItem(parent_lti, tobj->GetName(), this,
                                        0, 0, kTRUE);
+  gClient->NeedRedraw(ltree);
   item->CheckItem(GetRnrElement());
+  
   if(fMainColorPtr != 0) item->SetColor(GetMainColor());
   item->SetTipText(tobj->GetTitle());
 
@@ -65,17 +109,89 @@ TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
   return item;
 }
 
+TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
+                                              RenderElement* parent)
+{
+  TGListTreeItem* parent_lti = parent ? parent->FindListTreeItem(ltree) : 0;
+  return AddIntoListTree(ltree, parent_lti);
+}
+
+Bool_t RenderElement::RemoveFromListTree(TGListTree* ltree)
+{
+  sLTI_i i = FindItem(ltree);
+  if(i != fItems.end()) {
+    ltree->DeleteItem(i->fItem);
+    fItems.erase(i);
+    gClient->NeedRedraw(ltree);
+    return kTRUE;
+  } else {
+    return kFALSE;
+  }
+}
+
+Bool_t RenderElement::RemoveFromListTree(TGListTree* ltree,
+                                        TGListTreeItem* parent_lti)
+{
+  sLTI_i i = FindItem(ltree, parent_lti);
+  if(i != fItems.end()) {
+    ltree->DeleteItem(i->fItem);
+    fItems.erase(i);
+    gClient->NeedRedraw(ltree);
+    return kTRUE;
+  } else {
+    return kFALSE;
+  }
+}
+
+RenderElement::sLTI_i RenderElement::FindItem(TGListTree* ltree)
+{
+  for(sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
+    if(i->fTree == ltree)
+      return i;
+  return fItems.end();
+}
+
+RenderElement::sLTI_i RenderElement::FindItem(TGListTree* ltree,
+                                             TGListTreeItem* parent_lti)
+{
+  for(sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
+    if(i->fTree == ltree && i->fItem->GetParent() == parent_lti)
+      return i;
+  return fItems.end();
+}
+
+TGListTreeItem* RenderElement::FindListTreeItem(TGListTree* ltree)
+{
+  for(sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
+    if(i->fTree == ltree)
+      return i->fItem;
+  return 0;
+}
+
+TGListTreeItem* RenderElement::FindListTreeItem(TGListTree* ltree,
+                                               TGListTreeItem* parent_lti)
+{
+  for(sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
+    if(i->fTree == ltree && i->fItem->GetParent() == parent_lti)
+      return i->fItem;
+  return 0;
+}
+
 /**************************************************************************/
 
-void RenderElement::FullUpdate()
+void RenderElement::UpdateItems()
 {
+  static const Exc_t eH("RenderElement::UpdateItems ");
+
+  TObject* tobj = GetObject(eH);
   for(sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) {
-    // Setup name and title/tooltip? Need update calls from setname/title as well.
+    i->fItem->Rename(tobj->GetName());
+    i->fItem->SetTipText(tobj->GetTitle());
     i->fItem->CheckItem(fRnrElement);
     if(fMainColorPtr != 0) i->fItem->SetColor(GetMainColor());
+    gClient->NeedRedraw(i->fTree);
   }
-  gReve->Redraw3D();
-  gReve->NotifyBrowser();
+  gReve->Redraw3D(); // This will go away once editor can notify ALL changes.
 }
 
 /**************************************************************************/
@@ -123,7 +239,7 @@ void RenderElement::SetRnrElement(Bool_t rnr)
 {
   if(rnr != fRnrElement) {
     fRnrElement = rnr;
-    FullUpdate();
+    UpdateItems();
   }
 }
 
@@ -133,7 +249,7 @@ void RenderElement::SetMainColor(Color_t color)
 {
   if (fMainColorPtr) {
     *fMainColorPtr = color;
-    FullUpdate();
+    UpdateItems();
   }
 }
 
@@ -147,19 +263,22 @@ void RenderElement::SetMainColor(Pixel_t pixel)
 
 ClassImp(RenderElementObjPtr)
 
-RenderElementObjPtr::RenderElementObjPtr(TObject* obj) :
+RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Bool_t own) :
   RenderElement(),
-  fObject(obj)  
+  fObject(obj),
+  fOwnObject(own)
 {}
 
-RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Color_t& mainColor) :
+RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Color_t& mainColor, Bool_t own) :
   RenderElement(mainColor),
-  fObject(obj)  
+  fObject(obj),
+  fOwnObject(own)
 {}
 
 RenderElementObjPtr::~RenderElementObjPtr()
 {
-  delete fObject;
+  if(fOwnObject)
+    delete fObject;
 }
 
 /**************************************************************************/
@@ -171,23 +290,49 @@ TObject* RenderElementObjPtr::GetObject(Reve::Exc_t eh)
   return fObject;
 }
 
-void RenderElementObjPtr::SetRnrElement(Bool_t rnr)
+/**************************************************************************/
+/**************************************************************************/
+
+ClassImp(RenderElementListBase)
+
+RenderElementListBase::~RenderElementListBase()
 {
-  if(rnr != fRnrElement) {
-    fRnrElement = rnr;
-    if(rnr) {
-      gReve->GetCC()->GetListOfPrimitives()->Add(fObject);
-    } else {
-      gReve->GetCC()->GetListOfPrimitives()->Remove(fObject);
-    }
-    FullUpdate();
+  // Collapse all sub-trees
+  for(sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) {
+    DestroyListSubTree(i->fTree, i->fItem);
+    // My own items removed in ~RenderElement
   }
+  RemoveElements();
 }
 
-/**************************************************************************/
 /**************************************************************************/
 
-ClassImp(RenderElementListBase)
+void RenderElementListBase::AddElement(RenderElement* el)
+{
+  fChildren.push_back(el);
+  el->AddParent(this);
+}
+
+void RenderElementListBase::RemoveElement(RenderElement* el)
+{
+  el->RemoveParent(this);
+  RemoveElementLocal(el);
+}
+
+void RenderElementListBase::RemoveElementLocal(RenderElement* el)
+{
+  fChildren.remove(el);
+}
+
+void RenderElementListBase::RemoveElements()
+{
+  for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
+    (*i)->RemoveParent(this);
+  }
+  fChildren.clear();
+}
+
+/**************************************************************************/
 
 Int_t RenderElementListBase::ExpandIntoListTree(TGListTree* ltree,
                                                TGListTreeItem* parent)
@@ -204,24 +349,38 @@ Int_t RenderElementListBase::ExpandIntoListTree(TGListTree* ltree,
   if(parent->GetFirstChild() != 0)
     return 0;
   Int_t n = 0;
-  for(lpRE_i i=fList.begin(); i!=fList.end(); ++i) {
+  for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
     (*i)->AddIntoListTree(ltree, parent);
     ++n;
   }
   return n;
 }
 
+Int_t RenderElementListBase::DestroyListSubTree(TGListTree* ltree,
+                                               TGListTreeItem* parent)
+{
+  Int_t n = 0;
+  TGListTreeItem* i = parent->GetFirstChild();
+  while(i != 0) {
+    n += DestroyListSubTree(ltree, i);
+    RenderElement* re = (RenderElement*) i->GetUserData();
+    i = i->GetNextSibling();
+    re->RemoveFromListTree(ltree, parent);
+  }
+  return n;
+}
+
 /**************************************************************************/
 
 void RenderElementListBase::EnableListElements()
 {
-  for(lpRE_i i=fList.begin(); i!=fList.end(); ++i)
+  for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i)
     (*i)->SetRnrElement(kTRUE);
 }
 
 void RenderElementListBase::DisableListElements()
 {
-  for(lpRE_i i=fList.begin(); i!=fList.end(); ++i)
+  for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i)
     (*i)->SetRnrElement(kFALSE);
 }
 
@@ -230,7 +389,7 @@ void RenderElementListBase::DisableListElements()
 void RenderElementListBase::SetMainColor(Color_t col)
 {
   Color_t oldcol = GetMainColor();
-  for(lpRE_i i=fList.begin(); i!=fList.end(); ++i) {
+  for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
     if((*i)->GetMainColor() == oldcol) (*i)->SetMainColor(col);
   }
   RenderElement::SetMainColor(col);
@@ -248,7 +407,7 @@ void RenderElementListBase::SetMainColor(Pixel_t pixel)
 void RenderElementListBase::PaintElements(Option_t* option)
 {
   if(fRnrElement) {
-    for(lpRE_i i=fList.begin(); i!=fList.end(); ++i) {
+    for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
       if((*i)->GetRnrElement())
        (*i)->GetObject()->Paint(option);
     }
@@ -259,3 +418,14 @@ void RenderElementListBase::PaintElements(Option_t* option)
 /**************************************************************************/
 
 ClassImp(RenderElementList)
+
+RenderElementList::RenderElementList(const Text_t* n, const Text_t* t, Bool_t doColor) :
+  RenderElementListBase(),
+  TNamed(n, t),
+  fColor(0),
+  fDoColor(doColor)
+{
+  if(fDoColor) {
+    SetMainColorPtr(&fColor);
+  }
+}
index 6b873d6c3ab6dfea09690534c453aa0099fd2545..73d2a2d0f06be2c5cc627acb0ebdf935fea19054 100644 (file)
@@ -23,12 +23,7 @@ class RenderElement
 {
   friend class RGTopFrame;
 
-protected:
-  // TRef     fSource;
-
-  Bool_t   fRnrElement;
-  Color_t* fMainColorPtr;
-
+public:
   struct ListTreeInfo {
     TGListTree*     fTree;
     TGListTreeItem* fItem;
@@ -44,16 +39,38 @@ protected:
 
     ClassDef(ListTreeInfo, 0);
   };
-  typedef std::set<ListTreeInfo>           sLTI_t;
-  typedef std::set<ListTreeInfo>::iterator sLTI_i;
+  typedef std::set<ListTreeInfo>               sLTI_t;
+  typedef std::set<ListTreeInfo>::iterator     sLTI_i;
+
+  typedef std::list<RenderElement*>            lpRE_t;
+  typedef std::list<RenderElement*>::iterator  lpRE_i;
+
+protected:
+  // TRef     fSource;
+
+  Bool_t   fRnrElement;
+  Color_t* fMainColorPtr;
 
   sLTI_t fItems;
+  lpRE_t fParents;
+
+  Bool_t fDestroyOnZeroRefCnt;
+  Bool_t fDenyDestroy;
 
 public:
   RenderElement();
   RenderElement(Color_t& main_color);
   virtual ~RenderElement();
 
+  virtual void AddParent(RenderElement* re);
+  virtual void RemoveParent(RenderElement* re);
+
+  Bool_t GetDestroyOnZeroRefCnt() const   { return fDestroyOnZeroRefCnt; }
+  void   SetDestroyOnZeroRefCnt(Bool_t d) { fDestroyOnZeroRefCnt = d; }
+
+  Bool_t GetDenyDestroy() const   { return fDenyDestroy; }
+  void   SetDenyDestroy(Bool_t d) { fDenyDestroy = d; }
+
   virtual TObject* GetObject(Reve::Exc_t eh="RenderElement::GetObject ");
 
   /*
@@ -66,13 +83,27 @@ public:
   */
 
   virtual TGListTreeItem* AddIntoListTree(TGListTree* ltree,
-                                         TGListTreeItem* parent);
+                                         TGListTreeItem* parent_lti);
+  virtual TGListTreeItem* AddIntoListTree(TGListTree* ltree,
+                                         RenderElement* parent);
+  virtual Bool_t          RemoveFromListTree(TGListTree* ltree);
+  virtual Bool_t          RemoveFromListTree(TGListTree* ltree,
+                                            TGListTreeItem* parent_lti);
+
+  virtual sLTI_i          FindItem(TGListTree* ltree);
+  virtual sLTI_i          FindItem(TGListTree* ltree,
+                                  TGListTreeItem* parent_lti);
+  virtual TGListTreeItem* FindListTreeItem(TGListTree* ltree);
+  virtual TGListTreeItem* FindListTreeItem(TGListTree* ltree,
+                                          TGListTreeItem* parent_lti);
 
-  virtual void FullUpdate();
+  virtual void UpdateItems();
 
   void SpawnEditor();                  // *MENU*
   void ExportToCINT(Text_t* var_name); // *MENU*
 
+  virtual void Destroy();              // *MENU*
+
   virtual Bool_t CanEditRnrElement()   { return kTRUE; }
   virtual Bool_t GetRnrElement() const { return fRnrElement; }
   virtual void   SetRnrElement(Bool_t rnr);
@@ -90,19 +121,22 @@ public:
 
 /**************************************************************************/
 
-class RenderElementObjPtr : public RenderElement
+class RenderElementObjPtr : public RenderElement,
+                            public TObject
 {
 protected:
   TObject* fObject;
+  Bool_t   fOwnObject;
 
 public:
-  RenderElementObjPtr(TObject* obj);
-  RenderElementObjPtr(TObject* obj, Color_t& mainColor);
+  RenderElementObjPtr(TObject* obj, Bool_t own=kTRUE);
+  RenderElementObjPtr(TObject* obj, Color_t& mainColor, Bool_t own=kTRUE);
   virtual ~RenderElementObjPtr();
 
-  virtual TObject* GetObject(Reve::Exc_t eh="RenderElementObjPtr::GetObject ");
+  virtual TObject* GetObject(Exc_t eh="RenderElementObjPtr::GetObject ");
 
-  virtual void SetRnrElement(Bool_t rnr);
+  Bool_t GetOwnObject() const   { return fOwnObject; }
+  void   SetOwnObject(Bool_t o) { fOwnObject = o; }
 
   ClassDef(RenderElementObjPtr, 1);
 }; // endclass RenderElementObjPtr
@@ -112,22 +146,22 @@ public:
 class RenderElementListBase : public RenderElement
 {
 protected:
-  typedef std::list<RenderElement*>            lpRE_t;
-  typedef std::list<RenderElement*>::iterator  lpRE_i;
-
-  lpRE_t fList;
+  lpRE_t fChildren;
 
   void PaintElements(Option_t* option="");
 
 public:
   RenderElementListBase() {}
   RenderElementListBase(Color_t& col) : RenderElement(col) {}
-  virtual ~RenderElementListBase() {}
+  virtual ~RenderElementListBase();
 
-  virtual void AddElement(RenderElement* el) { fList.push_back(el); }
-  virtual void RemoveElements()              { fList.clear(); }
+  virtual void AddElement(RenderElement* el);
+  virtual void RemoveElement(RenderElement* el);
+  virtual void RemoveElementLocal(RenderElement* el);
+  virtual void RemoveElements();
 
   virtual Int_t ExpandIntoListTree(TGListTree* ltree, TGListTreeItem* parent);
+  virtual Int_t DestroyListSubTree(TGListTree* ltree, TGListTreeItem* parent);
 
   void EnableListElements();   // *MENU*
   void DisableListElements();  // *MENU*
@@ -140,18 +174,19 @@ public:
 
 /**************************************************************************/
 
-class RenderElementList : public TNamed, public RenderElementListBase
+class RenderElementList : public RenderElementListBase,
+                          public TNamed
 {
 protected:
   Color_t   fColor;
+  Bool_t    fDoColor;
 
 public:
-  RenderElementList(const Text_t* n="RenderElementList", const Text_t* t="") :
-    TNamed(n, t), RenderElementListBase(fColor), fColor(0)
-  {}
+  RenderElementList(const Text_t* n="RenderElementList", const Text_t* t="",
+                   Bool_t doColor=kFALSE);
   virtual ~RenderElementList() {}
 
-  virtual Bool_t CanEditMainColor()  { return kTRUE; }
+  virtual Bool_t CanEditMainColor()  { return fDoColor; }
 
   virtual void Paint(Option_t* option = "") { PaintElements(option); }