[dasher] Change root node automatically in RenderToView



commit 296d63de2dfd49532a13216aff6fabe8c087cfb2
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Thu Sep 2 19:17:46 2010 +0100

    Change root node automatically in RenderToView
    
    (CheckForNewRoot inlined into RenderToView, no other calls needed;
    Reparent_root called only from RenderToView (not needed in SetOffset),
      returns true for success / false if failed)

 Src/DasherCore/DasherInterfaceBase.cpp |    2 -
 Src/DasherCore/DasherModel.cpp         |   66 +++++++++++---------------------
 Src/DasherCore/DasherModel.h           |   14 +-----
 3 files changed, 25 insertions(+), 57 deletions(-)
---
diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp
index ee38ebd..52f224c 100644
--- a/Src/DasherCore/DasherInterfaceBase.cpp
+++ b/Src/DasherCore/DasherInterfaceBase.cpp
@@ -530,8 +530,6 @@ void CDasherInterfaceBase::NewFrame(unsigned long iTime, bool bForceRedraw) {
 	  bChanged = m_pInputFilter->Timer(iTime, m_pDasherView, m_pDasherModel, 0, 0, &pol);
 	}
       }
-
-      m_pDasherModel->CheckForNewRoot(m_pDasherView);
     }
   }
 
diff --git a/Src/DasherCore/DasherModel.cpp b/Src/DasherCore/DasherModel.cpp
index 66555bf..98b46c3 100644
--- a/Src/DasherCore/DasherModel.cpp
+++ b/Src/DasherCore/DasherModel.cpp
@@ -160,7 +160,7 @@ void CDasherModel::Make_root(CDasherNode *pNewRoot) {
   }
 }
 
-void CDasherModel::Reparent_root() {
+bool CDasherModel::Reparent_root() {
   DASHER_ASSERT(m_Root != NULL);
 
   // Change the root node to the parent of the existing node. We need
@@ -170,16 +170,14 @@ void CDasherModel::Reparent_root() {
 
   if(oldroots.size() == 0) {
     pNewRoot = m_Root->RebuildParent();
-    // Return if there's no existing parent and no way of recreating one
-    if(pNewRoot == NULL) return;
+    // Fail if there's no existing parent and no way of recreating one
+    if(pNewRoot == NULL) return false;
   }
   else {
     pNewRoot = oldroots.back();
     oldroots.pop_back();
   }
 
-  pNewRoot->SetFlag(NF_COMMITTED, false);
-
   DASHER_ASSERT(m_Root->Parent() == pNewRoot);
 
   const myint lower(m_Root->Lbnd()), upper(m_Root->Hbnd());
@@ -193,9 +191,11 @@ void CDasherModel::Reparent_root() {
            (m_Rootmin - m_Rootmin_min) / static_cast<double>(iRootWidth))) {
     //but cache the (currently-unusable) root node - else we'll keep recreating (and deleting) it on every frame... 
     oldroots.push_back(pNewRoot);
-    return;
+    return false;
   }
-    
+  
+  pNewRoot->SetFlag(NF_COMMITTED, false);
+  
   //Update the root coordinates to reflect the new root
   m_Root = pNewRoot;
     
@@ -207,6 +207,7 @@ void CDasherModel::Reparent_root() {
     it->iN2 = it->iN2 + (myint((GetLongParameter(LP_NORMALIZATION) - upper)) * iRootWidth / iRange);
     it->iN1 = it->iN1 - (myint(lower) * iRootWidth / iRange);
   }
+  return true;
 }
 
 void CDasherModel::ClearRootQueue() {
@@ -260,19 +261,6 @@ void CDasherModel::SetOffset(int iOffset, CAlphabetManager *pMgr, CDasherView *p
 
   m_iDisplayOffset = 0;
 
-  //now (re)create parents, while they show on the screen
-  // - if we were lazy, we could leave this to NewFrame,
-  // and one node around the root would be recreated per frame,
-  // but we'll do it properly here.
-  if(pView) {
-    while(pView->IsSpaceAroundNode(m_Rootmin,m_Rootmax)) {
-      CDasherNode *pOldRoot = m_Root;
-      Reparent_root();
-      if(m_Root == pOldRoot)
-	break;
-    }
-  }
-
   // TODO: See if this is better positioned elsewhere
   m_pDasherInterface->ScheduleRedraw();
 }
@@ -568,6 +556,10 @@ void CDasherModel::RenderToView(CDasherView *pView, CExpansionPolicy &policy) {
   DASHER_ASSERT(pView != NULL);
   DASHER_ASSERT(m_Root != NULL);
 
+  while(pView->IsSpaceAroundNode(m_Rootmin,m_Rootmax)) {
+    if (!Reparent_root()) break;
+  }
+  
   // The Render routine will fill iGameTargetY with the Dasher Coordinate of the 
   // youngest node with NF_GAME set. The model is responsible for setting NF_GAME on
   // the appropriate Nodes.
@@ -588,39 +580,25 @@ void CDasherModel::RenderToView(CDasherView *pView, CExpansionPolicy &policy) {
   // TODO: Fix up stats
   // TODO: Is this the right way to handle this?
   OutputTo(pOutput, NULL, NULL);
-}
-
-bool CDasherModel::CheckForNewRoot(CDasherView *pView) {
-  DASHER_ASSERT(m_Root != NULL);
-  // TODO: pView is redundant here
-
-  if(!(m_Root->GetFlag(NF_SUPER))) {
-    CDasherNode *root(m_Root);    
-    Reparent_root();
-    return(m_Root != root);
-  }
-
-  CDasherNode *pNewRoot = NULL;
-  if (m_Root->onlyChildRendered) {
+  
+  while (CDasherNode *pNewRoot = m_Root->onlyChildRendered) {
 #ifdef DEBUG
     //if only one child was rendered, no other child covers the screen -
     // as no other child was onscreen at all!
     for (CDasherNode::ChildMap::const_iterator it = m_Root->GetChildren().begin(); it != m_Root->GetChildren().end(); it++) {
-      DASHER_ASSERT(*it == m_Root->onlyChildRendered || !(*it)->GetFlag(NF_SUPER));
+      DASHER_ASSERT(*it == pNewRoot || !(*it)->GetFlag(NF_SUPER));
     }
 #endif
-    if (m_Root->onlyChildRendered->GetFlag(NF_SUPER))
-      pNewRoot = m_Root->onlyChildRendered;
-  }
-  ////GAME MODE TEMP - only change the root if it is on the game path/////////
-  if (pNewRoot && (!m_bGameMode || pNewRoot->GetFlag(NF_GAME))) {
-    Make_root(pNewRoot);
+    if (pNewRoot->GetFlag(NF_SUPER) &&
+        ////GAME MODE TEMP - only change the root if it is on the game path/////////
+        (!m_bGameMode || m_Root->onlyChildRendered->GetFlag(NF_GAME))) {
+      Make_root(pNewRoot);
+    } else
+      break;
   }
-
-  return false;
+  
 }
 
-
 void CDasherModel::ScheduleZoom(long time, dasherint X, dasherint Y, int iMaxZoom)
 {
   // 1 = min, 2 = max. y1, y2 is the length we select from Y1, Y2. With
diff --git a/Src/DasherCore/DasherModel.h b/Src/DasherCore/DasherModel.h
index 3752d58..90c78eb 100644
--- a/Src/DasherCore/DasherModel.h
+++ b/Src/DasherCore/DasherModel.h
@@ -169,14 +169,6 @@ class Dasher::CDasherModel:public Dasher::CFrameRate, private NoClones
   };
 
   ///
-  /// Check whether a change of root node is needed, and perform the
-  /// update if so
-  /// TODO: Could be done in UpdateBounds?
-  ///
-
-  bool CheckForNewRoot(CDasherView *pView);
-
-  ///
   /// Rebuild the tree of nodes (may reuse the existing ones if !bForce). 
   /// @param iLocation offset (cursor position) in attached buffer from which to obtain context
   /// @param pMgr Manager to use to create nodes
@@ -303,10 +295,10 @@ class Dasher::CDasherModel:public Dasher::CFrameRate, private NoClones
   void Make_root(CDasherNode *pNewRoot); 
 
   ///
-  /// Rebuild the parent of the current root - used during backing off
+  /// Make the parent of the current root into the new root (rebuilding if necessary) - used during backing off
+  /// Return true if successful, false if couldn't.
   ///
-
-  void Reparent_root(); 
+  bool Reparent_root(); 
 
   /// Handle the output caused by a change in node over the crosshair. Specifically,
   /// deletes from m_pLastOutput back to closest ancestor of pNewNode,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]