0024007: [Regression] Sporadic crashes when working with XDE documents
[occt.git] / src / XCAFDoc / XCAFDoc_DocumentTool.cxx
index 464e53f..0acc3ec 100755 (executable)
 #include <TDF_Data.hxx>
 #include <TDF_Tool.hxx>
 #include <TDF_LabelLabelMap.hxx>
-
-// purpose: give acces to DocumentTool->Label() for static methods
-static TDF_LabelLabelMap RootLDocLMap;
-
+#include <TDataStd_TreeNode.hxx>
 
 //=======================================================================
 //function : GetID
@@ -40,6 +37,20 @@ const Standard_GUID& XCAFDoc_DocumentTool::GetID()
   return DocumentToolID; 
 }
 
+namespace {
+//=======================================================================
+//function : GetRefID
+//purpose  : Returns a reference id to find a tree node attribute at the root
+//           label
+//=======================================================================
+
+static const Standard_GUID& GetDocumentToolRefID() 
+{
+  static Standard_GUID DocumentToolRefID ("efd212eb-6dfd-11d4-b9c8-0060b0ee281b");
+  return DocumentToolRefID; 
+}
+}
+
 
 //=======================================================================
 //function : Set
@@ -50,14 +61,14 @@ Handle(XCAFDoc_DocumentTool) XCAFDoc_DocumentTool::Set(const TDF_Label& L,
                                                        const Standard_Boolean IsAcces)
 {
   Handle(XCAFDoc_DocumentTool) A;
-  if (!DocLabel(L).FindAttribute (XCAFDoc_DocumentTool::GetID(), A)) {
-    if (!IsAcces) {
-      TDF_Label RootL = L.Root();
-      if (RootLDocLMap.IsBound(RootL)) RootLDocLMap.UnBind(RootL);
-      RootLDocLMap.Bind(RootL, L);
-    }
+  TDF_Label aL = DocLabel (L);
+  if (!aL.FindAttribute (XCAFDoc_DocumentTool::GetID(), A)) {
+    if (!IsAcces)
+      aL = L;
+
     A = new XCAFDoc_DocumentTool;
-    DocLabel(L).AddAttribute(A);
+    aL.AddAttribute(A);
+    A->Init();
     // set ShapeTool, ColorTool and LayerTool attributes
     XCAFDoc_ShapeTool::Set(ShapesLabel(L));
     XCAFDoc_ColorTool::Set(ColorsLabel(L));
@@ -77,11 +88,16 @@ Handle(XCAFDoc_DocumentTool) XCAFDoc_DocumentTool::Set(const TDF_Label& L,
 TDF_Label XCAFDoc_DocumentTool::DocLabel(const TDF_Label& acces) 
 {
   TDF_Label DocL, RootL = acces.Root();
-  if (RootLDocLMap.IsBound(RootL))
-    return RootLDocLMap.Find(RootL);
-  
+  const Standard_GUID& aRefGuid = GetDocumentToolRefID();
+  Handle(TDataStd_TreeNode) aRootNode, aLabNode;
+
+  if (RootL.FindAttribute (aRefGuid, aRootNode)) {
+    aLabNode = aRootNode->First();
+    DocL = aLabNode->Label();
+    return DocL;
+  }
+
   DocL = RootL.FindChild(1);
-  RootLDocLMap.Bind(RootL, DocL);
   return DocL;
 }
 
@@ -267,7 +283,15 @@ void XCAFDoc_DocumentTool::Paste (const Handle(TDF_Attribute)& /* into */,
 void XCAFDoc_DocumentTool::Init() const
 {
   TDF_Label DocL = Label(), RootL = DocL.Root();
-  if ( ! RootLDocLMap.IsBound(RootL) ) RootLDocLMap.Bind(RootL, DocL);
+  const Standard_GUID& aRefGuid = GetDocumentToolRefID();
+  Handle(TDataStd_TreeNode) aRootNode, aLabNode;
+
+  if (!RootL.FindAttribute (aRefGuid, aRootNode)) {
+    Handle(TDataStd_TreeNode) aRootNode = TDataStd_TreeNode::Set (RootL, aRefGuid);
+    Handle(TDataStd_TreeNode) aLNode = TDataStd_TreeNode::Set (DocL, aRefGuid);
+    aLNode->SetFather (aRootNode);
+    aRootNode->SetFirst (aLNode);
+  }
 }
 
 
@@ -278,25 +302,18 @@ void XCAFDoc_DocumentTool::Init() const
 
 Standard_Boolean XCAFDoc_DocumentTool::IsXCAFDocument(const  Handle(TDocStd_Document)& D)
 {
-  return RootLDocLMap.IsBound(D->Main().Root());
+  TDF_Label RootL = D->Main().Root();
+  const Standard_GUID& aRefGuid = GetDocumentToolRefID();
+  Handle(TDataStd_TreeNode) aRootNode;
+  return RootL.FindAttribute (aRefGuid, aRootNode);
 }
 
 
 //=======================================================================
 //function : Destroy
-//purpose  : Removal of the document from RootLDocLMap is necessary. Otherwise
-//           there remains orphan labels and upon creation of a new
-//           label with XCAFDoc_DocumentTool attribute that
-//           orphan is attempted to get used (when hashes match) causing
-//           an exception when trying to access its data framework.
+//purpose  : No longer required. Kept for binary compatibility only.
 //=======================================================================
 
 void XCAFDoc_DocumentTool::Destroy()
 {
-  TDF_Label DocL = Label();
-  if ( ! DocL.IsNull() ) {
-    TDF_Label RootL = DocL.Root();
-    if ( RootLDocLMap.IsBound( RootL ) ) 
-      RootLDocLMap.UnBind( RootL );
-  }
 }