[dasher: 9/38] Refactor: AlphMgr stores group labels in std::map; rm its own version SGroupInfo



commit af64d0a085ba5f7f2153a8eb54b15fd288b519bc
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Tue Dec 6 21:43:54 2011 +0000

    Refactor: AlphMgr stores group labels in std::map; rm its own version SGroupInfo
    
    (=>Use standard SGroupInfo for elided tree)

 Src/DasherCore/AlphabetManager.cpp |   30 ++++++++++++++----------------
 Src/DasherCore/AlphabetManager.h   |   24 ++++++------------------
 Src/DasherCore/MandarinAlphMgr.cpp |    4 ++--
 3 files changed, 22 insertions(+), 36 deletions(-)
---
diff --git a/Src/DasherCore/AlphabetManager.cpp b/Src/DasherCore/AlphabetManager.cpp
index 5b69851..4730f43 100644
--- a/Src/DasherCore/AlphabetManager.cpp
+++ b/Src/DasherCore/AlphabetManager.cpp
@@ -101,31 +101,29 @@ void CAlphabetManager::MakeLabels(CDasherScreen *pScreen) {
     delete (*it); *it = NULL;
   }
   m_vLabels.resize(m_pAlphabet->GetNumberTextSymbols()+1);
+  for (map<const SGroupInfo *,CDasherScreen::Label *>::iterator it=m_mGroupLabels.begin(); it!=m_mGroupLabels.end(); it++)
+    delete it->second;
+  m_mGroupLabels.clear();
   m_pFirstGroup = copyGroups(pScreen, 1, m_pAlphabet->GetNumberTextSymbols()+1,m_pAlphabet->m_pBaseGroup);
 }
 
-CAlphabetManager::SGroupInfo::SGroupInfo(CDasherScreen *pScreen, const std::string &strEnc, int iBkgCol, const ::SGroupInfo *pCopy)
-: pChild(NULL), pNext(NULL), strLabel(strEnc + pCopy->strLabel), iStart(pCopy->iStart), iEnd(pCopy->iEnd),
-  iColour(pCopy->bVisible ? pCopy->iColour : iBkgCol), bVisible(pCopy->bVisible || (iBkgCol!=-1)),
-  iNumChildNodes(pCopy->iNumChildNodes), pLabel(strLabel.empty() ? NULL : pScreen->MakeLabel(strLabel)) {
-}
-
-CAlphabetManager::SGroupInfo::~SGroupInfo() {
-  delete pChild;
-  delete pNext;
-  delete pLabel;
-}
-
-CAlphabetManager::SGroupInfo *CAlphabetManager::copyGroups(CDasherScreen *pScreen, int iStart, int iEnd, ::SGroupInfo *pFirstChild) {  
+SGroupInfo *CAlphabetManager::copyGroups(CDasherScreen *pScreen, int iStart, int iEnd, const SGroupInfo *pFirstChild) {  
   for (int i = iStart; i< iEnd; i++) {
     string strGroupPrefix;
     if (pFirstChild && i>=pFirstChild->iStart) {
       //reached group. elide any group with only a single child (see below).
       // Variables store necessary properties of any elided groups:
       int iBkgCol(-1);
-      for (const ::SGroupInfo *pInner=pFirstChild;;) {
+      for (const SGroupInfo *pInner=pFirstChild;;) {
         if (pInner->iNumChildNodes>1) { //in/reached nontrivial subgroup - do make node for entire group:
-          SGroupInfo *pRes = new SGroupInfo(pScreen, strGroupPrefix, iBkgCol, pInner);
+          SGroupInfo *pRes = new SGroupInfo(*pInner);
+          //apply properties of enclosing group(s)...
+          pRes->strLabel = strGroupPrefix + pRes->strLabel;
+          if (!pInner->bVisible) pRes->iColour = iBkgCol;
+          if (iBkgCol!=-1) pRes->bVisible=true;
+          if (pRes->strLabel.length())
+            m_mGroupLabels[pRes] = pScreen->MakeLabel(pRes->strLabel);
+          //and recurse on children
           pRes->pChild = copyGroups(pScreen, pInner->iStart, pInner->iEnd, pInner->pChild);
           pRes->pNext = copyGroups(pScreen, pInner->iEnd, iEnd, pFirstChild->pNext);
           return pRes;
@@ -432,7 +430,7 @@ CAlphabetManager::CGroupNode *CAlphabetManager::CreateGroupNode(CAlphNode *pPare
   // When creating a group node...
   // ...the offset is the same as the parent...
 
-  CGroupNode *pNewNode = new CGroupNode(pParent->offset(), pInfo->pLabel, iBkgCol, this, pInfo);
+  CGroupNode *pNewNode = new CGroupNode(pParent->offset(), m_mGroupLabels[pInfo], iBkgCol, this, pInfo);
 
   //...as is the context!
   pNewNode->iContext = m_pLanguageModel->CloneContext(pParent->iContext);
diff --git a/Src/DasherCore/AlphabetManager.h b/Src/DasherCore/AlphabetManager.h
index 2883fd7..044dd88 100644
--- a/Src/DasherCore/AlphabetManager.h
+++ b/Src/DasherCore/AlphabetManager.h
@@ -66,23 +66,11 @@ namespace Dasher {
     /// \param pInterface to use for I/O by calling WriteTrainFile(fname,txt)
     void WriteTrainFileFull(CDasherInterfaceBase *pInterface);
   protected:
-    ///The SGroupInfo tree from the alphabet, but with single-child groups collapsed,
-    /// and with labels from the Screen.
-    struct SGroupInfo {
-      SGroupInfo(CDasherScreen *pScreen, const std::string &strEnc, int iBkgCol, const ::SGroupInfo *pCopy);
-      ~SGroupInfo();
-      SGroupInfo *pChild;
-      SGroupInfo *pNext;
-      std::string strLabel;
-      int iStart;
-      int iEnd;
-      int iColour;
-      bool bVisible;
-      int iNumChildNodes;
-      CDasherScreen::Label *pLabel;
-    } *m_pFirstGroup;
-    
-    //A label for each symbol, indexed by symbol id (element 0 = null)
+    ///Post-processed version of alphabet group tree, eliding all groups with only a single child.
+    SGroupInfo *m_pFirstGroup;
+    ///A label for each group in the elided tree
+    std::map<const SGroupInfo *,CDasherScreen::Label *> m_mGroupLabels;
+    ///A label for each symbol, indexed by symbol id (element 0 = null)
     std::vector<CDasherScreen::Label *> m_vLabels;
     
     virtual const std::string &GetLabelText(symbol i) const;
@@ -254,7 +242,7 @@ namespace Dasher {
     /// Returns array of non-cumulative probs. Should this be protected and/or virtual???
     void GetProbs(std::vector<unsigned int> *pProbs, CLanguageModel::Context iContext);
     
-    SGroupInfo *copyGroups(CDasherScreen *pScreen, int iStart, int iEnd, ::SGroupInfo *pFirstChild);
+    SGroupInfo *copyGroups(CDasherScreen *pScreen, int iStart, int iEnd, const SGroupInfo *pFirstChild);
     
     ///Constructs child nodes under the specified parent according to provided group.
     /// Nodes are created by calling CreateSymbolNode and CreateGroupNode, unless buildAround is non-null.
diff --git a/Src/DasherCore/MandarinAlphMgr.cpp b/Src/DasherCore/MandarinAlphMgr.cpp
index cd68513..7499176 100644
--- a/Src/DasherCore/MandarinAlphMgr.cpp
+++ b/Src/DasherCore/MandarinAlphMgr.cpp
@@ -63,10 +63,10 @@ CMandarinAlphMgr::CMandarinAlphMgr(CSettingsUser *pCreator, CDasherInterfaceBase
   if (symbol para = pCHAlphabet->GetParagraphSymbol())
     conversions[pCHAlphabet->GetDisplayText(para)]=pair<symbol,symbol>(para,para+1);
   //Non-recursive traversal of all the groups in the CHAlphabet (we don't care where they are, just to find them)
-  vector<const ::SGroupInfo *> groups;
+  vector<const SGroupInfo *> groups;
   groups.push_back(pCHAlphabet->m_pBaseGroup);
   while (!groups.empty()) {
-    const ::SGroupInfo *pGroup(groups.back()); groups.pop_back();
+    const SGroupInfo *pGroup(groups.back()); groups.pop_back();
     if (pGroup->pNext) groups.push_back(pGroup->pNext);
     if (pGroup->pChild) groups.push_back(pGroup->pChild);
     //process this group. The SPY syll+tone is stored as the label, using a tone mark over the vowel, e.g. &#257; = a1



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