[dasher] Fix rebuilding of parents and language changing.
- From: Patrick Welche <pwelche src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [dasher] Fix rebuilding of parents and language changing.
- Date: Mon, 8 Feb 2010 18:13:32 +0000 (UTC)
commit a082f96160999718b19b07d25eab3a5d5b7f352f
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Mon Feb 8 19:08:25 2010 +0100
Fix rebuilding of parents and language changing.
Removed DasherNode::NodeIsParent
DasherModel::RebuildAroundNode became DasherModel::RebuildAroundCrossHair
ChangeLog | 4 +++
Src/DasherCore/AlphabetManager.cpp | 43 ++++++++------------------------
Src/DasherCore/AlphabetManager.h | 8 ------
Src/DasherCore/ControlManager.cpp | 1 -
Src/DasherCore/ConversionManager.cpp | 1 -
Src/DasherCore/DasherModel.cpp | 45 ++++++++++++++++-----------------
Src/DasherCore/DasherModel.h | 10 ++++---
Src/DasherCore/DasherNode.cpp | 8 ------
Src/DasherCore/DasherNode.h | 1 -
9 files changed, 43 insertions(+), 78 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a01f14e..6aabb2d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-02-08 Alan Lawrence <acl33 inf phy cam ac uk>
+
+ * Fix rebuilding of parents and language changing.
+
2009-02-06 Alan Lawrence <acl33 inf phy cam ac uk>
* Fix SymbolStream UTF-8 character input function.
diff --git a/Src/DasherCore/AlphabetManager.cpp b/Src/DasherCore/AlphabetManager.cpp
index 2d00985..c82c2c4 100644
--- a/Src/DasherCore/AlphabetManager.cpp
+++ b/Src/DasherCore/AlphabetManager.cpp
@@ -74,28 +74,8 @@ CAlphabetManager::CGroupNode *CAlphabetManager::makeGroup(CDasherNode *pParent,
}
CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, int iLower, int iUpper, bool bEnteredLast, int iOffset) {
-
- CAlphNode *pNewNode = BuildNodeForOffset(pParent, iLower, iUpper, bEnteredLast, max(-1,iOffset-1));
- if (!pNewNode) {
- DASHER_ASSERT(bEnteredLast);
- //could not build a node 'responsible' for entering the preceding character,
- // as said character is not in the current alphabet! However, we'll allow the
- // user to start entering text afresh
- return BuildNodeForOffset(pParent, iLower, iUpper, false, iOffset);
- // (the new node'll be constructed using the current alphabet's default context,
- // i.e. start of sentence)
- }
- pNewNode->SetFlag(NF_SEEN, true);
-
- // if(m_bGameMode) {
- // pNodeUserData->iGameOffset = -1;
- pNewNode->SetFlag(NF_GAME, true);
- // }
-
- return pNewNode;
-}
-CAlphabetManager::CAlphNode *CAlphabetManager::BuildNodeForOffset(CDasherNode *pParent, int iLower, int iUpper, bool bSym, int iNewOffset) {
+ int iNewOffset(max(-1,iOffset-1));
std::vector<symbol> vContextSymbols;
// TODO: make the LM get the context, rather than force it to fix max context length as an int
@@ -127,8 +107,9 @@ CAlphabetManager::CAlphNode *CAlphabetManager::BuildNodeForOffset(CDasherNode *p
}
if (it == vContextSymbols.end()) {
//previous character was not in the alphabet!
- if (bSym) return NULL; //can't construct a node "responsible" for entering such a character!
- //ok. Create a node as if we were starting a new sentence...
+ //can't construct a node "responsible" for entering it
+ bEnteredLast=false;
+ //instead, Create a node as if we were starting a new sentence...
vContextSymbols.clear();
m_pNCManager->GetAlphabet()->GetSymbols(vContextSymbols, m_pNCManager->GetAlphabet()->GetDefaultContext());
it = vContextSymbols.begin();
@@ -139,7 +120,7 @@ CAlphabetManager::CAlphNode *CAlphabetManager::BuildNodeForOffset(CDasherNode *p
m_pLanguageModel->EnterSymbol(iContext, *(it++));
}
- if(!bSym) {
+ if(!bEnteredLast) {
pDisplayInfo->strDisplayText = ""; //equivalent to do m_pNCManager->GetAlphabet()->GetDisplayText(0)
pDisplayInfo->iColour = m_pNCManager->GetAlphabet()->GetColour(0, iNewOffset%2);
pNewNode = makeGroup(pParent, iLower, iUpper, pDisplayInfo, NULL);
@@ -148,6 +129,11 @@ CAlphabetManager::CAlphNode *CAlphabetManager::BuildNodeForOffset(CDasherNode *p
pDisplayInfo->strDisplayText = m_pNCManager->GetAlphabet()->GetDisplayText(iSymbol);
pDisplayInfo->iColour = m_pNCManager->GetAlphabet()->GetColour(iSymbol, iNewOffset%2);
pNewNode = makeSymbol(pParent, iLower, iUpper, pDisplayInfo, iSymbol);
+ //if the new node is not child of an existing node, then it
+ // represents a symbol that's already happened - so we're either
+ // going backwards (rebuildParent) or creating a new root after a language change
+ DASHER_ASSERT (!pParent);
+ pNewNode->SetFlag(NF_SEEN, true);
}
pNewNode->m_iOffset = iNewOffset;
@@ -450,14 +436,7 @@ CDasherNode *CAlphabetManager::CAlphNode::RebuildParent(int iNewOffset) {
//possible that we have a parent, as RebuildParent() rebuilds back to closest AlphNode.
if (Parent()) return Parent();
- CAlphNode *pNewNode = m_pMgr->BuildNodeForOffset(NULL, 0, 0, iNewOffset!=-1, iNewOffset);
- if (!pNewNode) {
- //could not rebuild parent node, as the preceding character was not
- // in the current alphabet. Returning null means the user won't be able
- // to reverse any further; he'll have to change language (to one
- // including that symbol) instead.
- return NULL;
- }
+ CAlphNode *pNewNode = m_pMgr->GetRoot(NULL, 0, 0, iNewOffset!=-1, iNewOffset+1);
//now fill in the new node - recursively - until it reaches us
m_pMgr->IterateChildGroups(pNewNode, NULL, this);
diff --git a/Src/DasherCore/AlphabetManager.h b/Src/DasherCore/AlphabetManager.h
index ae17605..94ca091 100644
--- a/Src/DasherCore/AlphabetManager.h
+++ b/Src/DasherCore/AlphabetManager.h
@@ -126,14 +126,6 @@ namespace Dasher {
virtual CDasherNode *CreateSymbolNode(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd);
virtual CLanguageModel::Context CreateSymbolContext(CAlphNode *pParent, symbol iSymbol);
virtual CGroupNode *CreateGroupNode(CAlphNode *pParent, SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd);
-
- ///
- ///Builds a new node from the context leading up to the specified offset
- /// bSym - true if the build node should be considered as having entered the last symbol (e.g. when rebuilding parent,
- /// but not when escaping back to Alphabet)
- /// iNewOffset - m_iOffset of the new node (i.e. index into context of character the node represents)
- ///
- CAlphNode *BuildNodeForOffset(CDasherNode *pParent, int iLower, int iUpper, bool bSym, int iNewOffset);
CLanguageModel *m_pLanguageModel;
CNodeCreationManager *m_pNCManager;
diff --git a/Src/DasherCore/ControlManager.cpp b/Src/DasherCore/ControlManager.cpp
index a118839..fe7435a 100644
--- a/Src/DasherCore/ControlManager.cpp
+++ b/Src/DasherCore/ControlManager.cpp
@@ -312,7 +312,6 @@ void CControlManager::CContNode::PopulateChildren() {
// Escape back to alphabet
pNewNode = m_pMgr->m_pNCManager->GetAlphRoot(this, iLbnd, iHbnd, false, m_iOffset);
- pNewNode->SetFlag(NF_SEEN, false);
}
else {
diff --git a/Src/DasherCore/ConversionManager.cpp b/Src/DasherCore/ConversionManager.cpp
index 13d912c..b6564df 100644
--- a/Src/DasherCore/ConversionManager.cpp
+++ b/Src/DasherCore/ConversionManager.cpp
@@ -103,7 +103,6 @@ void CConversionManager::CConvNode::PopulateChildren() {
int iHbnd(m_pMgr->m_pNCManager->GetLongParameter(LP_NORMALIZATION));
CDasherNode *pNewNode = m_pMgr->m_pNCManager->GetAlphRoot(this, iLbnd, iHbnd, false, m_iOffset + 1);
- pNewNode->SetFlag(NF_SEEN, false);
DASHER_ASSERT(GetChildren().back()==pNewNode);
}
diff --git a/Src/DasherCore/DasherModel.cpp b/Src/DasherCore/DasherModel.cpp
index 44da803..ab34ea9 100644
--- a/Src/DasherCore/DasherModel.cpp
+++ b/Src/DasherCore/DasherModel.cpp
@@ -112,7 +112,7 @@ void CDasherModel::HandleEvent(Dasher::CEvent *pEvent) {
switch (pEvt->m_iParameter) {
case BP_CONTROL_MODE: // Rebuild the model if control mode is switched on/off
- RebuildAroundNode(Get_node_under_crosshair());
+ RebuildAroundCrosshair();
break;
case BP_SMOOTH_OFFSET:
if (!GetBoolParameter(BP_SMOOTH_OFFSET))
@@ -150,7 +150,7 @@ void CDasherModel::Make_root(CDasherNode *pNewRoot) {
// std::cout << "Make root" << std::endl;
DASHER_ASSERT(pNewRoot != NULL);
- DASHER_ASSERT(pNewRoot->NodeIsParent(m_Root));
+ DASHER_ASSERT(pNewRoot->Parent() == m_Root);
m_Root->SetFlag(NF_COMMITTED, true);
@@ -189,25 +189,24 @@ void CDasherModel::RecursiveMakeRoot(CDasherNode *pNewRoot) {
// TODO: we really ought to check that pNewRoot is actually a
// descendent of the root, although that should be guaranteed
- if(!pNewRoot->NodeIsParent(m_Root))
+ if(pNewRoot->Parent() != m_Root)
RecursiveMakeRoot(pNewRoot->Parent());
Make_root(pNewRoot);
}
-// RebuildAroundNode is only used when BP_CONTROL changes,
-// so not very often.
-void CDasherModel::RebuildAroundNode(CDasherNode *pNode) {
+// only used when BP_CONTROL changes, so not very often.
+void CDasherModel::RebuildAroundCrosshair() {
+ CDasherNode *pNode = Get_node_under_crosshair();
DASHER_ASSERT(pNode != NULL);
+ DASHER_ASSERT(pNode == m_pLastOutput);
RecursiveMakeRoot(pNode);
-
+ DASHER_ASSERT(m_Root == pNode);
ClearRootQueue();
m_Root->Delete_children();
m_Root->PopulateChildren();
-
- m_pLastOutput = m_Root;
}
void CDasherModel::Reparent_root(int lower, int upper) {
@@ -304,15 +303,10 @@ void CDasherModel::InitialiseAtOffset(int iOffset, CDasherView *pView) {
DeleteTree();
m_Root = m_pNodeCreationManager->GetAlphRoot(NULL, 0,GetLongParameter(LP_NORMALIZATION), iOffset!=0, iOffset);
-
- m_pLastOutput = m_Root;
-
- // Create children of the root
- // TODO: What about parents?
-
- if(m_Root->Range() >= 0.1 * GetLongParameter(LP_NORMALIZATION)) {
- ExpandNode(m_Root);
- }
+ m_pLastOutput = (m_Root->GetFlag(NF_SEEN)) ? m_Root : NULL;
+
+ // Create children of the root...
+ ExpandNode(m_Root);
// Set the root coordinates so that the root node is an appropriate
// size and we're not in any of the children
@@ -326,6 +320,7 @@ void CDasherModel::InitialiseAtOffset(int iOffset, CDasherView *pView) {
m_iDisplayOffset = 0;
+ //now (re)create parents, while they show on the screen
if(pView) {
while(pView->IsNodeVisible(m_Rootmin,m_Rootmax)) {
CDasherNode *pOldRoot = m_Root;
@@ -462,6 +457,9 @@ void CDasherModel::UpdateBounds(myint iNewMin, myint iNewMax, unsigned long iTim
// Check whether new nodes need to be created
ExpandNode(Get_node_under_crosshair());
+// This'll get done again when we render the frame, later, but we use NF_SEEN
+// (set here) to ensure the node under the cursor can never be collapsed
+// (even when the node budget is exceeded) when we do the rendering...
HandleOutput(pAdded, pNumDeleted);
}
@@ -535,8 +533,9 @@ void CDasherModel::HandleOutput(Dasher::VECTOR_SYMBOL_PROB* pAdded, int* pNumDel
// std::cout << "HandleOutput: " << m_pLastOutput << " => " << pNewNode << std::endl;
- CDasherNode *pLastSeen;
- for (pLastSeen = pNewNode; !pLastSeen->GetFlag(NF_SEEN); pLastSeen = pLastSeen->Parent());
+ CDasherNode *pLastSeen = pNewNode;
+ while (pLastSeen && !pLastSeen->GetFlag(NF_SEEN))
+ pLastSeen = pLastSeen->Parent();
while (m_pLastOutput != pLastSeen) {
m_pLastOutput->Undo();
@@ -547,7 +546,7 @@ void CDasherModel::HandleOutput(Dasher::VECTOR_SYMBOL_PROB* pAdded, int* pNumDel
(*pNumDeleted) += m_pLastOutput->m_iNumSymbols;
m_pLastOutput = m_pLastOutput->Parent();
- m_pLastOutput->Enter();
+ if (m_pLastOutput) m_pLastOutput->Enter();
}
if(!pNewNode->GetFlag(NF_SEEN)) {
@@ -610,7 +609,8 @@ bool CDasherModel::RenderToView(CDasherView *pView, CExpansionPolicy &policy) {
DASHER_ASSERT(pView != NULL);
DASHER_ASSERT(m_Root != NULL);
- DASHER_ASSERT(Get_node_under_crosshair() == m_pLastOutput);
+ // XXX we HandleOutput in RenderToView
+ // DASHER_ASSERT(Get_node_under_crosshair() == m_pLastOutput);
bool bReturnValue = false;
std::vector<std::pair<myint,bool> > vGameTargetY;
@@ -643,7 +643,6 @@ bool CDasherModel::CheckForNewRoot(CDasherView *pView) {
#ifdef DEBUG
CDasherNode *pOldNode = Get_node_under_crosshair();
- DASHER_ASSERT(pOldNode == m_pLastOutput);
#endif
CDasherNode *root(m_Root);
diff --git a/Src/DasherCore/DasherModel.h b/Src/DasherCore/DasherModel.h
index f2f4b5d..f5f411d 100644
--- a/Src/DasherCore/DasherModel.h
+++ b/Src/DasherCore/DasherModel.h
@@ -324,12 +324,14 @@ class Dasher::CDasherModel:public CFrameRate, private NoClones
void RecursiveMakeRoot(CDasherNode *pNewRoot);
///
- /// Rebuild the data structure such that a given node is guaranteed
- /// to be in the same place on the screen. This would usually be the
- /// node under the crosshair
+ /// Makes the node under the crosshair the root by deleting everything
+ /// outside it, then rebuilds the nodes beneath it. (Thus, the node under
+ /// the crosshair stays in the same place.) Used when control mode is turned
+ /// on or off, or more generally, when the sizes of child nodes may have
+ /// changed.
///
- void RebuildAroundNode(CDasherNode *pNode);
+ void RebuildAroundCrosshair();
///
/// Rebuild the parent of the current root - used during backing off
diff --git a/Src/DasherCore/DasherNode.cpp b/Src/DasherCore/DasherNode.cpp
index 0a3d220..f5301a9 100644
--- a/Src/DasherCore/DasherNode.cpp
+++ b/Src/DasherCore/DasherNode.cpp
@@ -98,14 +98,6 @@ void CDasherNode::Trace() const {
*/
}
-bool CDasherNode::NodeIsParent(CDasherNode *oldnode) const {
- if(oldnode == m_pParent)
- return true;
- else
- return false;
-
-}
-
void CDasherNode::GetContext(CDasherInterfaceBase *pInterface, vector<symbol> &vContextSymbols, int iOffset, int iLength) {
if (!GetFlag(NF_SEEN)) {
DASHER_ASSERT(m_pParent);
diff --git a/Src/DasherCore/DasherNode.h b/Src/DasherCore/DasherNode.h
index fd4e7da..4b0b06a 100644
--- a/Src/DasherCore/DasherNode.h
+++ b/Src/DasherCore/DasherNode.h
@@ -185,7 +185,6 @@ class Dasher::CDasherNode:private NoClones {
inline unsigned int ChildCount() const;
inline CDasherNode *Parent() const;
void SetParent(CDasherNode *pNewParent);
- bool NodeIsParent(CDasherNode * oldnode) const;
// TODO: Should this be here?
CDasherNode *const Get_node_under(int, myint y1, myint y2, myint smousex, myint smousey); // find node under given co-ords
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]