[dasher] Extract CAlphBase supertype of CAlphNode w/ common code for rebuilding
- From: Patrick Welche <pwelche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dasher] Extract CAlphBase supertype of CAlphNode w/ common code for rebuilding
- Date: Tue, 15 Mar 2011 17:12:27 +0000 (UTC)
commit fc7e857d5f78ef73460de3ea3a8bc2238d3fbdec
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Sat Feb 12 21:38:04 2011 +0000
Extract CAlphBase supertype of CAlphNode w/ common code for rebuilding
inc for CConvRoot. Should now have all the architecture for Mandarin rebuilding,
but still need to (a) figure out m_pyParent from chinese symbol,
(b) Modify CConvRoot to allow call to PopulateChildren w/ existing CMandSym
Src/DasherCore/AlphabetManager.cpp | 94 +++++++++++++++++------------------
Src/DasherCore/AlphabetManager.h | 71 +++++++++++++++++++--------
Src/DasherCore/MandarinAlphMgr.cpp | 70 +++++++++++++++++++++------
Src/DasherCore/MandarinAlphMgr.h | 26 ++++++----
4 files changed, 168 insertions(+), 93 deletions(-)
---
diff --git a/Src/DasherCore/AlphabetManager.cpp b/Src/DasherCore/AlphabetManager.cpp
index cfe4b72..f01b245 100644
--- a/Src/DasherCore/AlphabetManager.cpp
+++ b/Src/DasherCore/AlphabetManager.cpp
@@ -116,8 +116,12 @@ int CAlphabetManager::GetColour(symbol sym, int iOffset) const {
}
+CAlphabetManager::CAlphBase::CAlphBase(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CAlphabetManager *pMgr)
+: CDasherNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText), m_pMgr(pMgr) {
+}
+
CAlphabetManager::CAlphNode::CAlphNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CAlphabetManager *pMgr)
-: CDasherNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText), m_pProbInfo(NULL), m_pMgr(pMgr) {
+: CAlphBase(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText, pMgr), m_pProbInfo(NULL) {
}
CAlphabetManager::CSymbolNode::CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CAlphabetManager *pMgr, symbol _iSymbol)
@@ -313,6 +317,15 @@ CAlphabetManager::CGroupNode *CAlphabetManager::CreateGroupNode(CAlphNode *pPare
return pNewNode;
}
+CDasherNode *CAlphabetManager::CAlphBase::RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo) {
+ CGroupNode *pRet=m_pMgr->CreateGroupNode(pParent, iLbnd, iHbnd, strEnc, iBkgCol, pInfo);
+ if (isInGroup(pInfo)) {
+ //created group node should contain this one
+ m_pMgr->IterateChildGroups(pRet,pInfo,this);
+ }
+ return pRet;
+}
+
CDasherNode *CAlphabetManager::CGroupNode::RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo) {
if (pInfo == m_pGroup) {
SetRange(iLbnd, iHbnd);
@@ -321,20 +334,15 @@ CDasherNode *CAlphabetManager::CGroupNode::RebuildGroup(CAlphNode *pParent, unsi
DASHER_ASSERT (offset() == pParent->offset());
return this;
}
- CGroupNode *pRet=m_pMgr->CreateGroupNode(pParent, iLbnd, iHbnd, strEnc, iBkgCol, pInfo);
- if (pInfo->iStart <= m_pGroup->iStart && pInfo->iEnd >= m_pGroup->iEnd) {
- //created group node should contain this one
- m_pMgr->IterateChildGroups(pRet,pInfo,this);
- }
- return pRet;
+ return CAlphBase::RebuildGroup(pParent, iLbnd, iHbnd, strEnc, iBkgCol, pInfo);
}
-CDasherNode *CAlphabetManager::CSymbolNode::RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo) {
- CGroupNode *pRet=m_pMgr->CreateGroupNode(pParent, iLbnd, iHbnd, strEnc, iBkgCol, pInfo);
- if (pInfo->iStart <= iSymbol && pInfo->iEnd > iSymbol) {
- m_pMgr->IterateChildGroups(pRet, pInfo, this);
- }
- return pRet;
+bool CAlphabetManager::CGroupNode::isInGroup(const SGroupInfo *pInfo) {
+ return pInfo->iStart <= m_pGroup->iStart && pInfo->iEnd >= m_pGroup->iEnd;
+}
+
+bool CAlphabetManager::CSymbolNode::isInGroup(const SGroupInfo *pInfo) {
+ return (pInfo->iStart <= iSymbol && pInfo->iEnd > iSymbol);
}
CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
@@ -359,6 +367,10 @@ CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, unsigned int
return pAlphNode;
}
+CDasherNode *CAlphabetManager::CAlphBase::RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
+ return m_pMgr->CreateSymbolNode(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
+}
+
CDasherNode *CAlphabetManager::CSymbolNode::RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
if(iSymbol == this->iSymbol) {
SetRange(iLbnd, iHbnd);
@@ -366,14 +378,10 @@ CDasherNode *CAlphabetManager::CSymbolNode::RebuildSymbol(CAlphNode *pParent, u
DASHER_ASSERT(offset() == pParent->offset() + numChars());
return this;
}
- return m_pMgr->CreateSymbolNode(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
-}
-
-CDasherNode *CAlphabetManager::CGroupNode::RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
- return m_pMgr->CreateSymbolNode(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
+ return CAlphBase::RebuildSymbol(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
}
-void CAlphabetManager::IterateChildGroups(CAlphNode *pParent, const SGroupInfo *pParentGroup, CAlphNode *buildAround) {
+void CAlphabetManager::IterateChildGroups(CAlphNode *pParent, const SGroupInfo *pParentGroup, CAlphBase *buildAround) {
std::vector<unsigned int> *pCProb(pParent->GetProbInfo());
DASHER_ASSERT((*pCProb)[0] == 0);
const int iMin(pParentGroup ? pParentGroup->iStart : 1);
@@ -500,40 +508,30 @@ void CAlphabetManager::CSymbolNode::Undo(int *pNumDeleted) {
}
CDasherNode *CAlphabetManager::CGroupNode::RebuildParent() {
- // CAlphNode's always have a parent, they inserted a symbol; CGroupNode's
- // with an m_pGroup have a container i.e. the parent group, unless
+
+ if (Parent()) return Parent();
+
+ // CGroupNodes with an m_pGroup have a container i.e. the parent group, unless
// m_pGroup==NULL => "root" node where Alphabet->m_pBaseGroup is the *first*child*...
if (m_pGroup == NULL) return NULL;
- //offset of group node is same as parent...
- return CAlphNode::RebuildParent(offset());
+
+ return CAlphBase::RebuildParent();
}
-CDasherNode *CAlphabetManager::CSymbolNode::RebuildParent() {
- //parent's offset usually one less than this, but can be two for the paragraph symbol.
- return CAlphNode::RebuildParent(offset()-numChars());
-}
+CDasherNode *CAlphabetManager::CAlphBase::RebuildParent() {
+ if (!Parent()) {
+ //Parent's offset usually one less than this, but can be two for the paragraph symbol.
+ int iNewOffset = offset()-numChars();
-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->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);
-
- //finally return our immediate parent (pNewNode may be an ancestor rather than immediate parent!)
- DASHER_ASSERT(Parent() != NULL);
-
- //although not required, we believe only NF_SEEN nodes are ever requested to rebuild their parents...
- DASHER_ASSERT(GetFlag(NF_SEEN));
- //so set NF_SEEN on all created ancestors (of which pNewNode is the last)
- CDasherNode *pNode = this;
- do {
- pNode = pNode->Parent();
- pNode->SetFlag(NF_SEEN, true);
- } while (pNode != pNewNode);
-
+ 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);
+
+ if (GetFlag(NF_SEEN)) {
+ for (CDasherNode *pNode=this; (pNode=pNode->Parent()); pNode->SetFlag(NF_SEEN, true));
+ }
+ }
return Parent();
}
diff --git a/Src/DasherCore/AlphabetManager.h b/Src/DasherCore/AlphabetManager.h
index de40cba..804b824 100644
--- a/Src/DasherCore/AlphabetManager.h
+++ b/Src/DasherCore/AlphabetManager.h
@@ -57,10 +57,44 @@ namespace Dasher {
virtual ~CAlphabetManager();
protected:
+ class CAlphNode;
+ /// Abstract superclass for alphabet manager nodes, provides common implementation
+ /// code for rebuilding parent nodes = reversing.
+ class CAlphBase : public CDasherNode {
+ public:
+ CAlphabetManager *mgr() {return m_pMgr;}
+ CDasherNode *RebuildParent();
+ ///Called to build a symbol (leaf) node which is a descendant of the symbol or root node preceding this.
+ /// Default implementation just calls the manager's CreateSymbolNode method to create a new node,
+ /// but subclasses can override to graft themselves into the appropriate point beneath the previous node.
+ /// \param pParent parent of the symbol node to create; could be the previous root, or an intervening node (e.g. group)
+ /// \param strGroup caption of any elided group node. If a new node is created, this should be appended to that node's caption;
+ /// however, if this existing node is grafted in instead, the caption will already have been prepended (as the group structure
+ /// is always the same and just repeats endlessly), so should be ignored.
+ /// \param iBkgCol background colour to show through any new transparent node created;
+ /// if the existing node is grafted in, again this will already have been taken into account.
+ virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
+ ///Called to build a group node which is a descendant of the symbol or root node preceding this.
+ /// Default implementation calls the manager's CreateGroupNode method to create a new node,
+ /// but then populates that group (i.e. further descends the hierarchy) _if_ that group
+ /// would contain this node (see IsInGroup). Subclasses can override to graft themselves into the hierarchy, if appropriate.
+ /// \param pParent parent of the symbol node to create; could be the previous root, or an intervening node (e.g. group)
+ virtual CDasherNode *RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo);
+ protected:
+ CAlphBase(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CAlphabetManager *pMgr);
+ CAlphabetManager *m_pMgr;
+ ///Number of unicode characters entered by this node; i.e., the number
+ /// to take off this node's offset, to get the offset of the most-recent
+ /// root (e.g. previous symbol). Default is 0.
+ virtual int numChars() {return 0;}
+ ///return true if the specified group would contain this node
+ /// (as a symbol or subgroup), any number of levels beneath it
+ virtual bool isInGroup(const SGroupInfo *pGroup)=0;
+ };
class CGroupNode;
- class CAlphNode : public CDasherNode {
+ ///Additionally stores LM contexts and probabilities calculated therefrom
+ class CAlphNode : public CAlphBase {
public:
- virtual CAlphabetManager *mgr() {return m_pMgr;}
CAlphNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CAlphabetManager *pMgr);
CLanguageModel::Context iContext;
///
@@ -68,16 +102,11 @@ namespace Dasher {
///
virtual ~CAlphNode();
virtual CLanguageModel::Context CloneAlphContext(CLanguageModel *pLanguageModel);
- CDasherNode *RebuildParent(int iNewOffset);
///Have to call this from CAlphabetManager, and from CGroupNode on a _different_ CAlphNode, hence public...
virtual std::vector<unsigned int> *GetProbInfo();
virtual int ExpectedNumChildren();
- virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol)=0;
- virtual CDasherNode *RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo)=0;
private:
std::vector<unsigned int> *m_pProbInfo;
- protected:
- CAlphabetManager *m_pMgr;
};
class CSymbolNode : public CAlphNode {
public:
@@ -87,12 +116,8 @@ namespace Dasher {
/// any such group, as GetColour() always returns an opaque color.
CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CAlphabetManager *pMgr, symbol iSymbol);
- ///
- /// Provide children for the supplied node
- ///
-
+ ///Create the children of this node, by starting traversal of the alphabet from the top
virtual void PopulateChildren();
- virtual CDasherNode *RebuildParent();
virtual void Output(Dasher::VECTOR_SYMBOL_PROB* pAdded, int iNormalization);
virtual void Undo(int *pNumDeleted);
@@ -101,9 +126,8 @@ namespace Dasher {
virtual bool GameSearchNode(std::string strTargetUtf8Char);
virtual void GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabetMap, std::vector<symbol> &vContextSymbols, int iOffset, int iLength);
virtual symbol GetAlphSymbol();
- const symbol iSymbol;
+ ///Override: if the symbol to create is the same as this node's symbol, return this node instead of creating a new one
virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
- virtual CDasherNode *RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo);
protected:
virtual const std::string &outputText();
/// Number of unicode _characters_ (not octets) for this symbol.
@@ -113,22 +137,29 @@ namespace Dasher {
int numChars();
///Compatibility constructor, so that subclasses can specify their own colour & label
CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CAlphabetManager *pMgr, symbol _iSymbol);
+ ///Override: true iff pGroup encloses this symbol (according to its start/end symbol#)
+ bool isInGroup(const SGroupInfo *pGroup);
+ const symbol iSymbol;
};
class CGroupNode : public CAlphNode {
public:
CGroupNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, CAlphabetManager *pMgr, const SGroupInfo *pGroup);
- ///
- /// Provide children for the supplied node
- ///
+ ///Override: if m_pGroup==NULL, i.e. whole/root-of alphabet, cannot rebuild.
virtual CDasherNode *RebuildParent();
+
+ ///Create children of this group node, by traversing the section of the alphabet
+ /// indicated by m_pGroup.
virtual void PopulateChildren();
virtual int ExpectedNumChildren();
virtual bool GameSearchNode(std::string strTargetUtf8Char);
- virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
- virtual CDasherNode *RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo);
std::vector<unsigned int> *GetProbInfo();
+ ///Override: if the group to create is the same as this node's group, return this node instead of creating a new one
+ virtual CDasherNode *RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo);
+ protected:
+ ///Override: true if pGroup encloses this one (by start/end symbol#)
+ bool isInGroup(const SGroupInfo *pGroup);
private:
const SGroupInfo *m_pGroup;
};
@@ -193,7 +224,7 @@ namespace Dasher {
/// instead of the AlphabetManager's CreateSymbolNode/CreateGroupNode methods. This is used when
/// rebuilding parents: passing in the pre-existing node here, allows it to intercept those calls
/// and graft itself in in place of a new node, when appropriate.
- void IterateChildGroups(CAlphNode *pParent, const SGroupInfo *pParentGroup, CAlphNode *buildAround);
+ void IterateChildGroups(CAlphNode *pParent, const SGroupInfo *pParentGroup, CAlphBase *buildAround);
CDasherInterfaceBase *m_pInterface;
diff --git a/Src/DasherCore/MandarinAlphMgr.cpp b/Src/DasherCore/MandarinAlphMgr.cpp
index 153da25..072cfa3 100644
--- a/Src/DasherCore/MandarinAlphMgr.cpp
+++ b/Src/DasherCore/MandarinAlphMgr.cpp
@@ -127,7 +127,7 @@ CAlphabetManager::CAlphNode *CMandarinAlphMgr::GetRoot(CDasherNode *pParent, uns
pNewNode = new CGroupNode(pParent, iNewOffset, iLower, iUpper, "", 0, this, NULL);
} else {
DASHER_ASSERT(p.first>0 && p.first<=m_pCHAlphabet->GetNumberTextSymbols());
- pNewNode = new CMandSym(pParent, iNewOffset, iLower, iUpper, "", this, p.first);
+ pNewNode = new CMandSym(pParent, iNewOffset, iLower, iUpper, "", this, p.first, 0);
}
pNewNode->iContext = p.second;
@@ -162,7 +162,7 @@ CDasherNode *CMandarinAlphMgr::CreateSymbolNode(CAlphNode *pParent, unsigned int
if (m_pConversionsBySymbol[iSymbol].size()>1)
return CreateConvRoot(pParent, iLbnd, iHbnd, strGroup, iSymbol);
- return CreateCHSymbol(pParent,pParent->iContext, iLbnd, iHbnd, strGroup, *(m_pConversionsBySymbol[iSymbol].begin()));
+ return CreateCHSymbol(pParent,pParent->iContext, iLbnd, iHbnd, strGroup, *(m_pConversionsBySymbol[iSymbol].begin()), iSymbol);
}
CMandarinAlphMgr::CConvRoot *CMandarinAlphMgr::CreateConvRoot(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, symbol iPYsym) {
@@ -177,24 +177,24 @@ CMandarinAlphMgr::CConvRoot *CMandarinAlphMgr::CreateConvRoot(CAlphNode *pParent
}
CMandarinAlphMgr::CConvRoot::CConvRoot(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, symbol pySym)
-: CDasherNode(pParent, iOffset, iLbnd, iHbnd, 9, strGroup), m_pMgr(pMgr), m_pySym(pySym) {
- DASHER_ASSERT(m_pMgr->m_pConversionsBySymbol[pySym].size()>1);
+: CAlphBase(pParent, iOffset, iLbnd, iHbnd, 9, strGroup, pMgr), m_pySym(pySym) {
+ DASHER_ASSERT(pMgr->m_pConversionsBySymbol[pySym].size()>1);
//colour + label from ConversionManager.
}
int CMandarinAlphMgr::CConvRoot::ExpectedNumChildren() {
- return m_pMgr->m_pConversionsBySymbol[m_pySym].size();
+ return mgr()->m_pConversionsBySymbol[m_pySym].size();
}
void CMandarinAlphMgr::CConvRoot::PopulateChildren() {
if (m_vChInfo.empty()) {
- const set<symbol> &convs(m_pMgr->m_pConversionsBySymbol[m_pySym]);
+ const set<symbol> &convs(mgr()->m_pConversionsBySymbol[m_pySym]);
for(set<symbol>::const_iterator it = convs.begin(); it != convs.end(); ++it) {
m_vChInfo.push_back(std::pair<symbol, unsigned int>(*it,0));
}
//ACL I think it's a good idea to keep those in a consistent order - symbol order will do nicely
sort(m_vChInfo.begin(),m_vChInfo.end());
- m_pMgr->AssignSizes(m_vChInfo, iContext);
+ mgr()->AssignSizes(m_vChInfo, iContext);
}
int iCum(0);
@@ -205,29 +205,43 @@ void CMandarinAlphMgr::CConvRoot::PopulateChildren() {
const unsigned int iLbnd(iCum), iHbnd(iCum + it->second);
iCum = iHbnd;
- CMandSym *pNewNode = mgr()->CreateCHSymbol(this, this->iContext, iLbnd, iHbnd, "", it->first);
+ CMandSym *pNewNode = mgr()->CreateCHSymbol(this, this->iContext, iLbnd, iHbnd, "", it->first, m_pySym);
DASHER_ASSERT(GetChildren().back()==pNewNode);
}
}
-CMandarinAlphMgr::CMandSym *CMandarinAlphMgr::CreateCHSymbol(CDasherNode *pParent, CLanguageModel::Context iContext, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, symbol iCHsym) {
+CMandarinAlphMgr::CMandSym *CMandarinAlphMgr::CreateCHSymbol(CDasherNode *pParent, CLanguageModel::Context iContext, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, symbol iCHsym, symbol iPYparent) {
// TODO: Parameters here are placeholders - need to figure out
// what's right
int iNewOffset = pParent->offset()+1;
if (m_pCHAlphabet->GetText(iCHsym) == "\r\n") iNewOffset++;
- CMandSym *pNewNode = new CMandSym(pParent, iNewOffset, iLbnd, iHbnd, strGroup, this, iCHsym);
+ CMandSym *pNewNode = new CMandSym(pParent, iNewOffset, iLbnd, iHbnd, strGroup, this, iCHsym, iPYparent);
pNewNode->iContext = m_pLanguageModel->CloneContext(iContext);
m_pLanguageModel->EnterSymbol(pNewNode->iContext, iCHsym);
return pNewNode;
}
+CDasherNode *CMandarinAlphMgr::CConvRoot::RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSym) {
+ if (iSym == m_pySym) {
+ SetParent(pParent);
+ SetRange(iLbnd,iHbnd);
+ return this;
+ }
+ return CAlphBase::RebuildSymbol(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSym);
+}
+
+bool CMandarinAlphMgr::CConvRoot::isInGroup(const SGroupInfo *pGroup) {
+ return pGroup->iStart <= m_pySym && pGroup->iEnd > m_pySym;
+}
+
void CMandarinAlphMgr::CConvRoot::SetFlag(int iFlag, bool bValue) {
- if (iFlag==NF_COMMITTED && bValue && !GetFlag(NF_COMMITTED))
- if (!GetFlag(NF_GAME) && m_pMgr->m_pNCManager->GetBoolParameter(BP_LM_ADAPTIVE))
- static_cast<CPPMPYLanguageModel *>(m_pMgr->m_pLanguageModel)->LearnPYSymbol(m_pMgr->m_iLearnContext, m_pySym);
+ if (iFlag==NF_COMMITTED && bValue && !GetFlag(NF_COMMITTED)
+ && !GetFlag(NF_GAME) && mgr()->m_pNCManager->GetBoolParameter(BP_LM_ADAPTIVE)) {
+ static_cast<CPPMPYLanguageModel *>(mgr()->m_pLanguageModel)->LearnPYSymbol(mgr()->m_iLearnContext, m_pySym);
+ }
CDasherNode::SetFlag(iFlag,bValue);
}
@@ -309,8 +323,34 @@ void CMandarinAlphMgr::AssignSizes(std::vector<pair<symbol,unsigned int> > &vChi
}
-CMandarinAlphMgr::CMandSym::CMandSym(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, symbol iSymbol)
-: CSymbolNode(pParent, iOffset, iLbnd, iHbnd, pMgr->GetCHColour(iSymbol,iOffset), strGroup+pMgr->m_pCHAlphabet->GetDisplayText(iSymbol), pMgr, iSymbol) {
+CMandarinAlphMgr::CMandSym::CMandSym(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, symbol iSymbol, symbol pyParent)
+: CSymbolNode(pParent, iOffset, iLbnd, iHbnd, pMgr->GetCHColour(iSymbol,iOffset), strGroup+pMgr->m_pCHAlphabet->GetDisplayText(iSymbol), pMgr, iSymbol), m_pyParent(pyParent) {
+}
+
+CDasherNode *CMandarinAlphMgr::CMandSym::RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
+ //TODO m_pyParent should have been computed in RebuildParent()
+ DASHER_ASSERT(m_pyParent!=0);
+ if (iSymbol==m_pyParent) {
+ //create the PY node that lead to this chinese
+ if (mgr()->m_pConversionsBySymbol[m_pyParent].size()==1) {
+ DASHER_ASSERT( *(mgr()->m_pConversionsBySymbol[m_pyParent].begin()) == this->iSymbol);
+ SetRange(iLbnd, iHbnd);
+ SetParent(pParent);
+ return this;
+ }
+ //ok, will be a PY-to-Chinese conversion choice
+ CConvRoot *pConv = mgr()->CreateConvRoot(pParent, iLbnd, iHbnd, strGroup, iSymbol);
+ //TODO equivalent of IterateChildGroups - make CConvRoot generate children, but replacing one with this
+ return pConv;
+ }
+ return CAlphBase::RebuildSymbol(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
+}
+
+bool CMandarinAlphMgr::CMandSym::isInGroup(const SGroupInfo *pGroup) {
+ //TODO m_pyParent should have been computed in RebuildParent()
+ DASHER_ASSERT(m_pyParent!=0);
+ //pinyin group contains the pinyin-"symbol"=CConvRoot which we want to be our parent...
+ return pGroup->iStart <= m_pyParent && pGroup->iEnd > m_pyParent;
}
const std::string &CMandarinAlphMgr::CMandSym::outputText() {
diff --git a/Src/DasherCore/MandarinAlphMgr.h b/Src/DasherCore/MandarinAlphMgr.h
index 881923f..47d610d 100644
--- a/Src/DasherCore/MandarinAlphMgr.h
+++ b/Src/DasherCore/MandarinAlphMgr.h
@@ -56,27 +56,32 @@ namespace Dasher {
CMandarinAlphMgr *mgr() {return static_cast<CMandarinAlphMgr *>(CSymbolNode::mgr());}
///Symbol constructor: display text from CHAlphabet, colour from GetCHColour
/// \param strGroup caption of any group(s) containing this symbol for which no nodes created; prepended to display text.
- CMandSym(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, symbol iSymbol);
- ///Rebuilding not supported
- virtual CDasherNode *RebuildParent() {return 0;}
+ CMandSym(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, symbol iSymbol, symbol pyParent);
+ protected:
+ CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
+ bool isInGroup(const SGroupInfo *pGroup);
private:
virtual const std::string &outputText();
+ ///The Pinyin symbol used to produce this chinese symbol, if known (0 if not!)
+ symbol m_pyParent;
};
- ///Offers a choice between a set of chinese symbols, all corresponding to a single PY symbol.
- /// Relative sizes of the CH symbols is obtained by CPPMPYLanguageModel::GetPartProbs, passing
- /// the set of possible CH symbols.
- class CConvRoot : public CDasherNode {
+ ///Offers a choice between a set of chinese symbols, all corresponding to a single PY symbol.
+ /// Relative sizes of the CH symbols is obtained by CPPMPYLanguageModel::GetPartProbs, passing
+ /// the set of possible CH symbols.
+ class CConvRoot : public CAlphBase {
public:
- CMandarinAlphMgr *mgr() {return m_pMgr;}
/// \param pySym symbol in pinyin alphabet; must have >1 possible chinese conversion.
CConvRoot(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, symbol pySym);
+ CMandarinAlphMgr *mgr() {return static_cast<CMandarinAlphMgr *>(CAlphBase::mgr());}
void PopulateChildren();
int ExpectedNumChildren();
CLanguageModel::Context iContext;
void SetFlag(int iFlag, bool bValue);
+ CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
+ protected:
+ bool isInGroup(const SGroupInfo *pGroup);
private:
std::vector<std::pair<symbol, unsigned int> > m_vChInfo;
- CMandarinAlphMgr *m_pMgr;
symbol m_pySym;
};
///Called to create the node for a pinyin leaf symbol;
@@ -97,7 +102,8 @@ namespace Dasher {
/// \param iContext parent node's context, from which to generate context for this node
/// \param strGroup caption of any elided groups (prepended to this node's caption)
/// \param iCHsym symbol number in chinese alphabet
- CMandSym *CreateCHSymbol(CDasherNode *pParent, CLanguageModel::Context iContext, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, symbol iCHsym);
+ /// \param pyParent pinyin-alphabet symbol which was used to enter this chinese symbol (if known, else 0)
+ CMandSym *CreateCHSymbol(CDasherNode *pParent, CLanguageModel::Context iContext, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, symbol iCHsym, symbol pyParent);
void AssignSizes(std::vector<std::pair<symbol,unsigned int> > &vChildren, Dasher::CLanguageModel::Context context);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]